From a1e1101036564cd687b935dfd253282a8edc134a Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 19:53:13 +0000 Subject: [PATCH 01/10] #124 Update project dependencies --- poetry.lock | 74 ++++++++++++++++++++++++++++++++++---------------- pyproject.toml | 3 +- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4cd468e..a13106b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -152,29 +152,29 @@ lxml = ["lxml"] [[package]] name = "black" -version = "23.10.1" +version = "23.11.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.10.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69"}, - {file = "black-23.10.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916"}, - {file = "black-23.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc"}, - {file = "black-23.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173"}, - {file = "black-23.10.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0"}, - {file = "black-23.10.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace"}, - {file = "black-23.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb"}, - {file = "black-23.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce"}, - {file = "black-23.10.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a"}, - {file = "black-23.10.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1"}, - {file = "black-23.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad"}, - {file = "black-23.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884"}, - {file = "black-23.10.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9"}, - {file = "black-23.10.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7"}, - {file = "black-23.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d"}, - {file = "black-23.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982"}, - {file = "black-23.10.1-py3-none-any.whl", hash = "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe"}, - {file = "black-23.10.1.tar.gz", hash = "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"}, + {file = "black-23.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911"}, + {file = "black-23.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f"}, + {file = "black-23.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394"}, + {file = "black-23.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f"}, + {file = "black-23.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479"}, + {file = "black-23.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244"}, + {file = "black-23.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221"}, + {file = "black-23.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5"}, + {file = "black-23.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187"}, + {file = "black-23.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6"}, + {file = "black-23.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b"}, + {file = "black-23.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142"}, + {file = "black-23.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055"}, + {file = "black-23.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4"}, + {file = "black-23.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06"}, + {file = "black-23.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07"}, + {file = "black-23.11.0-py3-none-any.whl", hash = "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e"}, + {file = "black-23.11.0.tar.gz", hash = "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05"}, ] [package.dependencies] @@ -480,6 +480,20 @@ files = [ {file = "fasteners-0.19.tar.gz", hash = "sha256:b4f37c3ac52d8a445af3a66bce57b33b5e90b97c696b7b984f530cf8f0ded09c"}, ] +[[package]] +name = "fire" +version = "0.5.0" +description = "A library for automatically generating command line interfaces." +optional = false +python-versions = "*" +files = [ + {file = "fire-0.5.0.tar.gz", hash = "sha256:a6b0d49e98c8963910021f92bba66f65ab440da2982b78eb1bbf95a0a34aacc6"}, +] + +[package.dependencies] +six = "*" +termcolor = "*" + [[package]] name = "fonttools" version = "4.44.0" @@ -1470,13 +1484,13 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pyright" -version = "1.1.334" +version = "1.1.335" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.334-py3-none-any.whl", hash = "sha256:dcb13e8358e021189672c4d6ebcad192ab061e4c7225036973ec493183c6da68"}, - {file = "pyright-1.1.334.tar.gz", hash = "sha256:3adaf10f1f4209575dc022f9c897f7ef024639b7ea5b3cbe49302147e6949cd4"}, + {file = "pyright-1.1.335-py3-none-any.whl", hash = "sha256:1149d99d5cea3997010a5ac39611534e0426125d5090913ae5cb1e0e2c9fbca3"}, + {file = "pyright-1.1.335.tar.gz", hash = "sha256:12c09c1644b223515cc342f7d383e55eefeedd730d7875e39a2cf338c2d99be4"}, ] [package.dependencies] @@ -1909,6 +1923,20 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] +[[package]] +name = "termcolor" +version = "2.3.0" +description = "ANSI color formatting for output in terminal" +optional = false +python-versions = ">=3.7" +files = [ + {file = "termcolor-2.3.0-py3-none-any.whl", hash = "sha256:3afb05607b89aed0ffe25202399ee0867ad4d3cb4180d98aaf8eefa6a5f7d475"}, + {file = "termcolor-2.3.0.tar.gz", hash = "sha256:b5b08f68937f138fe92f6c089b99f1e2da0ae56c52b78bf7075fd95420fd9a5a"}, +] + +[package.extras] +tests = ["pytest", "pytest-cov"] + [[package]] name = "threadpoolctl" version = "3.2.0" @@ -2074,4 +2102,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.9, <3.13" -content-hash = "6efb5c16a9519d2ee6e420f386c6d45ebb2056e05e9538efb4e6cd34bbc5db99" +content-hash = "f6fc940c4d00540f6f8aebbbfbb260804854c6b2916bf9dd809b6bfdc29adca1" diff --git a/pyproject.toml b/pyproject.toml index 725c1b4..99d3c94 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,9 +26,10 @@ scikit-learn = "^1.2" scipy = "^1.10" xarray = "^2023.1" zarr = "^2.14" +fire = "^0.5.0" [tool.poetry.group.dev.dependencies] -black = "^23.10" +black = "^23.11" ipython = "^8.16" myst-parser = "^2.0" pydata-sphinx-theme = "^0.14" From 6999d8ac3af5a8e78e4119a7efd0cf53797c0979 Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 19:55:31 +0000 Subject: [PATCH 02/10] #124 Add empty qlook module --- decode/__init__.py | 2 ++ decode/qlook.py | 1 + tests/test_qlook.py | 0 3 files changed, 3 insertions(+) create mode 100644 decode/qlook.py create mode 100644 tests/test_qlook.py diff --git a/decode/__init__.py b/decode/__init__.py index af6127a..47d3368 100644 --- a/decode/__init__.py +++ b/decode/__init__.py @@ -6,6 +6,7 @@ "load", "make", "plot", + "qlook", "select", ] __version__ = "2.6.0" @@ -19,4 +20,5 @@ from . import load from . import make from . import plot +from . import qlook from . import select diff --git a/decode/qlook.py b/decode/qlook.py new file mode 100644 index 0000000..a9a2c5b --- /dev/null +++ b/decode/qlook.py @@ -0,0 +1 @@ +__all__ = [] diff --git a/tests/test_qlook.py b/tests/test_qlook.py new file mode 100644 index 0000000..e69de29 From a16b60a63b7f6e3234e4b088723b2bc11f7a6868 Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 20:10:02 +0000 Subject: [PATCH 03/10] #124 Add entry point of decode-qlook --- decode/qlook.py | 9 +++++++++ pyproject.toml | 3 +++ 2 files changed, 12 insertions(+) diff --git a/decode/qlook.py b/decode/qlook.py index a9a2c5b..4bbf48a 100644 --- a/decode/qlook.py +++ b/decode/qlook.py @@ -1 +1,10 @@ __all__ = [] + + +# dependencies +from fire import Fire + + +def main() -> None: + """Entry point of the decode-qlook command.""" + Fire() diff --git a/pyproject.toml b/pyproject.toml index 99d3c94..1cfa090 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,9 @@ pyright = "^1.1" pytest = "^7.4" sphinx = "^7.2" +[tool.poetry.scripts] +decode-qlook = "decode.qlook:main" + [tool.pyright] typeCheckingMode = "basic" From 1c0a478b2b0f9d7ad3d017a2b109746ac9ed1f64 Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 22:16:11 +0000 Subject: [PATCH 04/10] #124 Add skydip command --- decode/qlook.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 1 deletion(-) diff --git a/decode/qlook.py b/decode/qlook.py index 4bbf48a..545cca1 100644 --- a/decode/qlook.py +++ b/decode/qlook.py @@ -1,10 +1,101 @@ __all__ = [] +# standard library +from pathlib import Path +from typing import Any, Literal, Optional, Sequence + + # dependencies +import numpy as np +import xarray as xr +import matplotlib.pyplot as plt from fire import Fire +from . import load, plot, select + + +# constants +# fmt: off +BAD_MKID_IDS = ( + 18, 77, 117, 118, 140, 141, 161, 182, 183, 184, + 201, 209, 211, 232, 233, 239, 258, 259, 278, 282, + 283, 296, 297, 299, 301, 313, +) +# fmt: on + + +def skydip( + dems: Path, + /, + *, + include_mkid_ids: Optional[Sequence[int]] = None, + exclude_mkid_ids: Optional[Sequence[int]] = BAD_MKID_IDS, + data_type: Literal["df/f", "brightness"] = "brightness", + outdir: Path = Path(), + format: str = "png", +) -> None: + """Quick-look at a skydip observation. + + Args: + dems: Input DEMS file (netCDF or Zarr). + include_mkid_ids: MKID IDs to be included in analysis. + Defaults to all MKID IDs. + exclude_mkid_ids: MKID IDs to be excluded in analysis. + Defaults to bad MKID IDs found on 2023-11-07. + data_type: Data type of the input DEMS file. + outdir: Output directory for analysis results. + format: Output image format of analysis results. + + """ + dems = Path(dems) + result = Path(outdir) / dems.with_suffix(f".skydip.{format}").name + + # load DEMS + da = load.dems(dems, chunks=None) + + if data_type == "df/f": + da.attrs.update(long_name=data_type, units="dimensionless") + + # add sec(Z) coordinate + secz = 1 / np.cos(np.deg2rad(90.0 - da.lat)) + secz.attrs.update(long_name="sec(Z)", units="dimensionless") + da = da.assign_coords(secz=secz) + + # select DEMS + da = select.by(da, "d2_mkid_type", include="filter") + da = select.by( + da, + "d2_mkid_id", + include=include_mkid_ids, + exclude=exclude_mkid_ids, + ) + da_on = select.by(da, "state", include="SCAN") + da_off = select.by(da, "state", exclude="GRAD") + + # plotting + weight = da_off.std("time") ** -2 + series = (da_on * weight).sum("chan") / weight.sum("chan") + + fig, axes = plt.subplots(1, 2, figsize=(12, 4)) + + ax = axes[0] + plot.data(np.abs(series), hue="secz", ax=ax) + ax.set_title(Path(dems).name) + ax.grid(True) + + ax = axes[1] + plot.data(np.abs(series), x="secz", ax=ax) + ax.set_title(Path(dems).name) + ax.set_xscale("log") + ax.set_yscale("log") + ax.grid(True) + + fig.tight_layout() + fig.savefig(result) + print(str(result)) def main() -> None: """Entry point of the decode-qlook command.""" - Fire() + with xr.set_options(keep_attrs=True): + Fire({"skydip": skydip}) From acf3bc429e4cb4f167b44e873e2b1ae142f9d05c Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 22:23:36 +0000 Subject: [PATCH 05/10] #124 Add zscan command --- decode/qlook.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/decode/qlook.py b/decode/qlook.py index 545cca1..7857126 100644 --- a/decode/qlook.py +++ b/decode/qlook.py @@ -95,7 +95,76 @@ def skydip( print(str(result)) +def zscan( + dems: Path, + /, + *, + include_mkid_ids: Optional[Sequence[int]] = None, + exclude_mkid_ids: Optional[Sequence[int]] = BAD_MKID_IDS, + data_type: Literal["df/f", "brightness"] = "brightness", + outdir: Path = Path(), + format: str = "png", +) -> None: + """Quick-look at an observation of subref axial focus scan. + + Args: + dems: Input DEMS file (netCDF or Zarr). + include_mkid_ids: MKID IDs to be included in analysis. + Defaults to all MKID IDs. + exclude_mkid_ids: MKID IDs to be excluded in analysis. + Defaults to bad MKID IDs found on 2023-11-07. + data_type: Data type of the input DEMS file. + outdir: Output directory for analysis results. + format: Output image format of analysis results. + + """ + dems = Path(dems) + result = Path(outdir) / dems.with_suffix(f".zscan.{format}").name + + # load DEMS + da = load.dems(dems, chunks=None) + + if data_type == "df/f": + da.attrs.update(long_name=data_type, units="dimensionless") + + # select DEMS + da = select.by(da, "d2_mkid_type", include="filter") + da = select.by( + da, + "d2_mkid_id", + include=include_mkid_ids, + exclude=exclude_mkid_ids, + ) + da_on = select.by(da, "state", include="ON") + da_off = select.by(da, "state", exclude="GRAD") + + # plotting + weight = da_off.std("time") ** -2 + series = (da_on * weight).sum("chan") / weight.sum("chan") + + fig, axes = plt.subplots(1, 2, figsize=(12, 4)) + + ax = axes[0] + plot.data(np.abs(series), hue="aste_subref_z", ax=ax) + ax.set_title(Path(dems).name) + ax.grid(True) + + ax = axes[1] + plot.data(np.abs(series), x="aste_subref_z", ax=ax) + ax.set_title(Path(dems).name) + ax.grid(True) + + fig.tight_layout() + fig.savefig(result) + print(str(result)) + + def main() -> None: """Entry point of the decode-qlook command.""" with xr.set_options(keep_attrs=True): - Fire({"skydip": skydip}) + Fire( + { + "skydip": skydip, + "zscan": zscan, + } + ) From b650c14ee13e050f7e6525b14be56c7b4f232b37 Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 22:44:44 +0000 Subject: [PATCH 06/10] #124 Fix skydip command --- decode/qlook.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/decode/qlook.py b/decode/qlook.py index 7857126..2b9e384 100644 --- a/decode/qlook.py +++ b/decode/qlook.py @@ -54,7 +54,8 @@ def skydip( da = load.dems(dems, chunks=None) if data_type == "df/f": - da.attrs.update(long_name=data_type, units="dimensionless") + da: xr.DataArray = np.abs(da) + da.attrs.update(long_name="|df/f|", units="dimensionless") # add sec(Z) coordinate secz = 1 / np.cos(np.deg2rad(90.0 - da.lat)) @@ -79,12 +80,12 @@ def skydip( fig, axes = plt.subplots(1, 2, figsize=(12, 4)) ax = axes[0] - plot.data(np.abs(series), hue="secz", ax=ax) + plot.data(series, hue="secz", ax=ax) ax.set_title(Path(dems).name) ax.grid(True) ax = axes[1] - plot.data(np.abs(series), x="secz", ax=ax) + plot.data(series, x="secz", ax=ax) ax.set_title(Path(dems).name) ax.set_xscale("log") ax.set_yscale("log") From 5d4ce9dab3d7db6d4bf5b58f8d36c7805a2bb0a2 Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 22:45:00 +0000 Subject: [PATCH 07/10] #124 Fix zscan command --- decode/qlook.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/decode/qlook.py b/decode/qlook.py index 2b9e384..8489bee 100644 --- a/decode/qlook.py +++ b/decode/qlook.py @@ -126,7 +126,7 @@ def zscan( da = load.dems(dems, chunks=None) if data_type == "df/f": - da.attrs.update(long_name=data_type, units="dimensionless") + da.attrs.update(long_name="df/f", units="dimensionless") # select DEMS da = select.by(da, "d2_mkid_type", include="filter") @@ -146,12 +146,12 @@ def zscan( fig, axes = plt.subplots(1, 2, figsize=(12, 4)) ax = axes[0] - plot.data(np.abs(series), hue="aste_subref_z", ax=ax) + plot.data(series, hue="aste_subref_z", ax=ax) ax.set_title(Path(dems).name) ax.grid(True) ax = axes[1] - plot.data(np.abs(series), x="aste_subref_z", ax=ax) + plot.data(series, x="aste_subref_z", ax=ax) ax.set_title(Path(dems).name) ax.grid(True) From 14b6dc2c2bb303784bf6134ad670fea1f0060caf Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 22:50:12 +0000 Subject: [PATCH 08/10] #124 Add contmap command --- decode/qlook.py | 116 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) diff --git a/decode/qlook.py b/decode/qlook.py index 8489bee..383a87d 100644 --- a/decode/qlook.py +++ b/decode/qlook.py @@ -3,7 +3,7 @@ # standard library from pathlib import Path -from typing import Any, Literal, Optional, Sequence +from typing import Literal, Optional, Sequence # dependencies @@ -11,7 +11,7 @@ import xarray as xr import matplotlib.pyplot as plt from fire import Fire -from . import load, plot, select +from . import assign, convert, load, make, plot, select # constants @@ -24,6 +24,111 @@ # fmt: on +def contmap( + dems: Path, + /, + *, + include_mkid_ids: Optional[Sequence[int]] = None, + exclude_mkid_ids: Optional[Sequence[int]] = BAD_MKID_IDS, + data_type: Literal["df/f", "brightness"] = "brightness", + skycoord_grid: str = "6 arcsec", + skycoord_units: str = "arcsec", + outdir: Path = Path(), + format: str = "png", +) -> None: + """Quick-look at a continuum mapping observation. + + Args: + dems: Input DEMS file (netCDF or Zarr). + include_mkid_ids: MKID IDs to be included in analysis. + Defaults to all MKID IDs. + exclude_mkid_ids: MKID IDs to be excluded in analysis. + Defaults to bad MKID IDs found on 2023-11-07. + data_type: Data type of the input DEMS file. + skycoord_grid: Grid size of the sky coordinate axes. + skycoord_units: Units of the sky coordinate axes. + outdir: Output directory for analysis results. + format: Output image format of analysis results. + + """ + dems = Path(dems) + result = Path(outdir) / dems.with_suffix(f".contmap.{format}").name + + # load DEMS + da = load.dems(dems, chunks=None) + da = assign.scan(da) + da = convert.frame(da, "relative") + + if data_type == "df/f": + da.attrs.update(long_name="df/f", units="dimensionless") + + # select DEMS + da = select.by(da, "d2_mkid_type", include="filter") + da = select.by( + da, + "d2_mkid_id", + include=include_mkid_ids, + exclude=exclude_mkid_ids, + ) + da_on = select.by(da, "state", include="SCAN") + da_off = select.by(da, "state", exclude="TRAN") + + # subtract temporal baseline + da_base = ( + da_off.groupby("scan") + .map(mean_in_time) + .interp_like( + da_on, + method="linear", + kwargs={"fill_value": "extrapolate"}, + ) + ) + da_sub = da_on - da_base.values + + # make continuum series + weight = da_off.std("time") ** -2 + series = (da_sub * weight).sum("chan") / weight.sum("chan") + + # make continuum map + cube = make.cube( + da_sub, + skycoord_grid=skycoord_grid, + skycoord_units=skycoord_units, + ) + cont = (cube * weight).sum("chan") / weight.sum("chan") + + if data_type == "df/f": + cont.attrs.update(long_name="df/f", units="dimensionless") + + # plotting + map_lim = max(abs(cube.lon).max(), abs(cube.lat).max()) + max_pix = cont.where(cont == cont.max(), drop=True) + max_lon = float(max_pix.lon) + max_lat = float(max_pix.lat) + + fig, axes = plt.subplots(1, 2, figsize=(12, 5.5)) + + ax = axes[0] + plot.data(series, ax=ax) + ax.set_title(Path(dems).name) + ax.grid(True) + + ax = axes[1] + cont.plot(ax=ax) # type: ignore + ax.set_title( + "Maxima: " + f"dAz = {max_lon:+.1f} {cont.lon.attrs['units']}, " + f"dEl = {max_lat:+.1f} {cont.lat.attrs['units']}" + ) + ax.set_xlim(-map_lim, map_lim) + ax.set_ylim(-map_lim, map_lim) + ax.grid() + + fig.tight_layout() + fig.savefig(result) + print(str(result)) + + def skydip( dems: Path, /, @@ -160,11 +265,18 @@ def zscan( print(str(result)) +def mean_in_time(dems: xr.DataArray) -> xr.DataArray: + """Similar to DataArray.mean but keeps middle time.""" + middle = dems[len(dems) // 2 : len(dems) // 2 + 1] + return xr.zeros_like(middle) + dems.mean("time") + + def main() -> None: """Entry point of the decode-qlook command.""" with xr.set_options(keep_attrs=True): Fire( { + "contmap": contmap, "skydip": skydip, "zscan": zscan, } From 45995bf16a380a410662dd7aa8c964aec489fc86 Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 22:55:07 +0000 Subject: [PATCH 09/10] =?UTF-8?q?#124=20Update=20package=20version=20(2.6.?= =?UTF-8?q?0=20=E2=86=92=202.7.0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CITATION.cff | 2 +- README.md | 2 +- decode/__init__.py | 2 +- pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 159e0af..8cdc375 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -3,7 +3,7 @@ message: "If you use this software, please cite it as below." title: "de:code" abstract: "DESHIMA code for data analysis" -version: 2.6.0 +version: 2.7.0 date-released: 2023-11-08 license: "MIT" doi: "10.5281/zenodo.3384216" diff --git a/README.md b/README.md index 40e189c..32b05c0 100644 --- a/README.md +++ b/README.md @@ -11,5 +11,5 @@ DESHIMA code for data analysis ## Installation ```shell -pip install decode==2.6.0 +pip install decode==2.7.0 ``` diff --git a/decode/__init__.py b/decode/__init__.py index 47d3368..15ecf84 100644 --- a/decode/__init__.py +++ b/decode/__init__.py @@ -9,7 +9,7 @@ "qlook", "select", ] -__version__ = "2.6.0" +__version__ = "2.7.0" # submodules diff --git a/pyproject.toml b/pyproject.toml index 1cfa090..a621740 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "decode" -version = "2.6.0" +version = "2.7.0" description = "DESHIMA code for data analysis" authors = ["Akio Taniguchi "] keywords = [ From fd83e53d1198732ae40fe0be1d13ba958088a9ef Mon Sep 17 00:00:00 2001 From: Akio Taniguchi Date: Wed, 8 Nov 2023 23:20:07 +0000 Subject: [PATCH 10/10] #124 Fix inferred type of abs(DataArray) --- decode/qlook.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/decode/qlook.py b/decode/qlook.py index 383a87d..32b4d94 100644 --- a/decode/qlook.py +++ b/decode/qlook.py @@ -3,7 +3,7 @@ # standard library from pathlib import Path -from typing import Literal, Optional, Sequence +from typing import Literal, Optional, Sequence, cast # dependencies @@ -159,7 +159,7 @@ def skydip( da = load.dems(dems, chunks=None) if data_type == "df/f": - da: xr.DataArray = np.abs(da) + da = cast(xr.DataArray, np.abs(da)) da.attrs.update(long_name="|df/f|", units="dimensionless") # add sec(Z) coordinate