diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b905b087..27b39360 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] - python-version: ["3.9", "3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -63,7 +63,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: "3.10" cache: pip - run: pip install --upgrade coverage[toml] - uses: actions/download-artifact@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8c83c31b..05b5aefb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Python ubuntu-latest uses: actions/setup-python@v4 with: - python-version: '3.9' # Should always be the minimum supported Python version + python-version: '3.10' # Should always be the minimum supported Python version cache: 'pip' cache-dependency-path': 'requirements.txt' - name: Install dependencies diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c19064c9..dde8d987 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ --- # See https://pre-commit.com for more information default_language_version: - python: python3.9 + python: python3.10 # See https://pre-commit.com/hooks.html for more hooks repos: - repo: 'https://github.com/pre-commit/pre-commit-hooks' - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace exclude: '(notebooks|attic|benchmark|testdata)/.*' @@ -30,7 +30,7 @@ repos: - id: isort exclude: '(notebooks|attic|benchmark|testdata)/.*' - repo: 'https://github.com/psf/black' - rev: 24.8.0 + rev: 24.10.0 hooks: - id: black exclude: '(notebooks|attic|benchmark|testdata)/.*' diff --git a/.readthedocs.yaml b/.readthedocs.yaml index e0652ef0..e2a2913c 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,7 +9,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.9" + python: "3.10" # You can also specify other tool versions: # nodejs: "19" # rust: "1.64" diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css index 15a41eca..961ef3bc 100644 --- a/docs/source/_static/css/custom.css +++ b/docs/source/_static/css/custom.css @@ -1,11 +1,95 @@ /* Remove width restriction on content so that diagrams - are more visible */ - .wy-nav-content { - max-width: none; - } - - /* Override the logo/searchbar background color; - it conflicts with the logo color */ - .wy-side-nav-search { - background-color: #C6B9D2; - } +are more visible */ +.wy-nav-content { + max-width: none; +} + +/* Override the logo/searchbar background color; + it conflicts with the logo color */ +.wy-side-nav-search { + background-color: #C6B9D2; +} + +.black { + color: black; +} + +.gray { + color: gray; +} + +.grey { + color: gray; +} + +.silver { + color: silver; +} + +.white { + color: white; +} + +.maroon { + color: maroon; +} + +.red { + color: red; +} + +.magenta { + color: magenta; +} + +.fuchsia { + color: fuchsia; +} + +.pink { + color: pink; +} + +.orange { + color: orange; +} + +.yellow { + color: yellow; +} + +.lime { + color: lime; +} + +.green { + color: green; +} + +.olive { + color: olive; +} + +.teal { + color: teal; +} + +.cyan { + color: cyan; +} + +.aqua { + color: aqua; +} + +.blue { + color: blue; +} + +.navy { + color: navy; +} + +.purple { + color: purple; +} diff --git a/docs/source/_static/icon/UMD_Globe_Icon_Large.png b/docs/source/_static/icon/UMD_Globe_Icon_Large.png new file mode 100644 index 00000000..972364cb Binary files /dev/null and b/docs/source/_static/icon/UMD_Globe_Icon_Large.png differ diff --git a/docs/source/background/gbo_context.rst b/docs/source/background/gbo_context.rst deleted file mode 100644 index c394d61a..00000000 --- a/docs/source/background/gbo_context.rst +++ /dev/null @@ -1,22 +0,0 @@ -************************** -Context Within GBO Systems -************************** - -Background -========== - -GBTIDL ------- - -`GBTIDL` is the current software used to calibrate SDFITS files from the GBT. - -Requirements -============ - -At its core, `dysh` needs to read in an SDFITS file and ultimately output calibrated data. - -.. mermaid:: - - flowchart LR - A[SDFITS File] --> B[Dysh] - B --> C[Output Data] diff --git a/docs/source/background/img/.gitkeep b/docs/source/background/img/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/source/background/index.rst b/docs/source/background/index.rst deleted file mode 100644 index c546dc11..00000000 --- a/docs/source/background/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -********** -Background -********** - -Why does this exist? - -.. toctree:: - :maxdepth: 2 - - gbo_context - sdfits_files/index diff --git a/docs/source/conf.py b/docs/source/conf.py index f53bf87e..83a9e822 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -58,6 +58,7 @@ "sphinxcontrib.mermaid", "numpydoc", "sphinx_inline_tabs", + "sphinx_design", ] numpydoc_show_class_members = True @@ -75,6 +76,11 @@ # TODO: These appear to have no effect mermaid_verbose = True +# Mermaid configuration +# https://github.com/mgaitan/sphinxcontrib-mermaid +mermaid_version = "11.2.0" +mermaid_params = ["--theme", "dark"] + # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] @@ -101,7 +107,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path . -exclude_patterns = [] +exclude_patterns = ["examples/output"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" @@ -120,11 +126,25 @@ # documentation. # html_theme_options = { + "repository_url": "https://github.com/GreenBankObservatory/dysh", + "repository_branch": "main", "logo": { "image_light": "_static/icon/dysh_logo_lightmode.png", "image_dark": "_static/icon/dysh_logo_darkmode.png", }, + # "show_toc_level": 2, + "use_source_button": True, + "use_issues_button": True, + "use_download_button": True, + "use_sidenotes": True, "show_toc_level": 2, + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/GreenBankObservatory/dysh", + "icon": "fa-brands fa-github", + }, + ], } # Add any paths that contain custom static files (such as style sheets) here, diff --git a/docs/source/examples b/docs/source/examples deleted file mode 120000 index dc9f6698..00000000 --- a/docs/source/examples +++ /dev/null @@ -1 +0,0 @@ -../../notebooks/examples/ \ No newline at end of file diff --git a/docs/source/explanations/index.rst b/docs/source/explanations/index.rst new file mode 100644 index 00000000..3c9841c2 --- /dev/null +++ b/docs/source/explanations/index.rst @@ -0,0 +1,58 @@ +.. _explanations: + +############################################### +:octicon:`repo;2em;purple` Explanation Material +############################################### + +Big-picture explanations of higher-level concepts. Most useful for building understanding of a particular topic. + +dysh +==== + +.. grid:: 1 2 2 2 + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`container;3em;green` **ScanBlock** + + What is a ScanBlock? + + .. button-link:: scanblock/index.html + :color: primary + :tooltip: Details of what is a ScanBlock + :outline: + :click-parent: + + ScanBlock + + +SDFITS +====== + +.. grid:: 1 2 2 2 + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`file;3em;green` **SDFITS** + + What are SDFITS files? + + .. button-link:: sdfits/index.html + :color: primary + :tooltip: SDFITS details + :outline: + :click-parent: + + SDFITS + + +.. toctree:: + :hidden: + :maxdepth: 3 + + scanblock/index + sdfits/index diff --git a/docs/source/explanations/scanblock/index.rst b/docs/source/explanations/scanblock/index.rst new file mode 100644 index 00000000..1d4988e4 --- /dev/null +++ b/docs/source/explanations/scanblock/index.rst @@ -0,0 +1,42 @@ +.. _scanblocks: + +######### +ScanBlock +######### + +.. mermaid:: + + flowchart TD + + subgraph newLines[GBTFITSLoad + 50 Scans + Position Switching + Dual Linear Polarization + 1 Beam + 4 Frequency Windows + 100 integrations each + ] + + + + + end + + + newLines -- getps( scan=45, plnum=1, ifnum=0 ) --> ScanBlock1 + newLines -- gettp( scan=[17,18,19], intnum=np.r_[50:100], ifnum=2 ) --> ScanBlock2 + + + + subgraph ScanBlock1[ScanBlock] + psscan["spectra.scan.PSScan
scans = 44,45
plnum = 1
ifnum = 0
intnum = (0,100)"] + end + subgraph ScanBlock2[ScanBlock] + tpscan1["spectra.scan.TPScan
scan=17
plnum = 0
ifnum = 2
intnum=(50,100)"] + tpscan2["spectra.scan.TPScan
scan=18
plnum = 0
ifnum = 2
intnum=(50,100)"] + tpscan3["spectra.scan.TPScan
scan=19
plnum = 0
ifnum = 2
intnum=(50,100)"] + + end + + ScanBlock1[Scan Block] -- timeaverage() --->spectrum1[Spectrum] + ScanBlock2[Scan Block] -- timeaverage() --->spectrum2[Spectrum] diff --git a/docs/source/explanations/sdfits/index.rst b/docs/source/explanations/sdfits/index.rst new file mode 100644 index 00000000..a57d6d7b --- /dev/null +++ b/docs/source/explanations/sdfits/index.rst @@ -0,0 +1,7 @@ +.. _sdfits-explanation: + +############ +SDFITS Files +############ + +This section is empty for now, but you can check the column definitions :ref:`here `, or the SDFITS convention as defined in `AIPS++ `_ or at `ADASS IX `_, or `the registered SDFITS convention `_. diff --git a/docs/source/for_beta_testers/beta_testing.rst b/docs/source/for_beta_testers/beta_testing.rst index 44e24315..6898e9e3 100644 --- a/docs/source/for_beta_testers/beta_testing.rst +++ b/docs/source/for_beta_testers/beta_testing.rst @@ -70,7 +70,7 @@ We provide steps for working in one of `GBO data reduction hosts `_, +`numpy `_, +`scipy `_, +`pandas `_, +`specutils `_, and +`matplotlib `_. - install - tutorials/index +We strongly recommend the use of a virtual environment for installing `dysh`. + +With `pip` from PyPi +-------------------- + +``dysh`` is most easily installed with ``pip``, which will take care of +any dependencies. The packaged code is hosted at the `Python Packaging +Index `_. + +.. code:: + + $ pip install dysh + +.. warning:: + `dysh` is currently in development and the above command will install the latest stable version of `dysh` which might not reflect the contents of the documentation. + For beta testing please see :ref:`beta-install`. + +From GitHub +----------- + +Installing from GitHub will allow you to install the latest, albeit unstable, version of `dysh`. +To install the main branch of `dysh` with all extra dependencies from GitHub: + +.. code:: + + $ pip install "dysh[all] @ git+https://github.com/GreenBankObservatory/dysh" diff --git a/docs/source/getting_started/install.rst b/docs/source/getting_started/install.rst deleted file mode 100644 index 077407f1..00000000 --- a/docs/source/getting_started/install.rst +++ /dev/null @@ -1,38 +0,0 @@ -******************* -Installing ``dysh`` -******************* - -``dysh`` requires Python 3.9+ and recent versions of -`astropy `_, -`numpy `_, -`scipy `_, -`pandas `_, -`specutils `_, and -`matplotlib `_. - -With `pip` from PyPi -==================== - -``dysh`` is most easily installed with ``pip``, which will take care of -any dependencies. The packaged code is hosted at the `Python Packaging -Index `_. - -.. code:: - - $ pip install dysh - -.. warning:: - `dysh` is currently in development and the above command will install the latest stable version of `dysh` which might not reflect the contents of the documentation. For beta testing please see :ref:`beta-install`. - -From github -=========== - -To install from github without creating a separate virtual environment: - -.. code:: - - $ git clone git@github.com:GreenBankObservatory/dysh.git - $ cd dysh - $ pip install -e . - -If you wish to install using a virtual environment, which we strongly recommend if you plan to contribute to the code, see :doc:`installation instructions for developers <../for_developers/install>`. diff --git a/docs/source/how-tos/examples b/docs/source/how-tos/examples new file mode 120000 index 00000000..d4789f2c --- /dev/null +++ b/docs/source/how-tos/examples @@ -0,0 +1 @@ +../../../notebooks/examples/ \ No newline at end of file diff --git a/docs/source/how-tos/index.rst b/docs/source/how-tos/index.rst new file mode 100644 index 00000000..84737709 --- /dev/null +++ b/docs/source/how-tos/index.rst @@ -0,0 +1,97 @@ +.. _howtos: + +##################################### +:octicon:`terminal;2em;green` Recipes +##################################### + +Practical step-by-step guides to help you achieve a specific goal. Most useful when you're trying to get something done. + + +.. grid:: 1 2 2 2 + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`rocket;3em;green` **Velocity Definitions and Rest Frames** + + How to change velocity definitions and reference frames + + .. button-link:: examples/velocity_frames.html + :color: primary + :outline: + :click-parent: + + Velocity & Frames + + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`file;3em;green` **Metadata Management** + + How to interact with the metadata of an SDFITS file + + .. button-link:: examples/metadata_management.html + :color: primary + :outline: + :click-parent: + + Metadata Management + + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`pulse;3em;green` **Smoothing** + + How to smooth data + + .. button-link:: examples/smoothing.html + :color: primary + :outline: + :click-parent: + + Smoothing + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :material-outlined:`save;3em;green` **Data IO** + + How to read and save data + + .. button-link:: examples/dataIO.html + :color: primary + :outline: + :click-parent: + + Data IO + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :material-outlined:`compare_arrows;3em;green` **Align Spectra** + + How to read and save data + + .. button-link:: examples/align_spectra.html + :color: primary + :outline: + :click-parent: + + Align Spectra + +.. toctree:: + :maxdepth: 4 + :hidden: + + examples/velocity_frames + examples/metadata_management + examples/smoothing + examples/dataIO + examples/align_spectra diff --git a/docs/source/index.rst b/docs/source/index.rst index f3841dac..7dba9adf 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,28 +6,100 @@ `Green Bank Observatory `_ and the Laboratory for Millimeter-Wave Astronomy (LMA) at the `University of Maryland (UMD) `_. -It is intended to replace `GBTIDL `_, GBO's current spectral line data reduction package. +It is intended to replace `GBTIDL `_, GBO's current spectral line data reduction package. Contents =============== +.. grid:: 1 2 2 2 + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`mortar-board;3em;orange` **Tutorials** + + Learning-oriented lessons take you through a series + of steps to complete a project. + + Most useful when you want to get started reducing your data. + + .. button-link:: tutorials/index.html + :color: primary + :outline: + :click-parent: + + Go to Tutorials + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`terminal;3em;green` **Recipes** + + Practical step-by-step guides to help you achieve a specific goal. + + Most useful when you're trying to get something done. + + + .. button-link:: how-tos/index.html + :color: primary + :outline: + :click-parent: + + Go to Recipes + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`repo;3em;purple` **Explanation** + + Big-picture explanations of higher-level concepts. + + Most useful for building understanding of a particular topic. + + + .. button-link:: explanations/index.html + :color: primary + :outline: + :click-parent: + + Go to Explanation Material + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + :octicon:`tools;3em;sd-text-primary` **References** + + Nitty-gritty technical descriptions of how `dysh` works. + + Most useful when you need detailed information about the API or how to + contribute. + + + .. button-link:: reference/index.html + :color: primary + :outline: + :click-parent: + + Go to Reference Material + + .. toctree:: :maxdepth: 2 + :hidden: whatsnew/0.3.rst - background/index getting_started/index - examples/index - modules/index + tutorials/index + how-tos/index + explanations/index + reference/index for_beta_testers/index for_developers/index -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` Reporting Issues ================ @@ -48,4 +120,4 @@ Dev Team | Peter Teuben (UMD) | Pedro Salas (GBO) | Evan Smith (GBO) -| Thomas Chamberlain (GBO) +| Thomas Chamberlin (GBO) diff --git a/docs/source/modules/index.rst b/docs/source/modules/index.rst deleted file mode 100644 index f2ea3fc3..00000000 --- a/docs/source/modules/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -**************** -Modules and APIs -**************** - -.. toctree:: - :maxdepth: 2 - - dysh.fits - dysh.spectra - dysh.plot - dysh.util diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst new file mode 100644 index 00000000..a9f80fe7 --- /dev/null +++ b/docs/source/reference/index.rst @@ -0,0 +1,48 @@ +.. _references: + + +##################################################### +:octicon:`tools;2em;sd-text-primary` Reference Guides +##################################################### + + +.. grid:: 1 2 2 2 + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + **Modules** + + dysh modules and functions + + .. button-link:: modules/index.html + :color: primary + :tooltip: Reference materials for dysh modules + :outline: + :click-parent: + + Modules + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + **SDFITS files** + + SDFITS files + + .. button-link:: sdfits_files/index.html + :color: primary + :tooltip: Reference materials for SDFITS files + :outline: + :click-parent: + + SDFITS files + +.. toctree:: + :maxdepth: 3 + :hidden: + + modules/index + sdfits_files/index diff --git a/docs/source/reference/modules/dysh.coordinates.rst b/docs/source/reference/modules/dysh.coordinates.rst new file mode 100644 index 00000000..37389e18 --- /dev/null +++ b/docs/source/reference/modules/dysh.coordinates.rst @@ -0,0 +1,14 @@ +Spatial and Velocity Coordinates and Reference Frames +===================================================== + +.. automodule:: dysh.coordinates + :members: + :undoc-members: + :show-inheritance: + +Core Functions and Classes +-------------------------- +.. automodule:: dysh.coordinates.core + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/modules/dysh.fits.rst b/docs/source/reference/modules/dysh.fits.rst similarity index 100% rename from docs/source/modules/dysh.fits.rst rename to docs/source/reference/modules/dysh.fits.rst diff --git a/docs/source/modules/dysh.plot.rst b/docs/source/reference/modules/dysh.plot.rst similarity index 100% rename from docs/source/modules/dysh.plot.rst rename to docs/source/reference/modules/dysh.plot.rst diff --git a/docs/source/modules/dysh.spectra.rst b/docs/source/reference/modules/dysh.spectra.rst similarity index 100% rename from docs/source/modules/dysh.spectra.rst rename to docs/source/reference/modules/dysh.spectra.rst diff --git a/docs/source/modules/dysh.util.rst b/docs/source/reference/modules/dysh.util.rst similarity index 100% rename from docs/source/modules/dysh.util.rst rename to docs/source/reference/modules/dysh.util.rst diff --git a/docs/source/reference/modules/index.rst b/docs/source/reference/modules/index.rst new file mode 100644 index 00000000..36346350 --- /dev/null +++ b/docs/source/reference/modules/index.rst @@ -0,0 +1,80 @@ +**************** +Modules and APIs +**************** + +.. grid:: 1 2 2 2 + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + **fits** + + .. button-link:: dysh.fits.html + :color: primary + :outline: + :click-parent: + + Go to dysh.fits + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + **spectra** + + .. button-link:: dysh.spectra.html + :color: primary + :outline: + :click-parent: + + Go to dysh.spectra + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + **plot** + + .. button-link:: dysh.plot.html + :color: primary + :outline: + :click-parent: + + Go to dysh.plot + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + **coordinates** + + .. button-link:: dysh.coordinates.html + :color: primary + :outline: + :click-parent: + + Go to dysh.coordinates + + .. grid-item-card:: + :shadow: md + :margin: 2 2 0 0 + + **util** + + .. button-link:: dysh.util.html + :color: primary + :outline: + :click-parent: + + Go to dysh.util + +.. toctree:: + :maxdepth: 2 + :hidden: + + dysh.fits + dysh.spectra + dysh.plot + dysh.coordinates + dysh.util diff --git a/docs/source/background/sdfits_files/gbt_sdfits.rst b/docs/source/reference/sdfits_files/gbt_sdfits.rst similarity index 96% rename from docs/source/background/sdfits_files/gbt_sdfits.rst rename to docs/source/reference/sdfits_files/gbt_sdfits.rst index 32694006..66bd4e80 100644 --- a/docs/source/background/sdfits_files/gbt_sdfits.rst +++ b/docs/source/reference/sdfits_files/gbt_sdfits.rst @@ -1,3 +1,5 @@ +.. _sdfits-reference: + **************** GBT SDFITS Files **************** @@ -9,7 +11,12 @@ The single-dish FITS (SDFITS) convention is used for observer-facing GBT data. T HDU 0 (PRIMARY) --------------- -.. list-table:: Header +.. _primary-sdfits-header: + +Header +^^^^^^ + +.. list-table:: :widths: 25 25 50 :header-rows: 1 @@ -38,7 +45,12 @@ HDU 0 (PRIMARY) HDU 1 (SINGLE DISH) ------------------- -.. list-table:: Header +.. _singledish-sdfits-header: + +Header +^^^^^^ + +.. list-table:: :widths: 25 25 50 :header-rows: 1 @@ -91,7 +103,10 @@ HDU 1 (SINGLE DISH) - "SINGLE DISH" - The name of this binary table extension -.. list-table:: Data +Data +^^^^ + +.. list-table:: :widths: 20 20 20 40 :header-rows: 1 @@ -630,4 +645,4 @@ Flag files indicate the data that should be ignored. For example, these flags ca Other Resources =============== -The full SDFITS documentation for GBO can be found here: `The GBT SDFITS Project Wiki `_ +The full SDFITS documentation for GBO can be found on `the GBT SDFITS Project Wiki `_. However, this page is out of date and requires a login to view. diff --git a/docs/source/background/sdfits_files/index.rst b/docs/source/reference/sdfits_files/index.rst similarity index 100% rename from docs/source/background/sdfits_files/index.rst rename to docs/source/reference/sdfits_files/index.rst diff --git a/docs/source/tutorials/examples b/docs/source/tutorials/examples new file mode 120000 index 00000000..d4789f2c --- /dev/null +++ b/docs/source/tutorials/examples @@ -0,0 +1 @@ +../../../notebooks/examples/ \ No newline at end of file diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst new file mode 100644 index 00000000..e10cc460 --- /dev/null +++ b/docs/source/tutorials/index.rst @@ -0,0 +1,37 @@ +.. _tutorials: + + +############################################ +:octicon:`mortar-board;2em;orange` Tutorials +############################################ + +Learning-oriented lessons take you through a series of steps to complete a project. +Most useful when you want to get started reducing your data. + + +.. card-carousel:: 2 + + .. card:: Position Switched Data + :link: examples/positionswitch.html + + - Calibrate the data. + + .. card:: Frequency Switched Data + :link: examples/frequencyswitch.html + + - Calibrate the data. + + .. card:: Sub Beam Nod Data + :link: examples/subbeamnod.html + + .. card:: Nodding Data + :link: examples/nodding.html + +.. toctree:: + :maxdepth: 4 + :hidden: + + examples/positionswitch + examples/frequencyswitch + examples/subbeamnod + examples/nodding diff --git a/notebooks/examples/align_spectra.ipynb b/notebooks/examples/align_spectra.ipynb new file mode 100644 index 00000000..2ae61aec --- /dev/null +++ b/notebooks/examples/align_spectra.ipynb @@ -0,0 +1,421 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9359fc63-3229-4fd3-8631-09c181e6a27b", + "metadata": {}, + "source": [ + "# Aligning Spectra\n", + "\n", + "This guide shows how to align spectra before they can be averaged.\n", + "\n", + "We use an observation with a mixed observing strategy; position switching and frequency switching.\n", + "In this case the on and off source observations also switch the signal in the frequency domain between a signal and a reference state, so there are four switching states: signal with the noise diode, signal without the noise diode, reference with the noise diode and reference without the noise diode.\n", + "\n", + "We will calibrate the signal and reference states independently, using position switching. Then, we'll look at the calibrated spectra as a function of channel and vizualize the shift between the signal and reference states. Finally we will shift the reference state and average it with the signal state." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "e34b86e9-6438-4e84-8503-d6dd1699e243", + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "import matplotlib.pyplot as plt\n", + "from dysh.util.download import from_url\n", + "from dysh.fits.gbtfitsload import GBTFITSLoad\n", + "from dysh.spectra import average_spectra" + ] + }, + { + "cell_type": "markdown", + "id": "74f02c88-5632-4f64-abda-6e70f63ff0fd", + "metadata": {}, + "source": [ + "## Data Retrieval\n", + "\n", + "Download the example SDFITS data, if necessary." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cf801734-2ba0-48cd-a664-3ca15ce58890", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting download...\n", + "TGBT24B_613_04.raw.vegas.trim.fits already downloaded at /home/sandboxes/psalas/Dysh/dysh/notebooks/examples/data\n" + ] + } + ], + "source": [ + "url = \"http://www.gb.nrao.edu/dysh/example_data/mixed-fs-ps/data/TGBT24B_613_04.raw.vegas.trim.fits\"\n", + "savepath = Path.cwd() / \"data\"\n", + "filename = from_url(url, savepath)" + ] + }, + { + "cell_type": "markdown", + "id": "66d69520-58ac-46ac-be99-071c5812217c", + "metadata": {}, + "source": [ + "## Data Loading\n", + "\n", + "Next, we use `GBTFITSLoad` to load the data, and then its `summary` method to inspect its contents." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "fb10b18f-4510-4707-ad2a-70a1ec2b4d79", + "metadata": {}, + "outputs": [], + "source": [ + "sdf = GBTFITSLoad(filename)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "62f47e96-7553-48c9-9dfb-032d2af60897", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SCANOBJECTVELOCITYPROCPROCSEQNRESTFREQDOPFREQ# IF# POL# INT# FEEDAZIMUTHELEVATIO
035MESSIER32-200.0OnOff11.4204061.420406115173.11554362.295527
136MESSIER32-200.0OnOff21.4204061.420406115172.30867659.322465
\n", + "
" + ], + "text/plain": [ + " SCAN OBJECT VELOCITY PROC PROCSEQN RESTFREQ DOPFREQ # IF # POL \\\n", + "0 35 MESSIER32 -200.0 OnOff 1 1.420406 1.420406 1 1 \n", + "1 36 MESSIER32 -200.0 OnOff 2 1.420406 1.420406 1 1 \n", + "\n", + " # INT # FEED AZIMUTH ELEVATIO \n", + "0 5 1 73.115543 62.295527 \n", + "1 5 1 72.308676 59.322465 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sdf.summary()" + ] + }, + { + "cell_type": "markdown", + "id": "17ac95ab-15f2-4f45-80cd-cc9d6ca0f001", + "metadata": {}, + "source": [ + "## Data Reduction\n", + "\n", + "### Position Switched Calibration\n", + "\n", + "We calibrate the signal and reference states independently." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d076291b-e69e-4018-ac95-718a7fa3c350", + "metadata": {}, + "outputs": [], + "source": [ + "# Signal.\n", + "ps_sig = sdf.getps(scan=35, sig=\"T\").timeaverage()\n", + "# Reference.\n", + "ps_ref = sdf.getps(scan=35, sig=\"F\").timeaverage()" + ] + }, + { + "cell_type": "markdown", + "id": "5d0d337f-68b5-4efb-a0f4-cc16eec85a74", + "metadata": {}, + "source": [ + "Plot the signal and reference spectra as a function of channel." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "0960e4d5-b2e1-4946-a9af-9d2816f2e43a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure()\n", + "plt.plot(ps_sig.flux)\n", + "plt.plot(ps_ref.flux)\n", + "plt.ylabel(f\"Antenna temperature ({ps_sig.flux.unit})\")\n", + "plt.xlabel(\"Channel\");" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "037dc86e-05f4-4b44-9018-bfc15bc0949e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Noise on the signal state 0.41 K\n", + "Noise on the reference state 0.40 K\n" + ] + } + ], + "source": [ + "print(f\"Noise on the signal state {ps_sig[5000:10000].stats()['rms']:.2f}\")\n", + "print(f\"Noise on the reference state {ps_ref[5000:10000].stats()['rms']:.2f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "1d1b09e3-969d-40db-89bc-f933756423e2", + "metadata": {}, + "source": [ + "If we were to average the data, then the result would have the spectral line misaligned, since the averaging is done per channel. We can see this if we calibrate the data without separating the signal and reference states. This is less than ideal because the signal gets reduced and the line shows up in two different places even though it is the same line." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "95b851e3-75cb-4b7b-b943-f9dbce5033ad", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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hiQpa9euxZw5cywbkJm9//77GDlyJJo2baqyPD09HZMnT0ZUVBTc3d3RsGFDxMTEYNGiRSgqKgIAjB07VuONahMTEyGTyZCTk6NXDG+99Rbef/995ObmmvjbENkm3m2byAZdv35d+f+VK1fi7bffxtmzZ5XLvLy8xAhLVGVlZXBzc4O/v7/YoRikqKgI33zzjfLuytWSk5MRExMDPz8/zJ07F+3atYNcLseJEyewZMkSNG7cGPfdd5/Z4oiOjkZkZCR++uknxMXFmW27RLaCLTRENig4OFj54+vrC5lMprLMy8sLpaWlePnll9GgQQO4u7ujT58+OHDggHIb/fr1w6RJkzBp0iT4+voiMDAQM2fORM370da1DQBQKBSYN28eoqKiIJfL0aRJE7z//vvK5xISEtCsWTN4eHigQ4cO+PXXX1Ve369fP7z88suYPn06/P39ERwcrNLCNHbsWOzYsQOfffaZsgUqJSVFGf+UKVMQGBiIIUOGKLdXszVHV3yaDB8+HGPGjFE+3r59OwIDA1FZWan/H8gAf/75J+RyOXr27Kmy/MUXX4SLiwsOHjyIRx99FK1bt0ZERARGjhyJjRs34t577zXofVJSUjS25vXr10+5zr333osVK1aY49cisjlMaIgkavr06VizZg2+//57HD58GFFRURgyZAiysrKU63z//fdwcXHB/v378dlnn2H+/Pn4+uuvDdpGfHw8PvjgA8ycOROnTp3C8uXL0bBhQwBAQkICfvjhByxevBgnT57E1KlT8dRTT2HHjh0qsX7//ffw9PTEvn37MG/ePLz77rvYunUrAOCzzz5Dr169MH78eFy/fh3Xr19HWFiY8nVubm7YvXs3Fi9erHE/6IpPk8aNGyMtLU35ODY2FsXFxdi7d6++u94gu3btQpcuXVSWZWZmYsuWLYiLi4Onp6fG18lkMoPeJywsTLn/rl+/jiNHjiAgIAB9+/ZVrtO9e3fs378fpaWlhv8iRLZOICKbtmzZMsHX11dlWUFBgeDq6ir8/PPPymVlZWVCSEiIMG/ePEEQBCE2NlZo3bq1oFAolOvMmDFDaN26td7byMvLE+RyubB06VK1uEpKSoR69eoJ//33n8rycePGCaNGjVI+jo2NFfr06aOyTrdu3YQZM2aorDN58mSVdWJjY4VOnTqpvW/NdXXFp82sWbOEli1bqiwL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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ps = sdf.getps(scan=35).timeaverage()\n", + "ps.plot(xaxis_unit=\"GHz\")" + ] + }, + { + "cell_type": "markdown", + "id": "bc32e74f-de9c-4175-a60f-dc2014a4cac1", + "metadata": {}, + "source": [ + "### Align Spectra\n", + "\n", + "Instead, we must align the spectra before averaging. In this case we will shift the reference state spectrum to match the signal state spectrum." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "db03ff0a-944e-4af6-a568-f33b3c36b4fd", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ps_ref_aligned = ps_ref.align_to(ps_sig)\n", + "\n", + "plt.figure()\n", + "plt.plot(ps_sig.flux)\n", + "plt.plot(ps_ref_aligned.flux)\n", + "plt.ylabel(f\"Antenna temperature ({ps_sig.flux.unit})\")\n", + "plt.xlabel(\"Channel\");" + ] + }, + { + "cell_type": "markdown", + "id": "1961a051-3c7a-4435-ab0a-b608b06c4145", + "metadata": {}, + "source": [ + "Now the spectra are aligned and can be averaged together." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "cdf33158-62c0-4f66-a27d-f35fd22b12ea", + "metadata": {}, + "outputs": [], + "source": [ + "ps_avg = average_spectra((ps_sig, ps_ref_aligned))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "1b0c1152-0072-4bd9-9a11-0d5c5cd09fec", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkEAAAGuCAYAAACX/tJnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABZUElEQVR4nO3dd1xTV+MG8CesIEpAZCvTgXsr4raiaH1braPWDrVaa1s77VLbqm3fX7HV1g6tXW+1tcNq6+iwVkVQq4gTFQcKgqACTrbMnN8fSCQkhARCkkue7+fDp9zcc29ObmPycO4ZMiGEABEREZGVsTF3BYiIiIjMgSGIiIiIrBJDEBEREVklhiAiIiKySgxBREREZJUYgoiIiMgqMQQRERGRVWIIIiIiIqvEEERERERWiSGIiIiIrJKduSugzZ49e7B06VIcOXIEGRkZ2LRpE8aNGwcAKC0txZtvvomtW7fiwoULcHFxQXh4OJYsWQJfX98az7l48WK8/fbbao+FhITg7NmzWssrlUpcuXIFzs7OkMlkRnttRERE1HCEEMjLy4Ovry9sbHS39VhkCCooKEC3bt0wY8YMjB8/Xm1fYWEhjh49irfeegvdunXDrVu38MILL+D+++/H4cOHdZ63U6dO2Llzp2rbzq7ml3/lyhX4+fnV74UQERGRWaSnp6NVq1Y6y1hkCBo9ejRGjx6tdZ+Liwt27Nih9tiKFSvQt29fpKWlwd/fv8bz2tnZwdvbW686ODs7A6i4iAqFQs+a6yc3Nxd+fn4Ncm6p4jVRx+uhiddEE6+JJl4TTdZ2TSpfb+X3uC4WGYIMlZOTA5lMBldXV53lzp8/D19fXzg6OiIsLAyRkZE1hqaaboHJ5XLI5fL6VhkAoFAorOINaQheE3W8Hpp4TTTxmmjiNdHUWK9JcXExiouLNR7XpyuL5DtGFxUV4fXXX8eUKVN0/s8NDQ3FmjVrsG3bNqxatQopKSkYNGgQ8vLydJ7fz88PLi4uqp/IyEhjvwQiIiKqo8jISLXvaUO6ski6Jai0tBQPPvgghBBYtWqVzrJVb6917doVoaGhCAgIwPr16zFz5swaj6vefGisViAiIiKqv/nz52Pu3Lmq7crbYfqQbAiqDEAXL17Erl27DG7ic3V1Rbt27ZCUlKSzXEM0H8rlcixatIiBqgpeE3W8Hpp4TTTxmmjiNdHU2K9JfbqpyIQQwsj1MSqZTKY2RB64G4DOnz+P6OhoeHh4GHze/Px8+Pv7Y/HixXj++ec19ufm5sLFxQU5OTmN8h4qERFRY2TI97dF9gnKz89HfHw84uPjAQApKSmIj49HWloaSktLMXHiRBw+fBg//vgjysvLkZmZiczMTJSUlKjOMXz4cKxYsUK1/corr2D37t1ITU3F/v378cADD8DW1hZTpkwx9csjIiIiC2CRt8MOHz6MYcOGqbYr7/VNmzYNixcvxu+//w4A6N69u9px0dHRGDp0KAAgOTkZ169fV+27dOkSpkyZghs3bsDDwwMDBw7EgQMH6tSKRERERNJn8bfDzIW3w4iIiKRH8rfDiIiIiBoaQxARERFZJYYgIiIiskoMQURERGSVGIKIiIjIKjEEEZEkRSdexcroJOQWlZq7KkQkURY5TxARkS6Xs2/j8dWHAADpNwuxZEJXM9eIiKSILUFEJDmHUm6qfl93KN2MNSEiKWMIIiIiIqvEEEREkiOTqW+XlSvNUxEikjSGICKSvL9OZpi7CkQkQQxBRCQ5V3OL1bZzi8rMVBMikjKGICKSnBsFJWrbshrKERHpwhBERJJjW+2Tq3ofISIifTAEEZHk2Nqof3TJ2BZERHXAEERE0iOE2uaZjFwzVYSIpIwhiIgkZ0V0ktr22gMXzVQTIpIyhiAikhylqL0MEVFtGIKIiIjIKjEEERERkVViCCIiIiKrxBBEREREVokhiIiIiKwSQxARERFZJYYgIiIiskoMQURERGSVGIKIiIjIKjEEERERkVViCCIiIiKrxBBEREREVokhiIiIiKwSQxARERFZJYYgIiIiskoMQURERGSVGIKIiIjIKjEEERERkVViCCIiIiKrxBBEREREVokhiIiIiKySRYagPXv24L777oOvry9kMhk2b96stl8IgYULF8LHxwdNmjRBeHg4zp8/X+t5V65cicDAQDg6OiI0NBQHDx5soFdAREREls4iQ1BBQQG6deuGlStXat3/wQcf4NNPP8UXX3yBuLg4NG3aFBERESgqKqrxnL/88gvmzp2LRYsW4ejRo+jWrRsiIiJw9erVhnoZREREZMFkQghh7kroIpPJsGnTJowbNw5ARSuQr68vXn75ZbzyyisAgJycHHh5eWHNmjV46KGHtJ4nNDQUffr0wYoVKwAASqUSfn5+eO65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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ps_avg.plot(xaxis_unit=\"chan\")" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "8ef254f2-4323-453b-825d-3ba8e9d1938e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Noise on the average 0.26 K\n" + ] + } + ], + "source": [ + "print(f\"Noise on the average {ps_avg[5000:10000].stats()['rms']:.2f}\")" + ] + }, + { + "cell_type": "markdown", + "id": "320a0e99-9042-44a9-b3f1-2a43bff985b8", + "metadata": {}, + "source": [ + "The resulting spectrum shows only one peak, at the frequency of the line, and the noise is smaller than in the individual states where the spectra overlapped (channels below ~18000). The noise improvement is better than $\\sqrt{2}$ since shifting the reference spectrum for the alignment artificially lowers its noise." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e4536016-0561-4c61-89c9-e1b9dc67abd8", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.0" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/examples/index.rst b/notebooks/examples/index.rst deleted file mode 100644 index 9aef2736..00000000 --- a/notebooks/examples/index.rst +++ /dev/null @@ -1,15 +0,0 @@ -********************* -Examples for GBT Data -********************* - -.. toctree:: - :glob: - :maxdepth: 1 - - frequencyswitch - positionswitch - metadata_management - subbeamnod - smoothing - velocity_frames - dataIO diff --git a/pyproject.toml b/pyproject.toml index 8bda1dc5..6354fe0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "dysh" description = '' readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10,<3.13" license = {file = "LICENSE"} keywords = [] dynamic = ["version"] @@ -16,10 +16,6 @@ authors = [ classifiers = [ "Development Status :: 3 - Alpha", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", ] dependencies = [ @@ -50,6 +46,7 @@ dev = [ "sphinx-autobuild", "sphinx-inline-tabs", "sphinx-book-theme", + "sphinx-design", "sphinxcontrib-mermaid", "nbformat", "nbclient", @@ -95,7 +92,7 @@ cov = "pytest --cov-report=xml --cov-config=pyproject.toml --cov=src/dysh --cov= # Run tests across all supported version of Python [[tool.hatch.envs.test.matrix]] -python = ["39", "310", "311", "312"] +python = ["310", "311", "312"] [tool.hatch.build.targets.sdist] include = ["/src", "/tests", "/bin"] diff --git a/requirements.txt b/requirements.txt index ed124203..509d459e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.9 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --extra=dev --extra=nb --no-emit-trusted-host --output-file=requirements.txt pyproject.toml @@ -121,11 +121,6 @@ docutils==0.18.1 # myst-parser # pydata-sphinx-theme # sphinx -exceptiongroup==1.2.0 - # via - # anyio - # ipython - # pytest executing==2.0.1 # via stack-data fastjsonschema==2.19.0 @@ -161,17 +156,8 @@ imagesize==1.4.1 importlib-metadata==6.8.0 # via # asdf - # build # jupyter-cache - # jupyter-client - # jupyter-lsp - # jupyterlab - # jupyterlab-server # myst-nb - # nbconvert - # sphinx -importlib-resources==6.1.1 - # via matplotlib iniconfig==2.0.0 # via pytest ipdb==0.13.13 @@ -525,6 +511,7 @@ sphinx-autobuild==2021.3.14 # via dysh (pyproject.toml) sphinx-book-theme==1.1.3 # via dysh (pyproject.toml) +sphinx-design==0.6.0 sphinx-inline-tabs==2023.4.21 # via dysh (pyproject.toml) sphinxcontrib-applehelp==1.0.7 @@ -557,15 +544,6 @@ terminado==0.18.0 # jupyter-server-terminals tinycss2==1.2.1 # via nbconvert -tomli==2.0.1 - # via - # build - # coverage - # ipdb - # jupyterlab - # numpydoc - # pip-tools - # pytest tornado==6.3.3 # via # ipykernel @@ -596,8 +574,6 @@ types-python-dateutil==2.8.19.14 # via arrow typing-extensions==4.8.0 # via - # async-lru - # ipython # myst-nb # pydata-sphinx-theme # sqlalchemy @@ -624,9 +600,7 @@ wheel==0.43.0 widgetsnbextension==4.0.9 # via ipywidgets zipp==3.17.0 - # via - # importlib-metadata - # importlib-resources + # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/src/dysh/coordinates/core.py b/src/dysh/coordinates/core.py index aaeb927c..16a288f3 100644 --- a/src/dysh/coordinates/core.py +++ b/src/dysh/coordinates/core.py @@ -342,28 +342,29 @@ def sanitize_skycoord(target): # @todo version that takes a SpectralCoord def topocentric_velocity_to_frame(target, toframe, observer, obstime): """Compute the difference in topocentric velocity and the velocity in the input frame. + Parameters ---------- - target: `~astropy.coordinates.SkyCoord` - The sky coordinates of the object including proper motion and distance. Must be in ICRS - target: `~astropy.coordinates.SkyCoord` - The sky coordinates of the object including proper motion and distance. Must be in ICRS + target: `~astropy.coordinates.SkyCoord` + The sky coordinates of the object including proper motion and distance. Must be in ICRS + target: `~astropy.coordinates.SkyCoord` + The sky coordinates of the object including proper motion and distance. Must be in ICRS - toframe: str - The frame into which `coord` should be transformed, e.g., 'icrs', 'lsrk', 'hcrs'. - The string 'topo' is interpreted as 'itrs'. - See astropy-supported reference frames (link) + toframe: str + The frame into which `coord` should be transformed, e.g., 'icrs', 'lsrk', 'hcrs'. + The string 'topo' is interpreted as 'itrs'. + See astropy-supported reference frames (link) - observer: `~astropy.coordinates.EarthLocation` - The location of the observer + observer: `~astropy.coordinates.EarthLocation` + The location of the observer - obstime: `~astropy.time.Time` - The time of the observation + obstime: `~astropy.time.Time` + The time of the observation Returns ------- - radial_velocity : `~astropy.units.Quantity` - The radial velocity of the source in `toframe` + radial_velocity : `~astropy.units.Quantity` + The radial velocity of the source in `toframe` """ if not isinstance(target.frame, coord.ICRS): @@ -389,8 +390,7 @@ def get_velocity_in_frame(target, toframe, observer=None, obstime=None): done: * If proper motions attributes of `target` are not set, they will be set to zero. - * Similarly, if distance attribute of `target` is not set, it will - be set to a very large number. + * Similarly, if distance attribute of `target` is not set, it will be set to a very large number. * This is done on a copy of the coordinate so as not to change the input object. toframe: str @@ -438,12 +438,13 @@ def veltofreq(velocity, restfreq, veldef): restfreq: `~astropy.units.Quantity` The rest frequency veldef : str - Velocity definition from FITS header, e.g., 'OPTI-HELO', 'VELO-LSR' + Velocity definition from FITS header, e.g., 'OPTI-HELO', 'VELO-LSR'. Returns ------- - frequency: `~astropy.units.Quantity` - The velocity values converted to frequency using `restfreq` and `veldef' + frequency: `~astropy.units.Quantity` + The velocity values converted to frequency using `restfreq` and `veldef`. + """ vdef = veldef_to_convention(veldef) @@ -546,7 +547,7 @@ def __new__(cls): def gbt_location(): """ Create an astropy EarthLocation for the GBT using the same established by GBO. - See: page 3: https://www.gb.nrao.edu/GBT/MC/doc/dataproc/gbtLOFits/gbtLOFits.pdf + See page 3 of https://www.gb.nrao.edu/GBT/MC/doc/dataproc/gbtLOFits/gbtLOFits.pdf latitude = 38d 25m 59.265s N longitude = 79d 50m 23.419s W height = 854.83 m @@ -554,9 +555,9 @@ def gbt_location(): Note these differ from astropy's "GBT" EarthLocation by several meters. Returns - ---------- - gbt : `~astropy.coordinates.EarthLocation` - astropy EarthLocation for the GBT + ------- + gbt : `~astropy.coordinates.EarthLocation` + astropy EarthLocation for the GBT """ gbt_lat = 38.4331291667 * u.deg gbt_lon = -79.839838611 * u.deg @@ -582,9 +583,10 @@ class Observatory: This can be used for instance in transforming velocities between different reference frames. - Example usage - ------------- + Examples + -------- .. code-block:: + obs = Observatory() print(obs['GBT']) print(obs['ALMA']) @@ -592,6 +594,7 @@ class Observatory: Alternatively, you can treat Observatory like a dict: .. code-block:: + gbt = Observatory["GBT"] """ diff --git a/src/dysh/fits/gbtfitsload.py b/src/dysh/fits/gbtfitsload.py index d74010bb..6ec88553 100644 --- a/src/dysh/fits/gbtfitsload.py +++ b/src/dysh/fits/gbtfitsload.py @@ -12,9 +12,16 @@ from dysh.log import logger from ..coordinates import Observatory, decode_veldef -from ..log import HistoricalBase, dysh_date, log_call_to_history, log_call_to_result +from ..log import HistoricalBase, log_call_to_history, log_call_to_result from ..spectra.scan import FSScan, NodScan, PSScan, ScanBlock, SubBeamNodScan, TPScan -from ..util import consecutive, indices_where_value_changes, keycase, select_from, uniq +from ..util import ( + consecutive, + convert_array_to_mask, + indices_where_value_changes, + keycase, + select_from, + uniq, +) from ..util.selection import Flag, Selection from .sdfitsload import SDFITSLoad @@ -211,6 +218,7 @@ def flags(self): @property def final_flags(self): + # this method is not particularly useful. consider removing it """ The merged flag rules in the Flag object. See :meth:`~dysh.util.SelectionBase.final` @@ -221,13 +229,9 @@ def final_flags(self): The final merged flags """ - all_channels_flagged = np.where(self._table["CHAN"] == "") - + # all_channels_flagged = np.where(self._table["CHAN"] == "")j return self._flag.final - def _set_flags(self): - self.final_flags - def filenames(self): """ The list of SDFITS filenames(s) that make up this GBTFITSLoad object @@ -274,7 +278,7 @@ def index(self, hdu=None, bintable=None, fitsindex=None): return df # override sdfits version - def rawspectra(self, bintable, fitsindex): + def rawspectra(self, bintable, fitsindex, setmask=False): """ Get the raw (unprocessed) spectra from the input bintable. @@ -284,6 +288,8 @@ def rawspectra(self, bintable, fitsindex): The index of the `bintable` attribute fitsindex: int the index of the FITS file contained in this GBTFITSLoad. Default:0 + setmask : boolean + If True, set the mask according to the current flags. Defaultf:false Returns ------- @@ -598,7 +604,7 @@ def select_within(self, tag=None, **kwargs): self._selection.select_within(tag=tag, **kwargs) @log_call_to_history - def select_channel(self, chan, tag=None): + def select_channel(self, channel, tag=None): """ Select channels and/or channel ranges. These are NOT used in :meth:`final` but rather will be used to create a mask for calibration or @@ -620,21 +626,28 @@ def select_channel(self, chan, tag=None): Parameters ---------- - chan : number, or array-like + channel : number, or array-like The channels to select Returns ------- None. """ - self._selection.select_channel(tag=tag, chan=chan) + self._selection.select_channel(tag=tag, channel=channel) + + @log_call_to_history + def clear_selection(self): + """Clear all selections for these data""" + self._selection.clear() @log_call_to_history def flag(self, tag=None, **kwargs): """Add one or more exact flag rules, e.g., `key1 = value1, key2 = value2, ...` - If `value` is array-like then a match to any of the array members will be selected. - For instance `flag(object=['3C273', 'NGC1234'])` will flag data for either of those - objects and `flag(ifnum=[0,2])` will flag IF number 0 or IF number 2. + If `value` is array-like then a match to any of the array members will be flagged. + For instance `flag(object=['3C273', 'NGC1234'])` will select data for either of those + objects and `flag(ifnum=[0,2])` will flag IF number 0 or IF number 2. Channels for selected data + can be flagged using keyword `channel`, e.g., `flag(object='MBM12',channel=[0,23])` + will flag channels 0 through 23 *inclusive* for object MBM12. See `~dysh.util.selection.Flag`. Parameters @@ -708,7 +721,7 @@ def flag_within(self, tag=None, **kwargs): self._flag.flag_within(tag=tag, **kwargs) @log_call_to_history - def flag_channel(self, chan, tag=None): + def flag_channel(self, channel, tag=None): """ Select channels and/or channel ranges. These are NOT used in :meth:`final` but rather will be used to create a mask for @@ -716,6 +729,8 @@ def flag_channel(self, chan, tag=None): nested arrays will be treated as ranges, for instance `` + # flag channel 128 + flag_channel(128) # flags channels 1 and 10 flag_channel([1,10]) # flags channels 1 thru 10 inclusive @@ -730,14 +745,48 @@ def flag_channel(self, chan, tag=None): Parameters ---------- - chan : number, or array-like + channel : number, or array-like The channels to flag Returns ------- None. """ - self._flag.flag_channel(tag=tag, chan=chan) + self._flag.flag_channel(tag=tag, channel=channel) + + @log_call_to_history + def apply_flags(self): + """ + Set the channel flags according to the rules specified in the `flags` attribute. + This sets numpy masks in the underlying `SDFITSLoad` objects. + + Returns + ------- + None. + + """ + # Loop over the dict of flagged channels, which + # have the same key as the flag rules. + # For all SDFs in each flag rule, set the flag mask(s) + # for their rows. The index of the sdf._flagmask array is the bintable index + for key, chan in self._flag._flag_channel_selection.items(): + selection = self._flag.get(key) + # chan will be a list or a list of lists + # If it is a single list, it is just a list of channels + # if it is list of lists, then it is upper lower inclusive + dfs = selection.groupby(["FITSINDEX", "BINTABLE"]) + # the dict key for the groups is a tuple (fitsindex,bintable) + for i, ((fi, bi), g) in enumerate(dfs): + chan_mask = convert_array_to_mask(chan, self._sdf[fi].nchan(bi)) + rows = g["ROW"].to_numpy() + self._sdf[fi]._flagmask[bi][rows] = chan_mask + + @log_call_to_history + def clear_flags(self): + """Clear all flags for these data""" + for sdf in self._sdf: + sdf._init_flags() + self._flag.clear() def _create_index_if_needed(self): if self._selection is not None: @@ -760,9 +809,6 @@ def _create_index_if_needed(self): self._construct_procedure() self._construct_integration_number() - def _create_flagmask(self): - """Creates the mask which is NFILESxNINTxNCHAN which will be used for setting channel flags""" - def _construct_procedure(self): """ Construct the procedure string (PROC) from OBSMODE and add it to the index (i.e., a new SDFITS column). @@ -818,23 +864,23 @@ def _construct_integration_number(self): idx = g.index intnumarray[idx] = intnums[i] self._index["INTNUM"] = intnumarray - # Wait until after INTNUM PR: - # self._flag["INTNUM"] = intnumarray - - # Here need to add it as a new column in the BinTableHDU, - # but we have to sort out FITSINDEX. - # s.add_col("INTNUM",intnumarray) - fits_index_changes = indices_where_value_changes("FITSINDEX", self._index) - lf = len(fits_index_changes) - for i in range(lf): - fic = fits_index_changes[i] - if i + 1 < lf: - fici = fits_index_changes[i + 1] - else: - fici = -1 - fi = self["FITSINDEX"][fic] - # @todo fix this MWP - # self._sdf[fi].add_col("INTNUM", intnumarray[fic:fici]) # bintable index??? + self._flag["INTNUM"] = intnumarray + + if False: + # Here need to add it as a new column in the BinTableHDU, + # but we have to sort out FITSINDEX. + # s.add_col("INTNUM",intnumarray) + fits_index_changes = indices_where_value_changes("FITSINDEX", self._index) + lf = len(fits_index_changes) + for i in range(lf): + fic = fits_index_changes[i] + if i + 1 < lf: + fici = fits_index_changes[i + 1] + else: + fici = -1 + fi = self["FITSINDEX"][fic] + # @todo fix this MWP + # self._sdf[fi].add_col("INTNUM", intnumarray[fic:fici]) # bintable index??? def info(self): """Return information on the HDUs contained in this object. See :meth:`~astropy.HDUList/info()`""" @@ -852,6 +898,7 @@ def gettp( weights="tsys", bintable=None, smoothref=1, + apply_flags=True, **kwargs, ): """ @@ -874,6 +921,8 @@ def gettp( None or 'tsys' to indicate equal weighting or tsys weighting to use in time averaging. Default: 'tsys' bintable : int, optional Limit to the input binary table index. The default is None which means use all binary tables. + smooth_ref: int, optional + the number of channels in the reference to boxcar smooth prior to calibration **kwargs : dict Optional additional selection keyword arguments, typically given as key=value, though a dictionary works too. @@ -886,13 +935,14 @@ def gettp( """ TF = {True: "T", False: "F"} - + if apply_flags: + self.apply_flags() if len(self._selection._selection_rules) > 0: _final = self._selection.final else: _final = self._index scans = kwargs.get("scan", None) - debug = kwargs.pop("debug", False) + # debug = kwargs.pop("debug", False) kwargs = keycase(kwargs) if type(scans) is int: scans = [scans] @@ -908,7 +958,7 @@ def gettp( # now downselect with any additional kwargs ps_selection._select_from_mixed_kwargs(**kwargs) _sf = ps_selection.final - logger.debug("SF=", _sf) + logger.debug(f"SF={_sf}") ifnum = uniq(_sf["IFNUM"]) plnum = uniq(_sf["PLNUM"]) scans = uniq(_sf["SCAN"]) @@ -938,9 +988,9 @@ def gettp( # df = select_from("CAL", TF[cal], df) # the rows with the selected sig state and all cal states tprows = list(_sifdf["ROW"]) - logger.debug("TPROWS len=", len(tprows)) - logger.debug("CALROWS on len=", len(calrows["ON"])) - logger.debug("fitsindex=", i) + logger.debug(f"TPROWS len={len(tprows)}") + logger.debug(f"CALROWS on len={len(calrows['ON'])}") + logger.debug(f"fitsindex={i}") if len(tprows) == 0: continue g = TPScan( @@ -953,6 +1003,7 @@ def gettp( bintable, calibrate, smoothref=smoothref, + apply_flags=apply_flags, ) g.merge_commentary(self) scanblock.append(g) @@ -964,7 +1015,15 @@ def gettp( @log_call_to_result def getps( - self, calibrate=True, timeaverage=True, polaverage=False, weights="tsys", bintable=None, smoothref=1, **kwargs + self, + calibrate=True, + timeaverage=True, + polaverage=False, + weights="tsys", + bintable=None, + smoothref=1, + apply_flags=True, + **kwargs, ): """ Retrieve and calibrate position-switched data. @@ -984,6 +1043,10 @@ def getps( bintable : int, optional Limit to the input binary table index. The default is None which means use all binary tables. (This keyword should eventually go away) + smooth_ref: int, optional + the number of channels in the reference to boxcar smooth prior to calibration + apply_flags : boolean, optional. If True, apply flags before calibration. + See :meth:`apply_flags`. Default: True **kwargs : dict Optional additional selection keyword arguments, typically given as key=value, though a dictionary works too. @@ -1000,6 +1063,9 @@ def getps( ScanBlock containing the individual `~spectra.scan.PSScan`s """ + + if apply_flags: + self.apply_flags() # either the user gave scans on the command line (scans !=None) or pre-selected them # with select_fromion.selectXX(). In either case make sure the matching ON or OFF # is in the starting selection. @@ -1092,6 +1158,7 @@ def getps( bintable=bintable, calibrate=calibrate, smoothref=smoothref, + apply_flags=apply_flags, ) g.merge_commentary(self) scanblock.append(g) @@ -1104,7 +1171,15 @@ def getps( @log_call_to_result def getnod( - self, calibrate=True, timeaverage=True, polaverage=False, weights="tsys", bintable=None, smoothref=1, **kwargs + self, + calibrate=True, + timeaverage=True, + polaverage=False, + weights="tsys", + bintable=None, + smoothref=1, + apply_flags=True, + **kwargs, ): """ Retrieve and calibrate nodding data. @@ -1128,6 +1203,10 @@ def getnod( bintable : int, optional Limit to the input binary table index. The default is None which means use all binary tables. (This keyword should eventually go away) + smooth_ref: int, optional + the number of channels in the reference to boxcar smooth prior to calibration + apply_flags : boolean, optional. If True, apply flags before calibration. + See :meth:`apply_flags`. Default: True **kwargs : dict Optional additional selection keyword arguments, typically given as key=value, though a dictionary works too. @@ -1159,8 +1238,8 @@ def get_nod_beams(sdf): if len(d1["FDNUM"].unique()) == 1 and len(d2["FDNUM"].unique()) == 1: beam1 = d1["FDNUM"].unique()[0] beam2 = d2["FDNUM"].unique()[0] - fdnum1 = d1["FEED"].unique()[0] - fdnum2 = d2["FEED"].unique()[0] + # fdnum1 = d1["FEED"].unique()[0] + # fdnum2 = d2["FEED"].unique()[0] return [beam1, beam2] else: # one more attempt (this can happen if PROCSCAN contains "Unknown") @@ -1171,6 +1250,8 @@ def get_nod_beams(sdf): return list(b) return [] + if apply_flags: + self.apply_flags() nod_beams = get_nod_beams(self) feeds = kwargs.pop("fdnum", None) if feeds is None: @@ -1293,6 +1374,7 @@ def get_nod_beams(sdf): bintable=bintable, calibrate=calibrate, smoothref=smoothref, + apply_flags=apply_flags, ) g.merge_commentary(self) scanblock.append(g) @@ -1318,6 +1400,7 @@ def getfs( weights="tsys", bintable=None, smoothref=1, + apply_flags=True, observer_location=Observatory["GBT"], **kwargs, ): @@ -1350,6 +1433,10 @@ def getfs( The default is 'tsys'. bintable : int, optional Limit to the input binary table index. The default is None which means use all binary tables. + smooth_ref: int, optional + the number of channels in the reference to boxcar smooth prior to calibration + apply_flags : boolean, optional. If True, apply flags before calibration. + See :meth:`apply_flags`. Default: True observer_location : `~astropy.coordinates.EarthLocation` Location of the observatory. See `~dysh.coordinates.Observatory`. This will be transformed to `~astropy.coordinates.ITRS` using the time of @@ -1373,6 +1460,9 @@ def getfs( """ debug = kwargs.pop("debug", False) logger.debug(kwargs) + + if apply_flags: + self.apply_flags() # either the user gave scans on the command line (scans !=None) or pre-selected them # with self.selection.selectXX() if len(self._selection._selection_rules) > 0: @@ -1391,7 +1481,7 @@ def getfs( for k, v in preselected.items(): if k not in kwargs: kwargs[k] = v - logger.debug("scans/w sel:", scans, self._selection) + logger.debug(f"scans/w sel: {scans} {self._selection}") fs_selection = copy.deepcopy(self._selection) # now downselect with any additional kwargs logger.debug(f"SELECTION FROM MIXED KWARGS {kwargs}") @@ -1408,6 +1498,8 @@ def getfs( scanblock = ScanBlock() for i in range(len(self._sdf)): + logger.debug(f"Processing file {i}: {self._sdf[i].filename}") + df = select_from("FITSINDEX", i, _sf) for k in ifnum: _ifdf = select_from("IFNUM", k, df) # one FSScan per ifnum @@ -1441,6 +1533,7 @@ def getfs( use_sig=use_sig, observer_location=observer_location, smoothref=1, + apply_flags=apply_flags, debug=debug, ) g.merge_commentary(self) @@ -1464,6 +1557,7 @@ def subbeamnod( weights="tsys", bintable=None, smoothref=1, + apply_flags=True, **kwargs, ): """Get a subbeam nod power scan, optionally calibrating it. @@ -1486,6 +1580,10 @@ def subbeamnod( None to indicate equal weighting or 'tsys' to indicate tsys weighting to use in time averaging. Default: 'tsys' bintable : int, optional Limit to the input binary table index. The default is None which means use all binary tables. + smooth_ref: int, optional + the number of channels in the reference to boxcar smooth prior to calibration + apply_flags : boolean, optional. If True, apply flags before calibration. + See :meth:`apply_flags`. Default: True **kwargs : dict Optional additional selection keyword arguments, typically given as key=value, though a dictionary works too. @@ -1496,12 +1594,15 @@ def subbeamnod( data : `~spectra.scan.ScanBlock` A ScanBlock containing one or more `~spectra.scan.SubBeamNodScan` """ + + if apply_flags: + self.apply_flags() if len(self._selection._selection_rules) > 0: _final = self._selection.final else: _final = self._index scans = kwargs.get("scan", None) - debug = kwargs.pop("debug", False) + # debug = kwargs.pop("debug", False) kwargs = keycase(kwargs) logger.debug(kwargs) @@ -1612,6 +1713,7 @@ def subbeamnod( bintable, calibrate=calibrate, smoothref=smoothref, + apply_flags=apply_flags, ) ) calrows = {"ON": sgon, "OFF": sgoff} @@ -1627,9 +1729,17 @@ def subbeamnod( bintable, calibrate=calibrate, smoothref=smoothref, + apply_flags=apply_flags, ) ) - sb = SubBeamNodScan(sigtp, reftp, calibrate=calibrate, weights=weights, smoothref=smoothref) + sb = SubBeamNodScan( + sigtp, + reftp, + calibrate=calibrate, + weights=weights, + smoothref=smoothref, + apply_flags=apply_flags, + ) scanblock.append(sb) elif method == "scan": for sdfi in range(len(self._sdf)): @@ -1655,6 +1765,7 @@ def subbeamnod( weights=weights, calibrate=calibrate, smoothref=smoothref, + apply_flags=apply_flags, ) sigtp.append(tpon[0]) tpoff = self.gettp( @@ -1669,6 +1780,7 @@ def subbeamnod( weights=weights, calibrate=calibrate, smoothref=smoothref, + apply_flags=apply_flags, ) reftp.append(tpoff[0]) # in order to reproduce gbtidl tsys, we need to do a normal @@ -1684,7 +1796,8 @@ def subbeamnod( weights=weights, calibrate=calibrate, smoothref=smoothref, - ) # .timeaverage(weights=w) + apply_flags=apply_flags, + ) fulltp.append(ftp[0]) sb = SubBeamNodScan( sigtp, @@ -1692,6 +1805,7 @@ def subbeamnod( calibrate=calibrate, weights=weights, smoothref=smoothref, + apply_flags=apply_flags, ) sb.merge_commentary(self) scanblock.append(sb) @@ -2206,7 +2320,7 @@ def write( given as key=value, though a dictionary works too. e.g., `ifnum=1, plnum=[2,3]` etc. """ - debug = kwargs.pop("debug", False) + # debug = kwargs.pop("debug", False) logger.debug(kwargs) selection = Selection(self._index) if len(kwargs) > 0: diff --git a/src/dysh/fits/sdfitsload.py b/src/dysh/fits/sdfitsload.py index a36c386b..3a10c60e 100644 --- a/src/dysh/fits/sdfitsload.py +++ b/src/dysh/fits/sdfitsload.py @@ -57,11 +57,11 @@ def __init__(self, filename, source=None, hdu=None, **kwargs): if doindex: self.create_index() # add default channel masks - self._flagmask = [] - # if doflag: - # for i in range(len(self._bintable)): - # nc = self.nchan(i) - # self._flagmask.append(np.full(nc, False)) + # These are numpy masks where False is not flagged, True is flagged. + # There is one 2-D flag mask arraywith shape NROWSxNCHANNELS per bintable + self._flagmask = None + if doflag: + self._init_flags() def __del__(self): # We need to ensure that any open HDUs are properly @@ -72,6 +72,15 @@ def __del__(self): except Exception: pass + def _init_flags(self): + """initialize the channel masks to False""" + self._flagmask = np.empty(len(self._bintable), dtype=object) + for i in range(len(self._flagmask)): + nc = self.nchan(i) + nr = self.nrows(i) + logger.debug(f"{nr=} {nc=}") + self._flagmask[i] = np.full((nr, nc), fill_value=False) + def info(self): """Return the `~astropy.HDUList` info()""" return self._hdu.info() @@ -358,7 +367,7 @@ def _find_bintable_and_row(self, row): """ return (self._index.iloc[row]["BINTABLE"], self._index.iloc[row]["ROW"]) - def rawspectra(self, bintable): + def rawspectra(self, bintable, setmask=False): """ Get the raw (unprocessed) spectra from the input bintable. @@ -366,16 +375,23 @@ def rawspectra(self, bintable): ---------- bintable : int The index of the `bintable` attribute + setmask : bool + If True, set the data mask according to the current flags in the `_flagmask` attribute. If False, set the data mask to False. Returns ------- - rawspectra : ~numpy.ndarray - The DATA column of the input bintable + rawspectra : ~numpy.ma.MaskedArray + The DATA column of the input bintable, masked according to `setmask` """ - return self._bintable[bintable].data[:]["DATA"] + data = self._bintable[bintable].data[:]["DATA"] + if setmask: + rawspec = np.ma.MaskedArray(data, mask=self._flagmask[bintable]) + else: + rawspec = np.ma.MaskedArray(data, mask=False) + return rawspec - def rawspectrum(self, i, bintable=0): + def rawspectrum(self, i, bintable=0, setmask=False): """ Get a single raw (unprocessed) spectrum from the input bintable. @@ -385,18 +401,25 @@ def rawspectrum(self, i, bintable=0): The row index to retrieve. bintable : int or None The index of the `bintable` attribute. If None, the underlying bintable is computed from i - + setmask : bool + If True, set the data mask according to the current flags in the `_flagmask` attribute. Returns ------- - rawspectrum : ~numpy.ndarray - The i-th row of DATA column of the input bintable + rawspectrum : ~numpy.ma.MaskedArray + The i-th row of DATA column of the input bintable, masked according to `setmask` """ if bintable is None: (bt, row) = self._find_bintable_and_row(i) - return self._bintable[bt].data[:]["DATA"][row] + data = self._bintable[bt].data[:]["DATA"][row] + else: + data = self._bintable[bintable].data[:]["DATA"][i] + row = i + if setmask: + rawspec = np.ma.MaskedArray(data, mask=self._flagmask[bintable][row]) else: - return self._bintable[bintable].data[:]["DATA"][i] + rawspec = np.ma.MaskedArray(data, False) + return rawspec def getrow(self, i, bintable=0): """ @@ -444,7 +467,7 @@ def getspec(self, i, bintable=0, observer_location=None): meta["NAXIS1"] = len(data) if "CUNIT1" not in meta: meta["CUNIT1"] = "Hz" # @todo this is in gbtfits.hdu[0].header['TUNIT11'] but is it always TUNIT11? - logger.debug(f"Fixing CUNIT1 to Hz") + logger.debug("Fixing CUNIT1 to Hz") meta["CUNIT2"] = "deg" # is this always true? meta["CUNIT3"] = "deg" # is this always true? restfrq = meta["RESTFREQ"] @@ -472,7 +495,7 @@ def getspec(self, i, bintable=0, observer_location=None): for k, v, c in h.cards: if k == ukey: if bunit != v: - logger.info(f"Found BUNIT={bunit}, now finding {uKey}={v}, using the latter") + logger.info(f"Found BUNIT={bunit}, now finding {ukey}={v}, using the latter") bunit = v break if bunit is not None: @@ -519,7 +542,7 @@ def nchan(self, bintable): Number channels in the first spectrum of the input bintable """ - return np.shape(self.rawspectrum(1, bintable))[0] + return np.shape(self.rawspectrum(0, bintable))[0] def npol(self, bintable): """ @@ -865,7 +888,6 @@ def _update_binary_table_column(self, column_dict): self._bintable[0].data[k] = v # otherwise we need to add rather than replace/update else: - # print("ADDING {k}={v}") self._add_binary_table_column(k, v, 0) else: start = 0 @@ -904,7 +926,6 @@ def _update_binary_table_column(self, column_dict): def __getitem__(self, items): # items can be a single string or a list of strings. # Want case insensitivity - # @todo deal with "DATA" if isinstance(items, str): items = items.upper() elif isinstance(items, (Sequence, np.ndarray)): @@ -923,7 +944,6 @@ def __getitem__(self, items): return self._index[items] def __setitem__(self, items, values): - # @todo deal with "DATA" if isinstance(items, str): items = items.upper() d = {items: values} @@ -943,7 +963,6 @@ def __setitem__(self, items, values): else: iset = set(items) col_exists = len(set(self.columns).intersection(iset)) > 0 - # col_in_selection = if col_exists and "DATA" not in items: warnings.warn("Changing an existing SDFITS column") try: diff --git a/src/dysh/fits/tests/test_gbtfitsload.py b/src/dysh/fits/tests/test_gbtfitsload.py index 7726d6a7..f47d8bd7 100644 --- a/src/dysh/fits/tests/test_gbtfitsload.py +++ b/src/dysh/fits/tests/test_gbtfitsload.py @@ -253,6 +253,7 @@ def test_gettp(self): 8: {"SCAN": 6, "IFNUM": 2, "PLNUM": 0, "CAL": False, "SIG": True}, } for k, v in tests.items(): + print(f"{k}, {v}") if v["SIG"] == False: with pytest.raises(Exception): tps = sdf.gettp(scan=v["SCAN"], ifnum=v["IFNUM"], plnum=v["PLNUM"], cal=v["CAL"], sig=v["SIG"]) @@ -269,8 +270,8 @@ def test_gettp(self): else: # CAL=True cal = tps[0]._refcalon.astype(np.float64) - assert np.all(tp.flux.value == np.nanmean(cal, axis=0)) - + # diff = tp.flux.value - np.nanmean(cal, axis=0) + assert np.all(tp.flux.value - np.nanmean(cal, axis=0) == 0) # Check that selection is being applied properly. tp_scans = sdf.gettp(scan=[6, 7], plnum=0) # Weird that the results are different for a bunch of channels. @@ -433,6 +434,17 @@ def test_getps_smoothref(self): except KeyError: continue + def test_getps_flagging(self): + path = util.get_project_testdata() / "TGBT21A_501_11" + data_file = path / "TGBT21A_501_11.raw.vegas.fits" + sdf = gbtfitsload.GBTFITSLoad(data_file) + sdf.flag_channel([[10, 20], [30, 41]]) + sb = sdf.getps(scan=152, ifnum=0, plnum=0, apply_flags=True) + ta = sb.timeaverage() + # average_spectra masks out the NaN in channel 3072 + expected_mask = np.hstack([np.arange(10, 21), np.arange(30, 42), np.array([3072])]) + assert np.all(np.where(ta.mask) == expected_mask) + def test_write_single_file(self, tmp_path): "Test that writing an SDFITS file works when subselecting data" p = util.get_project_testdata() / "AGBT20B_014_03.raw.vegas" diff --git a/src/dysh/plot/specplot.py b/src/dysh/plot/specplot.py index 43bbb1f3..3cd0c0a1 100644 --- a/src/dysh/plot/specplot.py +++ b/src/dysh/plot/specplot.py @@ -7,6 +7,7 @@ import astropy.units as u import matplotlib.pyplot as plt import numpy as np +from astropy.utils.masked import Masked from ..coordinates import frame_to_label @@ -150,6 +151,7 @@ def plot(self, **kwargs): sf = s.flux if yunit is not None: sf = s.flux.to(yunit) + sf = Masked(sf, s.mask) self._axis.plot(sa, sf, color=this_plot_kwargs["color"], lw=lw) self._axis.set_xlim(this_plot_kwargs["xmin"], this_plot_kwargs["xmax"]) self._axis.set_ylim(this_plot_kwargs["ymin"], this_plot_kwargs["ymax"]) diff --git a/src/dysh/spectra/core.py b/src/dysh/spectra/core.py index a32668b0..bd6ed2d5 100644 --- a/src/dysh/spectra/core.py +++ b/src/dysh/spectra/core.py @@ -3,6 +3,7 @@ """ import warnings +from copy import deepcopy import astropy.units as u import numpy as np @@ -14,11 +15,12 @@ ) from astropy.modeling.fitting import LinearLSQFitter from astropy.modeling.polynomial import Chebyshev1D, Hermite1D, Legendre1D, Polynomial1D +from scipy import ndimage from specutils import SpectralRegion from specutils.fitting import fit_continuum from ..coordinates import veltofreq -from ..log import log_function_call +from ..log import log_function_call, logger from ..util import minimum_string_match, powerof2 @@ -678,5 +680,123 @@ def smooth(data, method="hanning", width=1, kernel=None, show=False): if show: return kernel # the boundary='extend' matches GBTIDL's /edge_truncate CONVOL() method - new_data = convolve(data, kernel, boundary="extend") + if hasattr(data, "mask"): + mask = data.mask + else: + mask = None + new_data = convolve(data, kernel, boundary="extend") # , nan_treatment="fill", fill_value=np.nan, mask=mask) return new_data + + +def data_ishift(y, ishift, axis=-1, remove_wrap=True, fill_value=np.nan): + """ + Shift `y` by `ishift` channels, where `ishift` is a natural number. + + Parameters + ---------- + y : array + Data to be shifted. + ishift : int + Amount to shift data by. + axis : int + Axis along which to apply the shift. + remove_wrap : bool + Replace channels that wrap around with `fill_value`. + fill_value : float + Value used to replace the data in channels that wrap around after the shift. + + Returns + ------- + new_y : array + Shifted `y`. + """ + + new_y = np.roll(y, ishift, axis=axis) + + if remove_wrap: + if ishift < 0: + new_y[ishift:] = fill_value + else: + new_y[:ishift] = fill_value + + return new_y + + +def data_fshift(y, fshift, method="fft", pad=False, window=True): + """ + Shift `y` by `fshift` channels, where |`fshift`|<1. + + Parameters + ---------- + y : array + Data to be shifted. + fshift : float + Amount to shift the data by. + abs(fshift) must be less than 1. + method : "fft" | "interpolate" + Method to use for shifting. + "fft" uses a phase shift. + "interpolate" uses `scipy.ndimage.shift`. + pad : bool + Pad the data during the phase shift. + Only used if `method="fft"`. + window : bool + Apply a Welch window during phase shift. + Only used if `method="fft"`. + """ + + if abs(fshift) > 1: + raise ValueError("abs(fshift) must be less than one: {fshift}") + + if method == "fft": + new_y = fft_shift(y, fshift, pad=pad, window=window) + elif method == "interpolate": + new_y = ndimage.shift(y, [fshift]) + + return new_y + + +def data_shift(y, s, axis=-1, remove_wrap=True, fill_value=np.nan, method="fft", pad=False, window=True): + """ + Shift `y` by `s` channels. + + Parameters + ---------- + y : array + Data to be shifted. + s : float + Amount to shift the data by. + axis : int + Axis along which to apply the shift. + remove_wrap : bool + Replace channels that wrap around with `fill_value`. + fill_value : float + Value used to replace the data in channels that wrap around after the shift. + method : "fft" | "interpolate" + Method to use for shifting. + "fft" uses a phase shift. + "interpolate" uses `scipy.ndimage.shift`. + pad : bool + Pad the data during the phase shift. + Only used if `method="fft"`. + window : bool + Apply a Welch window during phase shift. + Only used if `method="fft"`. + """ + + ishift = int(np.round(s)) # Integer shift. + fshift = s - ishift # Fractional shift. + + logger.debug(f"Shift: s={s} ishift={ishift} fshift={fshift}") + + if ishift != 0: + # Apply integer shift. + y_new = data_ishift(y, ishift, axis=axis, remove_wrap=remove_wrap, fill_value=fill_value) + else: + y_new = deepcopy(y) + + if fshift != 0: + # Apply fractional shift. + y_new = data_fshift(y_new, fshift, method=method, pad=pad, window=window) + + return y_new diff --git a/src/dysh/spectra/scan.py b/src/dysh/spectra/scan.py index 77ba6b36..7827bd23 100644 --- a/src/dysh/spectra/scan.py +++ b/src/dysh/spectra/scan.py @@ -11,27 +11,21 @@ from astropy import constants as ac from astropy.io.fits import BinTableHDU, Column from astropy.table import Table, vstack -from scipy import ndimage +from astropy.utils.masked import Masked from dysh.spectra import core from ..coordinates import Observatory from ..log import HistoricalBase, log_call_to_history, logger from ..util import uniq -from .core import ( +from .core import ( # fft_shift, average, - fft_shift, find_non_blanks, mean_tsys, sq_weighted_avg, tsys_weight, ) -from .spectrum import Spectrum - -# from typing import Literal - - -# from astropy.coordinates.spectral_coordinate import NoVelocityWarning +from .spectrum import Spectrum, average_spectra class SpectralAverageMixin: @@ -51,6 +45,9 @@ def timeaverage(self, weights=None): ------- spectrum : :class:`~spectra.spectrum.Spectrum` The time-averaged spectrum + + .. note:: + Data that are masked will have values set to zero. This is a feature of `numpy.ma.average`. Data mask fill value is NaN (np.nan) """ pass @@ -138,12 +135,6 @@ def _validate_defaults(self): if type(self._scan) != int: raise (f"{self.__class__.__name__}._scan is not an int: {type(self._scan)}") - # class ScanMixin: - # """This class describes the common interface to all Scan classes. - ## A Scan represents one IF, one feed, and one or more polarizations. - # Derived classes *must* implement :meth:`calibrate`. - # """ - @property def scan(self): """ @@ -414,7 +405,7 @@ def calibrate(self, **kwargs): scan.calibrate(**kwargs) @log_call_to_history - def timeaverage(self, weights="tsys", mode="old"): + def timeaverage(self, weights="tsys"): r"""Compute the time-averaged spectrum for all scans in this ScanBlock. Parameters @@ -425,60 +416,23 @@ def timeaverage(self, weights="tsys", mode="old"): :math:`w = t_{exp} \times \delta\nu/T_{sys}^2` Default: 'tsys' + Returns ------- timeaverage: list of `~spectra.spectrum.Spectrum` List of all the time-averaged spectra + + .. note:: + Data that are masked will have values set to zero. This is a feature of `numpy.ma.average`. Data mask fill value is NaN (np.nan) """ # warnings.simplefilter("ignore", NoVelocityWarning) - if mode == "old": - # average of the averages - self._timeaveraged = [] - for scan in self.data: - self._timeaveraged.append(scan.timeaverage(weights)) - if weights == "tsys": - # There may be multiple integrations, so need to - # average the Tsys weights - w = np.array([np.nanmean(k.tsys_weight) for k in self.data]) - if len(np.shape(w)) > 1: # remove empty axes - w = w.squeeze() - else: - w = weights - timeavg = np.array([k.data for k in self._timeaveraged]) - # Weight the average of the timeaverages by the weights. - avgdata = average(timeavg, axis=0, weights=w) - avgspec = np.mean(self._timeaveraged) - avgspec.meta = self._timeaveraged[0].meta - avgspec.meta["TSYS"] = np.average(a=[k.meta["TSYS"] for k in self._timeaveraged], axis=0, weights=w) - avgspec.meta["EXPOSURE"] = np.sum([k.meta["EXPOSURE"] for k in self._timeaveraged]) - # observer = self._timeaveraged[0].observer # nope this has to be a location ugh. see @todo in Spectrum constructor - # hardcode to GBT for now - s = Spectrum.make_spectrum( - avgdata * avgspec.flux.unit, meta=avgspec.meta, observer_location=Observatory["GBT"] - ) - s.merge_commentary(self) - elif mode == "new": - # average of the integrations - allcal = np.all([d._calibrate for d in self.data]) - if not allcal: - raise Exception("Data must be calibrated before time averaging.") - c = np.concatenate([d._calibrated for d in self.data]) - if weights == "tsys": - w = np.concatenate([d.tsys_weight for d in self.data]) - # if len(np.shape(w)) > 1: # remove empty axes - # w = w.squeeze() - else: - w = None - timeavg = average(c, weights=w) - avgspec = self.data[0].calibrated(0) - avgspec.meta["TSYS"] = np.nanmean([d.tsys for d in self.data]) - avgspec.meta["EXPOSURE"] = np.sum([d.exposure for d in self.data]) - s = Spectrum.make_spectrum( - timeavg * avgspec.flux.unit, meta=avgspec.meta, observer_location=Observatory["GBT"] - ) - s.merge_commentary(self) - else: - raise Exception(f"unrecognized mode {mode}") + # average of the averages + self._timeaveraged = [] + i = 0 + for scan in self.data: + self._timeaveraged.append(scan.timeaverage(weights)) + s = average_spectra(self._timeaveraged, weights=weights) + s.merge_commentary(self) return s @log_call_to_history @@ -636,6 +590,7 @@ class TPScan(ScanBase): whether or not to calibrate the data. If `True`, the data will be (calon - caloff)*0.5, otherwise it will be SDFITS row data. Default:True smoothref: int the number of channels in the reference to boxcar smooth prior to calibration + apply_flags : boolean, optional. If True, apply flags before calibration. Notes ----- @@ -671,6 +626,7 @@ def __init__( bintable, calibrate=True, smoothref=1, + apply_flags=False, observer_location=Observatory["GBT"], ): ScanBase.__init__(self, gbtfits) @@ -680,6 +636,7 @@ def __init__( self._calstate = calstate self._scanrows = scanrows self._smoothref = smoothref + self._apply_flags = apply_flags if self._smoothref > 1: warnings.warn(f"TP smoothref={self._smoothref} not implemented yet") @@ -708,8 +665,8 @@ def __init__( self._refonrows = sorted(list(set(self._calrows["ON"]).intersection(set(self._scanrows)))) # all cal=F states where sig=sigstate self._refoffrows = sorted(list(set(self._calrows["OFF"]).intersection(set(self._scanrows)))) - self._refcalon = gbtfits.rawspectra(self._bintable_index)[self._refonrows] - self._refcaloff = gbtfits.rawspectra(self._bintable_index)[self._refoffrows] + self._refcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refonrows] + self._refcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refoffrows] # now remove blanked integrations # seems like this should be done for all Scan classes! # PS: yes. @@ -927,6 +884,9 @@ def timeaverage(self, weights="tsys"): ------- spectrum : :class:`~spectra.spectrum.Spectrum` The time-averaged spectrum + + .. note:: + Data that are masked will have values set to zero. This is a feature of `numpy.ma.average`. Data mask fill value is NaN (np.nan) """ if self._npol > 1: raise Exception("Can't yet time average multiple polarizations") @@ -936,7 +896,8 @@ def timeaverage(self, weights="tsys"): else: w = np.ones_like(self.tsys_weight) non_blanks = find_non_blanks(self._data)[0] - self._timeaveraged._data = average(self._data, axis=0, weights=w) + self._timeaveraged._data = np.ma.average(self._data, axis=0, weights=w) + self._timeaveraged._data.set_fill_value(np.nan) self._timeaveraged.meta["MEANTSYS"] = np.mean(self._tsys[non_blanks]) self._timeaveraged.meta["WTTSYS"] = sq_weighted_avg(self._tsys[non_blanks], axis=0, weights=w[non_blanks]) self._timeaveraged.meta["TSYS"] = self._timeaveraged.meta["WTTSYS"] @@ -964,6 +925,7 @@ class PSScan(ScanBase): whether or not to calibrate the data. If true, data will be calibrated as TSYS*(ON-OFF)/OFF. Default: True smoothref: int the number of channels in the reference to boxcar smooth prior to calibration + apply_flags : boolean, optional. If True, apply flags before calibration. observer_location : `~astropy.coordinates.EarthLocation` Location of the observatory. See `~dysh.coordinates.Observatory`. This will be transformed to `~astropy.coordinates.ITRS` using the time of @@ -980,6 +942,7 @@ def __init__( bintable, calibrate=True, smoothref=1, + apply_flags=False, observer_location=Observatory["GBT"], ): ScanBase.__init__(self, gbtfits) @@ -990,13 +953,7 @@ def __init__( self._scanrows = scanrows self._nrows = len(self._scanrows["ON"]) self._smoothref = smoothref - # print(f"PJT len(scanrows ON) {len(self._scanrows['ON'])}") - # print(f"PJT len(scanrows OFF) {len(self._scanrows['OFF'])}") - # print("PJT scans", scans) - # print("PJT scanrows", scanrows) - # print("PJT calrows", calrows) - # print(f"len(scanrows ON) {len(self._scanrows['ON'])}") - # print(f"len(scanrows OFF) {len(self._scanrows['OFF'])}") + self._apply_flags = apply_flags # calrows perhaps not needed as input since we can get it from gbtfits object? # calrows['ON'] are rows with noise diode was on, regardless of sig or ref @@ -1022,9 +979,9 @@ def __init__( self._refoffrows = sorted(list(set(self._calrows["OFF"]).intersection(set(self._scanrows["OFF"])))) self._sigcalon = gbtfits.rawspectra(self._bintable_index)[self._sigonrows] self._nchan = len(self._sigcalon[0]) - self._sigcaloff = gbtfits.rawspectra(self._bintable_index)[self._sigoffrows] - self._refcalon = gbtfits.rawspectra(self._bintable_index)[self._refonrows] - self._refcaloff = gbtfits.rawspectra(self._bintable_index)[self._refoffrows] + self._sigcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._sigoffrows] + self._refcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refonrows] + self._refcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refoffrows] self._tsys = None self._exposure = None self._calibrated = None @@ -1060,8 +1017,11 @@ def calibrated(self, i): ------- spectrum : `~spectra.spectrum.Spectrum` """ + # @todo suppress astropy INFO message "overwriting Masked Quantity's current mask with specified mask." s = Spectrum.make_spectrum( - self._calibrated[i] * u.K, meta=self.meta[i], observer_location=self._observer_location + Masked(self._calibrated[i] * u.K, self._calibrated[i].mask), + meta=self.meta[i], + observer_location=self._observer_location, ) s.merge_commentary(self) return s @@ -1077,10 +1037,10 @@ def calibrate(self, **kwargs): self._status = 1 nspect = self.nrows // 2 - self._calibrated = np.empty((nspect, self._nchan), dtype="d") + self._calibrated = np.ma.empty((nspect, self._nchan), dtype="d") self._tsys = np.empty(nspect, dtype="d") self._exposure = np.empty(nspect, dtype="d") - tcal = list(self._sdfits.index(bintable=self._bintable_index).iloc[self._refonrows]["TCAL"]) + tcal = self._sdfits.index(bintable=self._bintable_index).iloc[self._refonrows]["TCAL"].to_numpy() # @todo this loop could be replaced with clever numpy if len(tcal) != nspect: raise Exception(f"TCAL length {len(tcal)} and number of spectra {nspect} don't match") @@ -1153,28 +1113,34 @@ def timeaverage(self, weights="tsys"): :math:`w = t_{exp} \times \delta\nu/T_{sys}^2` Default: 'tsys' + Returns ------- spectrum : :class:`~spectra.spectrum.Spectrum` The time-averaged spectrum + + .. note:: + Data that are masked will have values set to zero. This is a feature of `numpy.ma.average`. Data mask fill value is NaN (np.nan) """ if self._calibrated is None or len(self._calibrated) == 0: raise Exception("You can't time average before calibration.") if self._npol > 1: raise Exception("Can't yet time average multiple polarizations") - self._timeaveraged = deepcopy(self.calibrated(0)) + self._timeaveraged = deepcopy(self.calibrated(0)) # ._copy() data = self._calibrated if weights == "tsys": w = self.tsys_weight else: w = np.ones_like(self.tsys_weight) - self._timeaveraged._data = average(data, axis=0, weights=w) + self._timeaveraged._data = np.ma.average(data, axis=0, weights=w) + self._timeaveraged._data.set_fill_value(np.nan) non_blanks = find_non_blanks(data) self._timeaveraged.meta["MEANTSYS"] = np.mean(self._tsys[non_blanks]) self._timeaveraged.meta["WTTSYS"] = sq_weighted_avg(self._tsys[non_blanks], axis=0, weights=w[non_blanks]) self._timeaveraged.meta["EXPOSURE"] = np.sum(self._exposure[non_blanks]) self._timeaveraged.meta["TSYS"] = self._timeaveraged.meta["WTTSYS"] self._timeaveraged._history = self._history + self._timeaveraged._observer_location = self._observer_location return self._timeaveraged @@ -1203,6 +1169,7 @@ class NodScan(ScanBase): Default: True smoothref: int the number of channels in the reference to boxcar smooth prior to calibration (if applicable) + apply_flags : boolean, optional. If True, apply flags before calibration. observer_location : `~astropy.coordinates.EarthLocation` Location of the observatory. See `~dysh.coordinates.Observatory`. This will be transformed to `~astropy.coordinates.ITRS` using the time of @@ -1220,6 +1187,7 @@ def __init__( bintable, calibrate=True, smoothref=1, + apply_flags=False, observer_location=Observatory["GBT"], ): ScanBase.__init__(self, gbtfits) @@ -1227,6 +1195,7 @@ def __init__( self._scanrows = scanrows self._nrows = len(self._scanrows["ON"]) self._smoothref = smoothref + self._apply_flags = apply_flags self._beam1 = beam1 # @todo allow having no calrow where noise diode was not fired @@ -1254,15 +1223,15 @@ def __init__( self._refonrows = sorted(list(set(self._calrows["ON"]).intersection(set(self._scanrows["OFF"])))) self._refoffrows = sorted(list(set(self._calrows["OFF"]).intersection(set(self._scanrows["OFF"])))) if beam1: - self._sigcalon = gbtfits.rawspectra(self._bintable_index)[self._sigonrows] - self._sigcaloff = gbtfits.rawspectra(self._bintable_index)[self._sigoffrows] - self._refcalon = gbtfits.rawspectra(self._bintable_index)[self._refonrows] - self._refcaloff = gbtfits.rawspectra(self._bintable_index)[self._refoffrows] + self._sigcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._sigonrows] + self._sigcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._sigoffrows] + self._refcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refonrows] + self._refcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refoffrows] else: - self._sigcalon = gbtfits.rawspectra(self._bintable_index)[self._refonrows] - self._sigcaloff = gbtfits.rawspectra(self._bintable_index)[self._refoffrows] - self._refcalon = gbtfits.rawspectra(self._bintable_index)[self._sigonrows] - self._refcaloff = gbtfits.rawspectra(self._bintable_index)[self._sigoffrows] + self._sigcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refonrows] + self._sigcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refoffrows] + self._refcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._sigonrows] + self._refcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._sigoffrows] self._nchan = len(self._sigcalon[0]) self._tsys = None self._exposure = None @@ -1300,7 +1269,9 @@ def calibrated(self, i): spectrum : `~spectra.spectrum.Spectrum` """ s = Spectrum.make_spectrum( - self._calibrated[i] * u.K, meta=self.meta[i], observer_location=self._observer_location + Masked(self._calibrated[i] * u.K, self._calibrated[i].mask), + meta=self.meta[i], + observer_location=self._observer_location, ) s.merge_commentary(self) return s @@ -1316,10 +1287,10 @@ def calibrate(self, **kwargs): self._status = 1 nspect = self.nrows // 2 - self._calibrated = np.empty((nspect, self._nchan), dtype="d") + self._calibrated = np.ma.empty((nspect, self._nchan), dtype="d") self._tsys = np.empty(nspect, dtype="d") self._exposure = np.empty(nspect, dtype="d") - tcal = list(self._sdfits.index(bintable=self._bintable_index).iloc[self._refonrows]["TCAL"]) + tcal = self._sdfits.index(bintable=self._bintable_index).iloc[self._refonrows]["TCAL"].to_numpy() # @todo this loop could be replaced with clever numpy if len(tcal) != nspect: raise Exception(f"TCAL length {len(tcal)} and number of spectra {nspect} don't match") @@ -1396,6 +1367,9 @@ def timeaverage(self, weights="tsys"): ------- spectrum : :class:`~spectra.spectrum.Spectrum` The time-averaged spectrum + + .. note:: + Data that are masked will have values set to zero. This is a feature of `numpy.ma.average`. Data mask fill value is NaN (np.nan) """ if self._calibrated is None or len(self._calibrated) == 0: raise Exception("You can't time average before calibration.") @@ -1407,7 +1381,8 @@ def timeaverage(self, weights="tsys"): w = self.tsys_weight else: w = np.ones_like(self.tsys_weight) - self._timeaveraged._data = average(data, axis=0, weights=w) + self._timeaveraged._data = np.ma.average(data, axis=0, weights=w) + self._timeaveraged._data.set_fill_value(np.nan) non_blanks = find_non_blanks(data) self._timeaveraged.meta["MEANTSYS"] = np.mean(self._tsys[non_blanks]) self._timeaveraged.meta["WTTSYS"] = sq_weighted_avg(self._tsys[non_blanks], axis=0, weights=w[non_blanks]) @@ -1447,6 +1422,7 @@ class FSScan(ScanBase): Whether to use the sig as the sig, or the ref as the sig. Default: True smoothref: int The number of channels in the reference to boxcar smooth prior to calibration. + apply_flags : boolean, optional. If True, apply flags before calibration. observer_location : `~astropy.coordinates.EarthLocation` Location of the observatory. See `~dysh.coordinates.Observatory`. This will be transformed to `~astropy.coordinates.ITRS` using the time of @@ -1465,6 +1441,7 @@ def __init__( shift_method="fft", use_sig=True, smoothref=1, + apply_flags=False, observer_location=Observatory["GBT"], debug=False, ): @@ -1478,7 +1455,7 @@ def __init__( self._smoothref = smoothref if self._smoothref > 1: print(f"FS smoothref={self._smoothref} not implemented yet") - + self._apply_flags = apply_flags self._sigonrows = sorted(list(set(self._calrows["ON"]).intersection(set(self._sigrows["ON"])))) self._sigoffrows = sorted(list(set(self._calrows["OFF"]).intersection(set(self._sigrows["ON"])))) self._refonrows = sorted(list(set(self._calrows["ON"]).intersection(set(self._sigrows["OFF"])))) @@ -1487,19 +1464,19 @@ def __init__( self._debug = debug if self._debug: - print("---------------------------------------------------") - print("FSSCAN: ") - print("SigOff", self._sigoffrows) - print("SigOn", self._sigonrows) - print("RefOff", self._refoffrows) - print("RegOn", self._refonrows) + logger.debug("---------------------------------------------------") + logger.debug("FSSCAN: ") + logger.debug(f"SigOff {self._sigoffrows}") + logger.debug(f"SigOn {self._sigonrows}") + logger.debug(f"RefOff {self._refoffrows}") + logger.debug(f"RefOn {self._refonrows}") nsigrows = len(self._sigonrows) + len(self._sigoffrows) nrefrows = len(self._refonrows) + len(self._refoffrows) if nsigrows != nrefrows: raise Exception("Number of sig rows does not match ref rows. Dangerous to proceed") if self._debug: - print("sigonrows", nsigrows, self._sigonrows) + logger.dbeug(f"sigonrows {nsigrows}, {self._sigonrows}") self._nrows = nsigrows a_scanrow = self._sigonrows[0] @@ -1510,27 +1487,27 @@ def __init__( else: self._bintable_index = bintable if self._debug: - print(f"bintable index is {self._bintable_index}") + logger.debug(f"bintable index is {self._bintable_index}") self._observer_location = observer_location self._scanrows = list(set(self._calrows["ON"])) + list(set(self._calrows["OFF"])) df = self._sdfits._index.iloc[self._scanrows] if self._debug: - print("len(df) = ", len(df)) + logger.debug(f"{len(df) = }") self._set_if_fd(df) self._pols = uniq(df["PLNUM"]) if self._debug: - print(f"FSSCAN #pol = {self._pols}") + logger.debug(f"FSSCAN #pol = {self._pols}") self._npol = len(self._pols) if False: self._nint = gbtfits.nintegrations(self._bintable_index) # @todo use gbtfits.velocity_convention(veldef,velframe) # so quick with slicing! - self._sigcalon = gbtfits.rawspectra(self._bintable_index)[self._sigonrows] - self._sigcaloff = gbtfits.rawspectra(self._bintable_index)[self._sigoffrows] - self._refcalon = gbtfits.rawspectra(self._bintable_index)[self._refonrows] - self._refcaloff = gbtfits.rawspectra(self._bintable_index)[self._refoffrows] + self._sigcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._sigonrows] + self._sigcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._sigoffrows] + self._refcalon = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refonrows] + self._refcaloff = gbtfits.rawspectra(self._bintable_index, setmask=apply_flags)[self._refoffrows] self._nchan = len(self._sigcalon[0]) self._tsys = None self._exposure = None @@ -1540,7 +1517,7 @@ def __init__( if self._calibrate: self.calibrate(fold=fold, shift_method=shift_method) if self._debug: - print("---------------------------------------------------") + logger.debug("---------------------------------------------------") self._validate_defaults() @property @@ -1568,7 +1545,9 @@ def calibrated(self, i): spectrum : `~spectra.spectrum.Spectrum` """ s = Spectrum.make_spectrum( - self._calibrated[i] * u.K, meta=self.meta[i], observer_location=self._observer_location + Masked(self._calibrated[i] * u.K, self._calibrated[i].mask), + meta=self.meta[i], + observer_location=self._observer_location, ) s.merge_commentary(self) return s @@ -1579,8 +1558,8 @@ def calibrate(self, **kwargs): fold=True or fold=False is required """ if self._debug: - print(f'FOLD={kwargs["fold"]}') - print(f'METHOD={kwargs["shift_method"]}') + logger.debug(f'FOLD={kwargs["fold"]}') + logger.debug(f'METHOD={kwargs["shift_method"]}') # some helper functions, courtesy proto_getfs.py def channel_to_frequency(crval1, crpix1, cdelt1, vframe, nchan, nint, ndim=1): @@ -1659,69 +1638,40 @@ def do_fold(sig, ref, sig_freq, ref_freq, remove_wrap=False, shift_method="fft") """ """ chan_shift = (sig_freq[0] - ref_freq[0]) / np.abs(np.diff(sig_freq)).mean() logger.debug(f"do_fold: {sig_freq[0]}, {ref_freq[0]},{chan_shift}") - ref_shift = do_shift(ref, chan_shift, remove_wrap=remove_wrap, method=shift_method) + ref_shift = core.data_shift(ref, chan_shift, remove_wrap=remove_wrap, method=shift_method) # @todo weights avg = (sig + ref_shift) / 2 return avg - def do_shift(data, offset, remove_wrap=False, method="fft"): - """ - Shift the data of a numpy array using roll/shift - - @todo use the fancier GBTIDL fft based shift - """ - - ishift = int(np.round(offset)) # Integer shift. - fshift = offset - ishift # Fractional shift. - - logger.debug("FOLD: {ishift=} {fshift=}") - data2 = np.roll(data, ishift, axis=0) - if remove_wrap: - if ishift < 0: - data2[ishift:] = np.nan - else: - data2[:ishift] = np.nan - # Now the fractional shift, each row separate since ndimage.shift() cannot deal with np.nan - if method == "fft": - # Set `pad=False` to avoid edge effects. - # This needs to be sorted out. - data2 = fft_shift(data2, fshift, pad=False) - elif method == "interpolate": - data2 = ndimage.shift(data2, [fshift]) - return data2 - kwargs_opts = {"verbose": False} kwargs_opts.update(kwargs) _fold = kwargs.get("fold", False) _mode = 1 # 1: keep the sig else: keep the ref (not externally supported) nspect = self.nrows // 2 - self._calibrated = np.empty((nspect, self._nchan), dtype="d") + self._calibrated = np.ma.empty((nspect, self._nchan), dtype="d") self._tsys = np.empty(nspect, dtype="d") self._exposure = np.empty(nspect, dtype="d") # sig_freq = self._sigcalon[0] df_sig = self._sdfits.index(bintable=self._bintable_index).iloc[self._sigonrows] df_ref = self._sdfits.index(bintable=self._bintable_index).iloc[self._refonrows] - if self._debug: - print("df_sig", type(df_sig), len(df_sig)) + logger.debug(f"df_sig {type(df_sig)} len(df_sig)") sig_freq = index_frequency(df_sig) ref_freq = index_frequency(df_ref) chan_shift = abs(sig_freq[0, 0] - ref_freq[0, 0]) / np.abs(np.diff(sig_freq)).mean() - if self._debug: - print("FS: shift=%g nchan=%d" % (chan_shift, self._nchan)) + logger.debug(f"FS: shift={chan_shift:g} nchan={self._nchan:g}") # tcal is the same for REF and SIG, and the same for all integrations actually. - tcal = list(self._sdfits.index(bintable=self._bintable_index).iloc[self._sigonrows]["TCAL"]) - if self._debug: - print("TCAL:", len(tcal), tcal[0]) + tcal = self._sdfits.index(bintable=self._bintable_index).iloc[self._sigonrows]["TCAL"].to_numpy() + logger.debug(f"TCAL: {len(tcal)} {tcal[0]}") if len(tcal) != nspect: raise Exception(f"TCAL length {len(tcal)} and number of spectra {nspect} don't match") # @todo the nspect loop could be replaced with clever numpy? for i in range(nspect): tsys_sig = mean_tsys(calon=self._sigcalon[i], caloff=self._sigcaloff[i], tcal=tcal[i]) tsys_ref = mean_tsys(calon=self._refcalon[i], caloff=self._refcaloff[i], tcal=tcal[i]) - if i == 0 and self._debug: - print("Tsys(sig/ref)[0]=", tsys_sig, tsys_ref) + if i == 0: + logger.debug(f"Tsys(sig/ref)[0]={tsys_sig} / {tsys_ref}") tp_sig = 0.5 * (self._sigcalon[i] + self._sigcaloff[i]) tp_ref = 0.5 * (self._refcalon[i] + self._refcaloff[i]) # @@ -1749,7 +1699,7 @@ def do_shift(data, offset, remove_wrap=False, method="fft"): self._exposure[i] = self.exposure[i] self._add_calibration_meta() - logger.debug("Calibrated {nspect} spectra with fold={_fold} and use_sig={self._use_sig}") + logger.debug(f"Calibrated {nspect} spectra with fold={_fold} and use_sig={self._use_sig}") # tip o' the hat to Pedro S. for exposure and delta_freq @property @@ -1811,6 +1761,9 @@ def timeaverage(self, weights="tsys"): ------- spectrum : :class:`~spectra.spectrum.Spectrum` The time-averaged spectrum + + .. note:: + Data that are masked will have values set to zero. This is a feature of `numpy.ma.average`. Data mask fill value is NaN (np.nan) """ if self._calibrated is None or len(self._calibrated) == 0: raise Exception("You can't time average before calibration.") @@ -1822,7 +1775,8 @@ def timeaverage(self, weights="tsys"): w = self.tsys_weight else: w = np.ones_like(self.tsys_weight) - self._timeaveraged._data = average(data, axis=0, weights=w) + self._timeaveraged._data = np.ma.average(data, axis=0, weights=w) + self._timeaveraged._data.set_fill_value(np.nan) non_blanks = find_non_blanks(data) self._timeaveraged.meta["MEANTSYS"] = np.mean(self._tsys[non_blanks]) self._timeaveraged.meta["WTTSYS"] = sq_weighted_avg(self._tsys[non_blanks], axis=0, weights=w[non_blanks]) @@ -1843,6 +1797,7 @@ class SubBeamNodScan(ScanBase): Whether or not to calibrate the data. smoothref: int the number of channels in the reference to boxcar smooth prior to calibration + apply_flags : boolean, optional. If True, apply flags before calibration. observer_location : `~astropy.coordinates.EarthLocation` Location of the observatory. See `~dysh.coordinates.Observatory`. This will be transformed to `~astropy.coordinates.ITRS` using the time of @@ -1863,6 +1818,7 @@ def __init__( reftp, calibrate=True, smoothref=1, + apply_flags=False, observer_location=Observatory["GBT"], **kwargs, ): @@ -1891,6 +1847,7 @@ def __init__( self._smoothref = smoothref if self._smoothref > 1: print(f"SubBeamNodScan smoothref={self._smoothref} not implemented yet") + self._apply_flags = apply_flags self._observer_location = observer_location self._calibrated = None if calibrate: @@ -1903,7 +1860,7 @@ def calibrate(self, **kwargs): self._tsys = np.empty(nspect, dtype=float) self._exposure = np.empty(nspect, dtype=float) self._delta_freq = np.empty(nspect, dtype=float) - self._calibrated = np.empty((nspect, self._nchan), dtype=float) + self._calibrated = np.ma.empty((nspect, self._nchan), dtype=float) for i in range(nspect): sig = self._sigtp[i].timeaverage(weights=kwargs["weights"]) @@ -1929,7 +1886,11 @@ def calibrated(self, i): rfq = restfrq * u.Unit(meta["CUNIT1"]) restfreq = rfq.to("Hz").value meta["RESTFRQ"] = restfreq # WCS wants no E - s = Spectrum.make_spectrum(self._calibrated[i] * u.K, meta=meta, observer_location=self._observer_location) + s = Spectrum.make_spectrum( + Masked(self._calibrated[i] * u.K, self._calibrated[i].mask), + meta=meta, + observer_location=self._observer_location, + ) s.merge_commentary(self) return s @@ -1942,18 +1903,36 @@ def delta_freq(self): return self._delta_freq def timeaverage(self, weights="tsys"): + r"""Compute the time-averaged spectrum for this scan. + + Parameters + ---------- + weights: str + 'tsys' or None. If 'tsys' the weight will be calculated as: + + :math:`w = t_{exp} \times \delta\nu/T_{sys}^2` + + Default: 'tsys' + Returns + ------- + spectrum : :class:`~spectra.spectrum.Spectrum` + The time-averaged spectrum + + .. note:: + Data that are masked will have values set to zero. This is a feature of `numpy.ma.average`. Data mask fill value is NaN (np.nan) + """ if self._calibrated is None or len(self._calibrated) == 0: raise Exception("You can't time average before calibration.") if self._npol > 1: raise Exception(f"Can't yet time average multiple polarizations {self._npol}") self._timeaveraged = deepcopy(self.calibrated(0)) data = self._calibrated - nchan = len(data[0]) if weights == "tsys": w = self.tsys_weight else: w = None - self._timeaveraged._data = average(data, axis=0, weights=w) + self._timeaveraged._data = np.ma.average(data, axis=0, weights=w) + self._timeaveraged._data.set_fill_value(np.nan) self._timeaveraged.meta["MEANTSYS"] = np.mean(self._tsys) self._timeaveraged.meta["WTTSYS"] = sq_weighted_avg(self._tsys, axis=0, weights=w) self._timeaveraged.meta["TSYS"] = self._timeaveraged.meta["WTTSYS"] diff --git a/src/dysh/spectra/spectrum.py b/src/dysh/spectra/spectrum.py index 59755f8e..5dfe3249 100644 --- a/src/dysh/spectra/spectrum.py +++ b/src/dysh/spectra/spectrum.py @@ -17,6 +17,7 @@ # from astropy.nddata.ccddata import fits_ccddata_writer from astropy.table import Table from astropy.time import Time +from astropy.utils.masked import Masked from astropy.wcs import WCS, FITSFixedWarning from ndcube import NDCube from specutils import Spectrum1D @@ -34,7 +35,7 @@ sanitize_skycoord, veldef_to_convention, ) -from ..log import HistoricalBase, log_call_to_history +from ..log import HistoricalBase, log_call_to_history, logger from ..plot import specplot as sp from ..util import minimum_string_match from . import baseline, get_spectral_equivalency @@ -67,11 +68,9 @@ class Spectrum(Spectrum1D, HistoricalBase): @log_call_to_history def __init__(self, *args, **kwargs): - # print(f"ARGS={args}") HistoricalBase.__init__(self) self._target = kwargs.pop("target", None) if self._target is not None: - # print(f"self._target is {self._target}") self._target = sanitize_skycoord(self._target) self._velocity_frame = self._target.frame.name else: @@ -163,11 +162,9 @@ def _toggle_sections(self, nchan, s): s1 = [] e = 0 # set this to 1 if you want to be exact complementary if s[0][0] == 0: - # print("toggle_sections: edged") for i in range(ns - 1): s1.append((s[i][1] + e, s[i + 1][0] - e)) else: - # print("toggle_sections: internal") s1.append((0, s[0][0])) for i in range(ns - 1): s1.append((s[i][1], s[i + 1][0])) @@ -386,7 +383,7 @@ def stats(self, roll=0, qac=False): def decimate(self, n): """ - Decimate a `Spectrum` by n pixels. + Decimate the `Spectrum` by n pixels. Parameters ---------- @@ -395,8 +392,8 @@ def decimate(self, n): Returns ------- - s : Spectrum - The decimated Spectrum. + s : `Spectrum` + The decimated `Spectrum`. """ if not float(n).is_integer(): @@ -422,7 +419,7 @@ def decimate(self, n): @log_call_to_history def smooth(self, method="hanning", width=1, decimate=0, kernel=None): """ - Smooth or Convolve a spectrum, optionally decimating it. + Smooth or Convolve the `Spectrum`, optionally decimating it. Default smoothing is hanning. @@ -467,8 +464,8 @@ def smooth(self, method="hanning", width=1, decimate=0, kernel=None): Returns ------- - s : Spectrum - The new, possibly decimated, convolved spectrum. + s : `Spectrum` + The new, possibly decimated, convolved `Spectrum`. """ nchan = len(self._data) # decimate = int(decimate) # Should we change this value and tell the user, or just error out? @@ -489,7 +486,7 @@ def smooth(self, method="hanning", width=1, decimate=0, kernel=None): # All checks for smoothing should be completed by this point. # Create a new metadata dictionary to modify by smooth. new_meta = deepcopy(self.meta) - + md = np.ma.masked_array(self._data, self.mask) if this_method == "gaussian": if width <= self._resolution: raise ValueError( @@ -497,11 +494,17 @@ def smooth(self, method="hanning", width=1, decimate=0, kernel=None): ) kwidth = np.sqrt(width**2 - self._resolution**2) # Kernel effective width. stddev = kwidth / 2.35482 - s1 = core.smooth(self._data, this_method, stddev) + + s1 = core.smooth(md, this_method, stddev) else: kwidth = width - s1 = core.smooth(self._data, this_method, width) - + s1 = core.smooth(md, this_method, width) + # mask = np.full(s1.shape, False) + # in core.smooth, we fill masked values with np.nan. + # astropy.convolve does not return a new mask, so we recreate + # a decimated mask where values are nan + # mask[np.where(s1 == np.nan)] = True + # new_data = Masked(s1 * self.flux.unit, mask) new_data = s1 * self.flux.unit new_meta["FREQRES"] = np.sqrt((kwidth * self.meta["CDELT1"]) ** 2 + self.meta["FREQRES"] ** 2) @@ -524,6 +527,120 @@ def smooth(self, method="hanning", width=1, decimate=0, kernel=None): return s + def shift(self, s, remove_wrap=True, fill_value=np.nan, method="fft"): + """ + Shift the `Spectrum` by `s` channels in place. + + Parameters + ---------- + s : float + Number of channels to shift the `Spectrum` by. + remove_wrap : bool + If `False` keep channels that wrap around the edges. + If `True` fill channels that wrap with `fill_value`. + fill_value : float + If `remove_wrap=True` fill channels that wrapped with this value. + method : "fft" + Method used to perform the fractional channel shift. + "fft" uses a phase shift. + """ + + new_spec = self._copy() + new_data = core.data_shift(new_spec.data, s, remove_wrap=remove_wrap, fill_value=fill_value, method=method) + + # Update data values. + new_spec._data = new_data + + # Update metadata. + new_spec.meta["CRPIX1"] += s + + # Update WCS. + new_spec.wcs.wcs.crpix[0] += s + + # Update `SpectralAxis` values. + # Radial velocity needs to be copied by hand. + radial_velocity = deepcopy(new_spec._spectral_axis._radial_velocity) + new_spectral_axis_values = new_spec.wcs.spectral.pixel_to_world(np.arange(new_spec.flux.shape[-1])) + new_spec._spectral_axis = new_spec.spectral_axis.replicate(value=new_spectral_axis_values) + new_spec._spectral_axis._radial_velocity = radial_velocity + + return new_spec + + def find_shift(self, other, units=None, frame=None): + """ + Find the shift required to align this `Spectrum` with `other`. + + Parameters + ---------- + other : `Spectrum` + Target `Spectrum` to align to. + units : {None, `astropy.units.Quantity`} + Find the shift to align the two `Spectra` in these units. + If `None`, the `Spectra` will be aligned using the units of + `other`. + frame : {None, str} + Find the shift in this reference frame. + If `None` will use the frame of `other`. + + Returns + ------- + shift : float + Number of channels that this `Spectrum` must be shifted to + be aligned with `other`. + """ + + if not isinstance(other, Spectrum): + raise ValueError("`other` must be a `Spectrum`.") + + if frame is not None and frame not in astropy_frame_dict.keys(): + raise ValueError( + f"`frame` ({frame}) not recognized. Frame must be one of {', '.join(list(astropy_frame_dict.keys()))}" + ) + else: + frame = other._velocity_frame + + sa = self.spectral_axis.with_observer_stationary_relative_to(frame) + tgt_sa = other.spectral_axis.with_observer_stationary_relative_to(frame) + + if units is None: + units = tgt_sa.unit + + sa = sa.to(units) + tgt_sa = tgt_sa.to(units) + + cdelt1 = sa[1] - sa[0] + shift = ((sa[0] - tgt_sa[0]) / cdelt1).value + + return shift + + def align_to(self, other, units=None, frame=None, remove_wrap=True, fill_value=np.nan, method="fft"): + """ + Align the `Spectrum` with respect to `other`. + + Parameters + ---------- + other : `Spectrum` + Target `Spectrum` to align to. + units : {None, `astropy.units.Quantity`} + Find the shift to align the two `Spectra` in these units. + If `None`, the `Spectra` will be aligned using the units of + `other`. + frame : {None, str} + Find the shift in this reference frame. + If `None` will use the frame of `other`. + remove_wrap : bool + If `True` allow spectrum to wrap around the edges. + If `False` fill channels that wrap with `fill_value`. + fill_value : float + If `wrap=False` fill channels that wrapped with this value. + method : "fft" + Method used to perform the fractional channel shift. + "fft" uses a phase shift. + """ + + s = self.find_shift(other, units=units, frame=frame) + return self.shift(s, remove_wrap=remove_wrap, fill_value=fill_value, method=method) + @property def equivalencies(self): """Get the spectral axis equivalencies that can be used in converting the axis @@ -630,7 +747,6 @@ def set_frame(self, toframe): actualframe = self.observer else: actualframe = astropy_frame_dict.get(toframe, toframe) - # print(f"actual frame is {actualframe} {type(actualframe)}") self._spectral_axis = self._spectral_axis.with_observer_stationary_relative_to(actualframe) self._meta["CTYPE1"] = change_ctype(self._meta["CTYPE1"], toframe) if isinstance(actualframe, str): @@ -808,7 +924,7 @@ def _copy(self, **kwargs): return s @classmethod - def fake_spectrum(cls, nchan=1024, **kwargs): + def fake_spectrum(cls, nchan=1024, seed=None, **kwargs): """ Create a fake spectrum, useful for simple testing. A default header is created, which may be modified with kwargs. @@ -818,6 +934,14 @@ def fake_spectrum(cls, nchan=1024, **kwargs): nchan : int, optional Number of channels. The default is 1024. + seed : {None, int, array_like[ints], `numpy.random.SeedSequence`, `numpy.random.BitGenerator`, `numpy.random.Generator`}, optional + A seed to initialize the `BitGenerator`. If None, then fresh, unpredictable entropy will be pulled from the OS. + If an int or array_like[ints] is passed, then all values must be non-negative and will be passed to + `SeedSequence` to derive the initial `BitGenerator` state. One may also pass in a `SeedSequence` instance. + Additionally, when passed a `BitGenerator`, it will be wrapped by `Generator`. If passed a `Generator`, it will + be returned unaltered. + The default is `None`. + **kwargs: dict or key=value Metadata to put in the header. If the key exists already in the default header, it will be replaced. Otherwise the key and value will be @@ -828,7 +952,9 @@ def fake_spectrum(cls, nchan=1024, **kwargs): spectrum : `~dysh.spectra.Spectrum` The spectrum object """ - data = np.random.rand(nchan) * u.K + + rng = np.random.default_rng(seed) + data = rng.random(nchan) * u.K meta = { "OBJECT": "NGC2415", "BANDWID": 23437500.0, @@ -932,7 +1058,8 @@ def fake_spectrum(cls, nchan=1024, **kwargs): @classmethod def make_spectrum(cls, data, meta, use_wcs=True, observer_location=None): # , shift_topo=False): - """Factory method to create a Spectrum object from a data and header. + """Factory method to create a Spectrum object from a data and header. The the data are masked, + the Spectrum mask will be set to the data mask. Parameters ---------- @@ -998,7 +1125,6 @@ def make_spectrum(cls, data, meta, use_wcs=True, observer_location=None): savecomment = meta.pop("COMMENT", None) if savecomment is None: savecomment = meta.pop("comments", None) - # print(f"{meta=}") wcs = WCS(header=meta) if savehist is not None: meta["HISTORY"] = savehist @@ -1045,18 +1171,29 @@ def make_spectrum(cls, data, meta, use_wcs=True, observer_location=None): ) obsitrs = None - s = cls( - flux=data, - wcs=wcs, - meta=meta, - velocity_convention=vc, - radial_velocity=target.radial_velocity, - rest_value=meta["RESTFRQ"] * u.Hz, - observer=obsitrs, - target=target, - ) - # s._history = [] - # s._comments = [] + if np.ma.is_masked(data): + s = cls( + flux=data, + wcs=wcs, + meta=meta, + velocity_convention=vc, + radial_velocity=target.radial_velocity, + rest_value=meta["RESTFRQ"] * u.Hz, + observer=obsitrs, + target=target, + mask=data.mask, + ) + else: + s = cls( + flux=data, + wcs=wcs, + meta=meta, + velocity_convention=vc, + radial_velocity=target.radial_velocity, + rest_value=meta["RESTFRQ"] * u.Hz, + observer=obsitrs, + target=target, + ) # For some reason, Spectrum1D.spectral_axis created with WCS do not inherit # the radial velocity. In fact, they get no radial_velocity attribute at all! # This method creates a new spectral_axis with the given radial velocity. @@ -1082,18 +1219,6 @@ def _copy_attributes(self, other): for k, v in vars(self).items(): if k not in IGNORE_ON_COPY: vars(other)[k] = deepcopy(v) - # other.add_history(self._history) - # other.add_comment(self._comments) - - # other._target = self._target - # other._observer = self._observer - # other._velocity_frame = self._velocity_frame - # other._obstime = self._obstime - # other._baseline_model = self._baseline_model - # other._exclude_regions = self._exclude_regions - # other._mask = self._mask - # other._subtracted = self._subtracted - # other._spectral_axis = self.spectral_axis def __add__(self, other): op = self.add @@ -1149,7 +1274,6 @@ def __truediv__(self, other): return result def _add_meta(self, operand, operand2, **kwargs): - # print(kwargs) kwargs.setdefault("other_meta", True) meta = deepcopy(operand) if kwargs["other_meta"]: @@ -1244,7 +1368,9 @@ def wav2idx(wav, wcs, spectral_axis, coo, sto): # New Spectrum. return self.make_spectrum( - self.flux[start_idx:stop_idx], meta=meta, observer_location=Observatory[meta["TELESCOP"]] + Masked(self.flux[start_idx:stop_idx], self.mask[start_idx:stop_idx]), + meta=meta, + observer_location=Observatory[meta["TELESCOP"]], ) @@ -1400,3 +1526,81 @@ def spectrum_reader_gbtidl(fileobj, **kwargs): # registry.register_writer("ipac", Spectrum, ascii_spectrum_reader_ipac) # registry.register_writer("votable", Spectrum, spectrum_reader_votable) # registry.register_writer("mrt", Spectrum, spectrum_reader_mrt) + + +def average_spectra(spectra, weights="tsys", align=False): + r""" + Average `spectra`. The resulting `average` will have an exposure equal to the sum of the exposures, + and coordinates and system temperature equal to the weighted average of the coordinates and system temperatures. + + Parameters + ---------- + spectra : list of `Spectrum` + Spectra to be averaged. They must have the same number of channels. + No checks are done to ensure they are aligned. + weights: str + 'tsys' or None. If 'tsys' the weight will be calculated as: + + :math:`w = t_{exp} \times \delta\nu/T_{sys}^2` + + Default: 'tsys' + align : bool + If `True` align the `spectra` to the first element. + This uses `Spectrum.align_to`. + + Returns + ------- + average : `Spectrum` + Averaged spectra. + """ + + nspec = len(spectra) + nchan = len(spectra[0].data) + shape = (nspec, nchan) + data_array = np.ma.empty(shape, dtype=float) + wts = np.empty(shape, dtype=float) + exposures = np.empty(nspec, dtype=float) + tsyss = np.empty(nspec, dtype=float) + xcoos = np.empty(nspec, dtype=float) + ycoos = np.empty(nspec, dtype=float) + obs_location = spectra[0]._observer_location + units = spectra[0].flux.unit + + for i, s in enumerate(spectra): + if not isinstance(s, Spectrum): + raise ValueError(f"Element {i} of `spectra` is not a `Spectrum`. {type(s)}") + if units != s.flux.unit: + raise ValueError( + f"Element {i} of `spectra` has units {s.flux.unit}, but the first element has units {units}." + ) + if align: + if i > 0: + s = s.align_to(spectra[0]) + data_array[i] = s.data + data_array[i].mask = s.mask + + if weights == "tsys": + wts[i] = core.tsys_weight(s.meta["EXPOSURE"], s.meta["CDELT1"], s.meta["TSYS"]) + else: + wts[i] = 1.0 + exposures[i] = s.meta["EXPOSURE"] + tsyss[i] = s.meta["TSYS"] + xcoos[i] = s.meta["CRVAL2"] + ycoos[i] = s.meta["CRVAL3"] + + data_array = np.ma.MaskedArray(data_array, mask=np.isnan(data_array) | data_array.mask, fill_value=np.nan) + data = np.ma.average(data_array, axis=0, weights=wts) + tsys = np.ma.average(tsyss, axis=0, weights=wts[:, 0]) + xcoo = np.ma.average(xcoos, axis=0, weights=wts[:, 0]) + ycoo = np.ma.average(ycoos, axis=0, weights=wts[:, 0]) + exposure = exposures.sum(axis=0) + + new_meta = deepcopy(spectra[0].meta) + new_meta["TSYS"] = tsys + new_meta["EXPOSURE"] = exposure + new_meta["CRVAL2"] = xcoo + new_meta["CRVAL3"] = ycoo + + averaged = Spectrum.make_spectrum(Masked(data * units, data.mask), meta=new_meta, observer_location=obs_location) + + return averaged diff --git a/src/dysh/spectra/tests/test_scan.py b/src/dysh/spectra/tests/test_scan.py index 8afa0433..d5ea4972 100644 --- a/src/dysh/spectra/tests/test_scan.py +++ b/src/dysh/spectra/tests/test_scan.py @@ -61,10 +61,12 @@ def test_compare_with_GBTIDL_2(self, data_dir): data_path = f"{data_dir}/TGBT21A_501_11/NGC2782" sdf_file = f"{data_path}/TGBT21A_501_11_NGC2782.raw.vegas.A.fits" + print(f"{sdf_file=}") gbtidl_file = f"{data_path}/TGBT21A_501_11_getps_scans_156-158_ifnum_0_plnum_0_timeaverage.fits" sdf = gbtfitsload.GBTFITSLoad(sdf_file) ps_scans = sdf.getps(scan=[156, 158], ifnum=0, plnum=0) + print(np.shape(ps_scans[0]._calibrated), np.shape(ps_scans[1]._calibrated)) ta = ps_scans.timeaverage() hdu = fits.open(gbtidl_file) diff --git a/src/dysh/spectra/tests/test_spectrum.py b/src/dysh/spectra/tests/test_spectrum.py index 40695b11..b1081b36 100644 --- a/src/dysh/spectra/tests/test_spectrum.py +++ b/src/dysh/spectra/tests/test_spectrum.py @@ -3,9 +3,10 @@ import astropy.units as u import numpy as np import pytest +from astropy.io import fits from dysh.fits.gbtfitsload import GBTFITSLoad -from dysh.spectra.spectrum import IGNORE_ON_COPY, Spectrum +from dysh.spectra.spectrum import IGNORE_ON_COPY, Spectrum, average_spectra from dysh.util import get_project_testdata @@ -25,14 +26,16 @@ def fit_gauss(spectrum): return g_fit -def compare_spectrum(one, other): +def compare_spectrum(one, other, ignore_history=False, ignore_comments=False): """ """ for k, v in vars(one).items(): if k in IGNORE_ON_COPY: continue - # elif k in ["_data", "_mask", "_weights"]: - # assert np.all(v == vars(other)[k]) + if ignore_history and k == "_history": + continue + if ignore_history and k == "_comments": + continue elif k in ["_wcs"]: v.to_header() == vars(other)[k].to_header() elif k in ["_spectral_axis"]: @@ -47,10 +50,10 @@ def setup_method(self): data_dir = get_project_testdata() / "AGBT05B_047_01" sdf_file = data_dir / "AGBT05B_047_01.raw.acs" sdf = GBTFITSLoad(sdf_file) - getps0 = sdf.getps(scan=51, plnum=0) - self.ps0 = getps0.timeaverage() - getps1 = sdf.getps(scan=51, plnum=1) - self.ps1 = getps1.timeaverage() + self.getps0 = sdf.getps(scan=51, plnum=0) + self.ps0 = self.getps0.timeaverage() + self.getps1 = sdf.getps(scan=51, plnum=1) + self.ps1 = self.getps1.timeaverage() self.ss = self.ps0._copy() # Synthetic one. x = np.arange(0, len(self.ss.data)) fwhm = 5 @@ -60,6 +63,7 @@ def setup_method(self): self.ss.meta["FREQRES"] = abs(self.ss.meta["CDELT1"]) self.ss.meta["FWHM"] = fwhm self.ss.meta["CENTER"] = self.ss.spectral_axis[mean].value + self.ss.meta["STDD"] = stdd def test_add(self): """Test that we can add two `Spectrum`.""" @@ -250,7 +254,6 @@ def test_slice(self, mock_show, tmp_path): meta_ignore = ["CRPIX1", "CRVAL1"] spec_pars = ["_target", "_velocity_frame", "_observer", "_obstime", "_observer_location"] s = slice(1000, 1100, 1) - trimmed = self.ps0[s] assert trimmed.flux[0] == self.ps0.flux[s.start] assert trimmed.flux[-1] == self.ps0.flux[s.stop - 1] @@ -391,3 +394,125 @@ def test_smooth_and_slice(self): assert np.sqrt(fwhm**2 - sss.meta["FREQRES"] ** 2) == pytest.approx( abs(self.ss.meta["CDELT1"]) * self.ss.meta["FWHM"], abs=abs(self.ss.meta["CDELT1"]) / 9.0 ) + + def test_shift(self): + """Test the shift method against the results produced by GBTIDL""" + + # Prepare test data. + filename = get_project_testdata() / "TGBT21A_501_11/TGBT21A_501_11_ifnum_0_int_0-2_getps_152_plnum_0.fits" + sdf = GBTFITSLoad(filename) + nchan = sdf["DATA"].shape[-1] + spec = Spectrum.fake_spectrum(nchan=nchan, seed=1) + spec.data[nchan // 2 - 5 : nchan // 2 + 6] = 10 + org_spec = spec._copy() + # The next two lines were used to create the input for GBTIDL. + # sdf["DATA"] = [spec.data] + # sdf.write("shift_testdata.fits") + + # Apply method to be tested. + shift = 5.5 + spec = spec.shift(shift) + + # Internal tests. + assert np.all(np.isnan(spec[: int(np.round(shift))].data)) + + # Load GBTIDL answer. + with fits.open(get_project_testdata() / "gshift_box.fits") as hdu: + table = hdu[1].data + gbtidl = table["DATA"][0] + + # Compare. + # Ignore the edge channels to avoid edge effects. + diff = (spec.data - gbtidl)[10:-10] + assert np.all(abs(diff) < 5e-4) + + assert spec.meta["CRPIX1"] == org_spec.meta["CRPIX1"] + shift + assert spec.spectral_axis[0].to("Hz").value == ( + org_spec.spectral_axis[0].to("Hz").value - spec.meta["CDELT1"] * shift + ) + + def test_find_shift(self): + """ + Test the find_shift method. + * Test that the shift with respect to itself is zero. + * Test that it can find an integer shift. + * Test that it can find a fractional shift. + * Test that it can find a shift in velocity units. + * Test that it can find a shift in a different frame. + """ + spec = Spectrum.fake_spectrum(seed=1) + + # Shift should be zero. + assert spec.find_shift(spec) == pytest.approx(0) + + chan_wid = np.mean(np.diff(spec._spectral_axis)) + + # Shift by one channel. + spec2 = spec._copy() + spec2._spectral_axis = spec2.spectral_axis.replicate(value=spec2.spectral_axis + chan_wid) + assert spec.find_shift(spec2) == pytest.approx(-1) + + # Shift by one and a half channels. + spec3 = spec._copy() + spec3._spectral_axis = spec3.spectral_axis.replicate(value=spec3.spectral_axis + chan_wid * 1.5) + assert spec.find_shift(spec3) == pytest.approx(-1.5) + + # Shift in velocity. + spec4 = spec._copy() + velo = spec4.spectral_axis.replicate(value=spec4.spectral_axis.to("km/s")) + dvel = velo[1] - velo[0] + spec4._spectral_axis = spec4.spectral_axis.replicate(value=velo + dvel * 0.5) + assert spec.find_shift(spec4) == pytest.approx(-0.5) + + # Shift in a different frame. + assert spec.find_shift(spec4, frame="lsrk") == pytest.approx(-0.5) + + def test_align_to(self): + """ + Tests for align_to method. + * Test that align_to itself does not change the spectrum. + * Test that aligning to a spectrum with a integer shift preserves the data. + * Test that aligning to a spectrum with a fractional shift preserves signal amplitude within errorbars. + """ + + spec = Spectrum.fake_spectrum(nchan=1024, seed=1) + org_spec = spec._copy() + + # Align to itself. + spec = spec.align_to(spec) + compare_spectrum(spec, org_spec, ignore_history=True) + assert np.all((spec - org_spec).data == 0) + + # Align to a shifted version. + shift = 5 + spec = spec.shift(shift) + assert np.all((spec.data[shift:] - org_spec.data[:-shift]) == 0.0) + + # Align to a shifted version with signal. + fshift = 0.5 + spec = self.ss._copy() + org_spec = spec._copy() + spec = spec.shift(shift + fshift) + # The amplitude of the signal will decrease because of the sampling. + tol = np.sqrt( + (1 - np.exp(-0.5 * (fshift) ** 2 / spec.meta["STDD"] ** 2)) ** 2.0 + + (np.nanstd(spec.data[: len(spec.data) - 50])) ** 2.0 + ) + assert spec.max().value == pytest.approx(org_spec.max().value, abs=3 * tol) + + def test_average_spectra(self): + """ + Tests for average_spectra. + Although not a class method of `Spectra` it is included here to reuse the setup method of the test. + * Test that it does not crash. + * Test that it does not crash whit alignment. + """ + + ps0_org = self.ps0._copy() + ps1_org = self.ps1._copy() + + avg = average_spectra((self.ps0, self.ps1)) + + avg = average_spectra((self.ps0, self.ps1), align=True) + compare_spectrum(ps0_org, self.ps0, ignore_history=True, ignore_comments=True) + compare_spectrum(ps1_org, self.ps1, ignore_history=True, ignore_comments=True) diff --git a/src/dysh/util/core.py b/src/dysh/util/core.py index 25b9825c..9413e98f 100644 --- a/src/dysh/util/core.py +++ b/src/dysh/util/core.py @@ -14,6 +14,8 @@ # import pandas as pd from astropy.time import Time +ALL_CHANNELS = "all channels" + def select_from(key, value, df): """ @@ -325,3 +327,51 @@ def ensure_ascii(text: Union[str, list[str]], check: bool = False) -> Union[str, for c in text: clean_text.append(_ensure_ascii_str(c)) return clean_text + + +def convert_array_to_mask(a, length, value=True): + """ + This method interprets a simple or compound array and returns a numpy mask + of length `length`. Single arrays/tuples will be treated as element index lists; + nested arrays will be treated as *inclusive* ranges, for instance: + + `` + # mask elements 1 and 10 + convert_array_to_mask([1,10]) + # mask elements 1 thru 10 inclusive + convert_array_to_mask([[1,10]]) + # mask ranges 1 thru 10 and 47 thru 56 inclusive, and element 75 + convert_array_to_mask([[1,10], [47,56], 75)]) + # tuples also work, though can be harder for a human to read + convert_array_to_mask(((1,10), [47,56], 75)) + `` + + Parameters + ---------- + a : number or array-like + The + length : int + The length of the mask to return, e.g. the number of channels in a spectrum. + + value : bool + The value to fill the mask with. True to mask data, False to unmask. + + Returns + ------- + mask : ~np.ndarray + A numpy array where the mask is True according to the rules above. + + """ + + if a == ALL_CHANNELS: + return np.full(length, value) + + mask = np.full(length, False) + + for v in a: + if isinstance(v, (tuple, list, np.ndarray)) and len(v) == 2: + # If there are just two numbers, interpret is as an inclusive range + mask[v[0] : v[1] + 1] = value + else: + mask[v] = value + return mask diff --git a/src/dysh/util/selection.py b/src/dysh/util/selection.py index f4de01d0..a7829c0b 100644 --- a/src/dysh/util/selection.py +++ b/src/dysh/util/selection.py @@ -15,7 +15,7 @@ from ..log import logger # from ..fits import default_sdfits_columns -from . import gbt_timestamp_to_time, generate_tag, keycase +from . import ALL_CHANNELS, gbt_timestamp_to_time, generate_tag, keycase default_aliases = { "freq": "crval1", @@ -631,14 +631,16 @@ def _base_select_within(self, tag=None, **kwargs): kw[k] = (v1, v2) self._base_select_range(tag, **kw) - def _base_select_channel(self, chan, tag=None): + def _base_select_channel(self, channel, tag=None): """ Select channels and/or channel ranges. These are NOT used in :meth:`final` but rather will be used to create a mask for calibration or flagging. Single arrays/tuples will be treated as channel lists; - nested arrays will be treated as ranges, for instance + nested arrays will be treated as *inclusive* ranges. For instance: `` + # select channel 24 + select_channel(24) # selects channels 1 and 10 select_channel([1,10]) # selects channels 1 thru 10 inclusive @@ -649,9 +651,11 @@ def _base_select_channel(self, chan, tag=None): select_channel(((1,10), [47,56], 75)) `` + *Note* : channel numbers start at zero. + Parameters ---------- - chan : number, or array-like + channel : number, or array-like The channels to select Returns @@ -667,9 +671,11 @@ def _base_select_channel(self, chan, tag=None): raise Exception( "You can only have one channel selection rule. Remove the old rule before creating a new one." ) - self._check_numbers(chan=chan) - self._channel_selection = chan - self._addrow({"CHAN": str(chan)}, dataframe=self, tag=tag) + self._check_numbers(chan=channel) + if isinstance(channel, numbers.Number): + channel = [int(channel)] + self._channel_selection = channel + self._addrow({"CHAN": str(channel)}, dataframe=self, tag=tag) # NB: using ** in doc here because `id` will make a reference to the # python built-in function. Arguably we should pick a different @@ -829,6 +835,21 @@ def __deepcopy__(self, memo): warnings.resetwarnings() return result + def get(self, key): + """Get the selection/flag rule by its ID + + Parameters + ---------- + key : int + The ID value. See :meth:`show`. + + Returns + ------- + ~pandas.DataFrame + The selection/flag rule + """ + return self._selection_rules[key] + class Selection(SelectionBase): """This class contains the methods for creating rules to select data from an SDFITS object. @@ -932,9 +953,11 @@ def select_channel(self, chan, tag=None): Select channels and/or channel ranges. These are NOT used in :meth:`final` but rather will be used to create a mask for calibration or flagging. Single arrays/tuples will be treated as channel lists; - nested arrays will be treated as ranges, for instance + nested arrays will be treated as *inclusive* ranges. For instance: `` + # select channel 24 + select_channel(24) # selects channels 1 and 10 select_channel([1,10]) # selects channels 1 thru 10 inclusive @@ -945,6 +968,8 @@ def select_channel(self, chan, tag=None): select_channel(((1,10), [47,56], 75)) `` + *Note* : channel numbers start at zero. + Parameters ---------- chan : number, or array-like @@ -992,7 +1017,9 @@ def flag(self, tag=None, **kwargs): """Add one or more exact flag rules, e.g., `key1 = value1, key2 = value2, ...` If `value` is array-like then a match to any of the array members will be flagged. For instance `flag(object=['3C273', 'NGC1234'])` will select data for either of those - objects and `flag(ifnum=[0,2])` will flag IF number 0 or IF number 2. + objects and `flag(ifnum=[0,2])` will flag IF number 0 or IF number 2. Channels for selected data + can be flagged using keyword `channel`, e.g., `flag(object='MBM12',channel=[0,23])` + will flag channels 0 through 23 *inclusive* for object MBM12. Parameters ---------- @@ -1005,23 +1032,29 @@ def flag(self, tag=None, **kwargs): The value to select """ - chan = kwargs.pop("chan", None) + chan = kwargs.pop("channel", None) if chan is not None: + if isinstance(chan, numbers.Number): + chan = [int(chan)] self._check_numbers(chan=chan) self._base_select(tag, **kwargs) # don't do this unless chan input is good. + idx = len(self._table) - 1 if chan is not None: - idx = len(self._table) - 1 self._table[idx]["CHAN"] = str(chan) self._flag_channel_selection[idx] = chan + else: + self._flag_channel_selection[idx] = ALL_CHANNELS - def flag_channel(self, chan, tag=None, **kwargs): + def flag_channel(self, channel, tag=None, **kwargs): """ - Flag channels and/or channel ranges for all rows. These are NOT used in :meth:`final` + Flag channels and/or channel ranges for *all data*. These are NOT used in :meth:`final` but rather will be used to create a mask for - flagging. Single arrays/tuples will be treated as channel lists; - nested arrays will be treated as ranges, for instance + flagging. Single arrays/tuples will be treated as *channel lists; + nested arrays will be treated as *inclusive* ranges. For instance: `` + # flag channel 24 + flag_channel(24) # flag channels 1 and 10 flag_channel([1,10]) # flags channels 1 thru 10 inclusive @@ -1032,9 +1065,12 @@ def flag_channel(self, chan, tag=None, **kwargs): flag_channel(((1,10), [47,56], 75)) `` - Parameters + *Note* : channel numbers start at zero + + + Parameters ---------- - chan : number, or array-like + channel : number, or array-like The channels to flag Returns @@ -1043,9 +1079,10 @@ def flag_channel(self, chan, tag=None, **kwargs): """ # okay to use base method because we are flagging all rows - self._base_select_channel(chan, tag, **kwargs) + self._base_select_channel(channel, tag, **kwargs) idx = len(self._table) - 1 - self._flag_channel_selection[idx] = chan + self._flag_channel_selection[idx] = channel + self._channel_selection = None # unused for flagging def flag_range(self, tag=None, **kwargs): """Flag a range of inclusive values for a given key(s). diff --git a/testdata/gshift_box.fits b/testdata/gshift_box.fits new file mode 100644 index 00000000..ae24d1de --- /dev/null +++ b/testdata/gshift_box.fits @@ -0,0 +1,539 @@ +SIMPLE = T /Written by IDL: Thu Oct 10 10:23:24 2024 BITPIX = 8 / NAXIS = 0 / EXTEND = T /File contains extensions DATE = '2024-10-10' / ORIGIN = 'NRAO Green Bank' /origin of observation TELESCOP= 'NRAO_GBT' /the telescope used GUIDEVER= 'GBTIDL ver2.10.1' /this file was created by gbtidl FITSVER = '1.9 ' /FITS definition version END XTENSION= 'BINTABLE' /Binary table written by MWRFITS v1.13 BITPIX = 8 /Required value NAXIS = 2 /Required value NAXIS1 = 131834 /Number of bytes per row NAXIS2 = 1 /Number of rows PCOUNT = 0 /Normally 0 (no varying arrays) GCOUNT = 1 /Required value TFIELDS = 83 /Number of columns in table COMMENT COMMENT *** End of mandatory fields *** COMMENT EXTNAME = 'SINGLE DISH' CTYPE4 = 'STOKES ' COMMENT COMMENT *** Column names *** COMMENT TTYPE1 = 'OBJECT ' / TTYPE2 = 'BANDWID ' / TTYPE3 = 'DATE-OBS' / TTYPE4 = 'DURATION' / TTYPE5 = 'EXPOSURE' / TTYPE6 = 'TSYS ' / TTYPE7 = 'DATA ' / TTYPE8 = 'TDIM7 ' / TTYPE9 = 'TUNIT7 ' / TTYPE10 = 'CTYPE1 ' / TTYPE11 = 'CRVAL1 ' / TTYPE12 = 'CRPIX1 ' / TTYPE13 = 'CDELT1 ' / TTYPE14 = 'CTYPE2 ' / TTYPE15 = 'CRVAL2 ' / TTYPE16 = 'CTYPE3 ' / TTYPE17 = 'CRVAL3 ' / TTYPE18 = 'CRVAL4 ' / TTYPE19 = 'OBSERVER' / TTYPE20 = 'OBSID ' / TTYPE21 = 'SCAN ' / TTYPE22 = 'OBSMODE ' / TTYPE23 = 'FRONTEND' / TTYPE24 = 'TCAL ' / TTYPE25 = 'VELDEF ' / TTYPE26 = 'VFRAME ' / TTYPE27 = 'RVSYS ' / TTYPE28 = 'OBSFREQ ' / TTYPE29 = 'LST ' / TTYPE30 = 'AZIMUTH ' / TTYPE31 = 'ELEVATIO' / TTYPE32 = 'TAMBIENT' / TTYPE33 = 'PRESSURE' / TTYPE34 = 'HUMIDITY' / TTYPE35 = 'RESTFREQ' / TTYPE36 = 'DOPFREQ ' / TTYPE37 = 'FREQRES ' / TTYPE38 = 'EQUINOX ' / TTYPE39 = 'RADESYS ' / TTYPE40 = 'TRGTLONG' / TTYPE41 = 'TRGTLAT ' / TTYPE42 = 'SAMPLER ' / TTYPE43 = 'FEED ' / TTYPE44 = 'SRFEED ' / TTYPE45 = 'FEEDXOFF' / TTYPE46 = 'FEEDEOFF' / TTYPE47 = 'SUBREF_STATE' / TTYPE48 = 'SIDEBAND' / TTYPE49 = 'PROCSEQN' / TTYPE50 = 'PROCSIZE' / TTYPE51 = 'PROCSCAN' / TTYPE52 = 'PROCTYPE' / TTYPE53 = 'LASTON ' / TTYPE54 = 'LASTOFF ' / TTYPE55 = 'TIMESTAMP' / TTYPE56 = 'QD_XEL ' / TTYPE57 = 'QD_EL ' / TTYPE58 = 'QD_BAD ' / TTYPE59 = 'QD_METHOD' / TTYPE60 = 'VELOCITY' / TTYPE61 = 'FOFFREF1' / TTYPE62 = 'ZEROCHAN' / TTYPE63 = 'ADCSAMPF' / TTYPE64 = 'VSPDELT ' / TTYPE65 = 'VSPRVAL ' / TTYPE66 = 'VSPRPIX ' / TTYPE67 = 'SIG ' / TTYPE68 = 'CAL ' / TTYPE69 = 'CALTYPE ' / TTYPE70 = 'TWARM ' / TTYPE71 = 'TCOLD ' / TTYPE72 = 'CALPOSITION' / TTYPE73 = 'BACKEND ' / TTYPE74 = 'PROJID ' / TTYPE75 = 'TELESCOP' / TTYPE76 = 'SITELONG' / TTYPE77 = 'SITELAT ' / TTYPE78 = 'SITEELEV' / TTYPE79 = 'IFNUM ' / TTYPE80 = 'PLNUM ' / TTYPE81 = 'FDNUM ' / TTYPE82 = 'INT ' / TTYPE83 = 'NSAVE ' / COMMENT COMMENT *** Column formats *** COMMENT TFORM1 = '32A ' / TFORM2 = 'D ' / TFORM3 = '22A ' / TFORM4 = 'D ' / TFORM5 = 'D ' / TFORM6 = 'D ' / TFORM7 = '32768E ' / TFORM8 = '16A ' / TFORM9 = '6A ' / TFORM10 = '8A ' / TFORM11 = 'D ' / TFORM12 = 'D ' / TFORM13 = 'D ' / TFORM14 = '4A ' / TFORM15 = 'D ' / TFORM16 = '4A ' / TFORM17 = 'D ' / TFORM18 = 'I ' / TFORM19 = '32A ' / TFORM20 = '32A ' / TFORM21 = 'J ' / TFORM22 = '32A ' / TFORM23 = '16A ' / TFORM24 = 'D ' / TFORM25 = '8A ' / TFORM26 = 'D ' / TFORM27 = 'D ' / TFORM28 = 'D ' / TFORM29 = 'D ' / TFORM30 = 'D ' / TFORM31 = 'D ' / TFORM32 = 'D ' / TFORM33 = 'D ' / TFORM34 = 'D ' / TFORM35 = 'D ' / TFORM36 = 'D ' / TFORM37 = 'D ' / TFORM38 = 'D ' / TFORM39 = '8A ' / TFORM40 = 'D ' / TFORM41 = 'D ' / TFORM42 = '8A ' / TFORM43 = 'I ' / TFORM44 = 'I ' / TFORM45 = 'D ' / TFORM46 = 'D ' / TFORM47 = 'I ' / TFORM48 = 'A ' / TFORM49 = 'I ' / TFORM50 = 'I ' / TFORM51 = '16A ' / TFORM52 = '16A ' / TFORM53 = 'J ' / TFORM54 = 'J ' / TFORM55 = '22A ' / TFORM56 = 'D ' / TFORM57 = 'D ' / TFORM58 = 'I ' / TFORM59 = 'A ' / TFORM60 = 'D ' / TFORM61 = 'D ' / TFORM62 = 'E ' / TFORM63 = 'D ' / TFORM64 = 'D ' / TFORM65 = 'D ' / TFORM66 = 'D ' / TFORM67 = 'A ' / TFORM68 = 'A ' / TFORM69 = '8A ' / TFORM70 = 'E ' / TFORM71 = 'E ' / TFORM72 = '16A ' / TFORM73 = '32A ' / TFORM74 = '32A ' / TFORM75 = '32A ' / TFORM76 = 'D ' / TFORM77 = 'D ' / TFORM78 = 'D ' / TFORM79 = 'I ' / TFORM80 = 'I ' / TFORM81 = 'I ' / TFORM82 = 'J ' / TFORM83 = 'J ' / END NGC2415 AvZ 2021-02-10T07:38:37.50@6@eO`@10r?@? ? +Ϛ?%g>?#t?h>$>>IP?*/^>6?? _>):>4>8>O>`Qh?k?Q>}?қ>M??C|>>8?6E?0?G#>E>^?I\>~y>L?Bk$?;DR>%? &?/o>0?%X>J}>D?B(?=k>j>|U?_=>?^EW?_?-5>ł>~>П?0/?H?D4>mh>ڀ?98G?f1?4?(,?F>]\>wr?Ob?_$?[(?H>$t?id>?>>?">G>M?>>nW>P(=>>Q>4?(? ?3??&Ժ?@?9j?>>8??">sb>+>L|?}??Y{>d>y>̘6? 0?:?K?7?J? +T>ͱ:>Z>q,>UF>zF>n>G> >I>~>&>Uh?)Y? 4?|?*K>v?Y?3>8?>?>/>}>d!>? +z??-à?O]x?'Tv? +X>TM>!?/??Pf?en8? B? +?W +>>o>f>r?AT? br?`?@>[&?>>?,Qj?!"P? ?<~?3N'?:Ȝ>g?`D>R]>fp>|>Kt>5>%>̝>?B?3rt?;?Mx?+>ޔ? q-?@> ?ˬ?B?'*?'t?>ݢ=>]L?#>&;?Z?2>Pj>7>?>JD==Nd>8>d>ӆ?3 ?w~.?`#?; +?@?h>b=NM>>a>>>>>:U>;"?4>?">d>]Z +??^>F>z>T=-P>>v>^^?._x?R>1>ݎd>/=FH??`kZ? a>f=|>>jY?G?)f>h?1 ?KT>/=D>W\>f>m?%m>(">-a?N?ZF?K.?/{ >ܕ=0=d>cy>?B?(>>??H?5?&D>8>QF>y ?">A9>m?.?N6?V >c=;> D>#>1mF>W|>>LT=:Ӑ=FL>/;>YJ?3P? +gX>E??M>>D?W>e>̨>A>Tʮ>x?S>{?k>q?.??P?:>|W>n>,>&>ʱ>?>~>>,K>م?U?]?N}>>g>'? +Q?V?6>9>>">>/? ?V?C>eA?j>A>'?&>>???0?6 >?%?&w:>k>??w?O^> >>n>`>߂>>{?-^[?^> S>j=__8>׾?w?]$?N4>">q?b>w?;d?>>ߑ>>>S>Ul>>⮿?#?:?`?9? +>R>|>d>?J>>pi?&j>_?+P?g5R? +[>-j?v? n>w? G>>g?A>0^=h|>?>?#T?; >6?ZA?]?;"?6g$?F/?>4?8jC?X?eF?k3>&>e>ԉ?.H?*/>fr>{6>? F>3=``>s>>?!+? J> +?-8 ?Z^.?k>>???? b>b=l>s>rr>AR>'8??>V>jeb>?9B?8?#?B?5?R.?>>(p?.0?>&>K>C?K? {>孹?;w?L6>t%?.Ԅ>G>U?$8?u?~p?>ի +?e?kh?OW?04?3w?$?.#?'>>>?[]>:?h?x>9?,>r>H}N=-@=t=u=|>q?1>mH>? +]?>Z>[?*?"@>پ?;W?S>z??#?|>D>9?ql?g?D>?N\?\ϊ?E>?`ޱ??!P?2>>n? +?u?>{>>3>=>?b7[?@>7(>W|>T>f?b>.?=T:?c1?cr?on?C-@? G>=i>q?3j?'ƍ>V=>> >*>w>3?=I? >؍? >Ȅ?N?5ٙ?[>L>>?'?gD?>>>>Qk>p^>Du?+?XM?q[?,>Ô>6Hh>8?#e?\?G?MT>>?:?dYG? J>!M?Q^?>?"?,RT> ??$>O>>ٴ>1?ep? k:?y?(k?]z?dm?/?jV?>>K?NO?b? ~`>ux?s?=?K>z>1?)>>ԍ?*œ?̗?>5N?>d<@<>e?+>L?SE??2?Q>>j> =R>'k?c?(?Z?I̢?}? +t?@>"=2L>2??>>>r?Ub`?>>`>">>f?Wv?P><> ?5=`>>a?:Y}>;? +?v?U?L_~?%r>p?R?>5>?>?v?:?8?e>2?4 ?G=??x~??t? ',??l>9>$x?">?`?^? \H?֔>>G?:?f ?"/B>7?V?2c>=>?@O?C">e??V{>|>V?j ?kBd>^ >h\? 8R?=?5>>%?vI"?9Q>>/?L*?^i>>RD>J>8v>? y>:&=>?9 >~t>>>?/]>>{.? ?>?:}?L?Q~?WB?-\>Z=ߤ>v>*T=ZX>q> >P?b?M?^6?l?%?L~?~> l2>lE>YH>^>dt>>x>i>}@(>U>o;>>g> ?"?h? ?i0 ??l>>Ѩ?P>0>?M6?'5>c? ?*Tu>s>r=? ?C>c=???i??Q?a-?up?+??57^?? j>\L?r?%>=>>_?r?>ij?)?A??6U?^N>㌜> >#?%?@>O>+>ܲ?>l=?\?:?0>j>z ">?;?Lڐ?7?Ij?q?p?{N?Q>c>ᄊ>-?>c>+?*\?%?s|>p >/? ?Q?>c?&*?H]?Pj?>~ST>?h? XW>Ȃ>? p? 0|?Ĕ>Pc>?$>'^?7?F>^>O>>Y(?E?I_?>f>Nq8?!?>S>>\?-T?>C?1>X>&>&e>p?F>l>է?pW?>0?@?X?n?&F>갫?V0>n>?qT?$?RJ?r>_n>>>>A? ?Q/?O>?)RF>q> >x?f?2>?7z>>zg>w">?9?_F`?#?\>?(k?/?! ?FX?J?#> >W?,C?f ?eq?!K?"Y?JQ? S>5}>I>8>>I?1K?;n?"w>>= +r=?=> WP>G>J>>~>x?!L?>>a>j>%??cd?6?$.?6"?B2 ? S>sB>I*?_{:?o>ŝ?}>S?>~>w7X>&?1N?T8?/?_?7>F>i=>7?E|?;? +?.?`?qSz?_?J?n>O?h?iJ? ?'>X>q>>>_ ?2?n7A? 5>a>܍??A ?&??6>H>?|?"?+|?KP>>?-?Q>e? >>$?=c?>>p>eD>/>g???.>)@>JP?Vt>>?Pk? >>=8>+g?Oj?_EF>ϼ<3>? ـ?Y?>Q?c=?t!?) >Ê?g>?If>]y>>,??x??#9$???n}?tf=ҝ>X?<d?KbX?7B>y=E$>ӊ>ۿ>?=?$X ?[3?>#?!$><>,=7? QF?a>=D>>[>>UM>Ԡ>?q?%&?Bz?9~?kJ?j?3p?&H?޽> o>h?>r? #?->o>=$=D>?B`>Y?)?h>v>xJ>>~?3?+#>P?fg?+>WU"> >2>Q6=R>bLz><>>>^> |>ίp? ?ID>ʎ=X>$>g>? y?>Jk?N?Iݪ? Ԕ?L?T1?2d>>S>?_E? ?C?Ud?e/?4)?p?*>Jr>T=#h>l>n>_>ʙ?]>?R?J?e?B ?H>dM>-`>>t>nM?߆?)\?*L? z>!=(>>!>Iw?Kw>J>Y>l7}>?J??[?ao??n\?Iq>> ll=@>?#r?5[O?9?GZ>>R>R>>ۄ>h?g?m?TM>>E>r>fMJ>9U>>?D?>>z>7??,D">Z=>??6n>=>ZD>ȏ>K>q? R>.)=_|>Ex>M>mr? >r >???>Y>{?D@?{>I?N?M@H?,?E?F?.'?oOv?.`>V>ӡ?=J? >??1 >8(>PI? +u>?+ن? 3(>!>?'?=1 >u>j>ɛ?82>[E>>U>%x?>q>̒>F>"?i>9>}?q>>Wf?l$?Ү>6=x>">l> >ȑ>4>a>}? ?==Yh>??5S?hJ?+?nX?>v>tŖ??> ?\j?C@?!>X}?0o>y>W?6>? +?4?>(? ?c?q>-6>T?9fM?t? +?L*?g +>%4???l?3? Β?-L>1=vh=6y=L>@a>>N>?i?AZ>c(>b>H=> >` ?a>k>Cu>2>???Jӎ?Q_>y??>>? >{p>Xj>ҵ?Cj?C? x>Y?+>>>m>&? ?"?P>+=g>~>O=̏$>D&>A>>m>? 4?6}>.>*?D?lB>u>?&lr?8g>>?(bx??X?[?%l?>>~Җ??B3t?*B?..5??+?,>t>#> V??K>=fz>>O<>r4>?'v>U2>(?$^? M?=>}>>5?& +?^>H>!N>B>n:>>z=>r>|,?8D? ?O~??D?O*?8t ?)M?,Hf?G?]?B>E2>]:>7>ߟ>\r?ٽ?M??1?17>1? +?(`R>.>>2>? +>o>6?r?M>˷??!?p?Mn>?x?W=">? ?%M? ??8-:?w>Ù>ڿ?>9>%??7s>(>{>q?>,>c>;f>=`>>ˡ?P>0=T>[P>}>S,>!>>t??*>B?? +*Q>fn?5?.S?A>R=5>m7>R>"?;>>?>Tu>B?~>ξ|>J><>R? @>DL>c2>ꀴ?9-8?@wL?1?3?N?B???0?UR?;>X?%?"r?<>4L>p>D>#>z??U?C?QT?6N?F>>)?A~?;=?Ϧ>ap>y>5|>>^>bu?Y?h>SV?@T>l>y?66>?>J>Z?ٷ>Z>#R>?T>I>ى?-?:? >\?6}8?MI?>&?5f>Y>?>?$!N?'A?(`>">y??di?DrM>I>@?7>ʥ>*<>>J?~?x?^i?MPY?LB>MkZ>nl?E?@-.>=H\>>>V >>?(?">'?F;?UI??)>>B=~h>S?,p2?)LL?-?(?D?6c>>9>\?R>>I>?f?N? +? +>t?5?-*+>?&>S>>>cC? ?Ab?4=>>j>`b>Q>C>Q7>?%M?W?k6>n?E? >_?J>2?Z3?;>I?L>>Jl>>o>Ԑ?~? >>U?ik2?>>6? >S>g8?js>>ć,>>c??P?)P?Dd?A\H?v>ӆ >>Hp>>|=x?c>ꎤ>b?;?7? >m>bv>&?b?Q>h?'3?44?Bf>6>>v-A> @>6>J>?A}5>>5?bZ>a>>>> b>n>#=o??g?;y?>R? V?C?=w?>? ?,Yp>`> ?4@?x?x=b=@>?6G?7rD>L? +?$>?9?d">=>SE>)?k?R>ۗ>ۇ?4t?9>&>S=c=ܜ>?T? +> >yP?P?N= >^?}t?i9R??>>>ؕ?z?J??Rm>={E>\?(~?G9>&?7+:?>a>ww>s>˕>?C2?#l?Yu??>u>AR?ɔ?$Z\?aD??b?^> +>;)>?&> ?{?>N>֊>w>cJ?c?89>z[>P>>>7>{j>Ù>َ>?Z?J>>6.>E=TX>u*P?^?+q?>;m>i6>?P>np>J:=>E?,yo?'?B>ɦ>֩Q?&?>U?D?Z ?$lD>>>=a >Yz>%> >ʳ?#9N?i5X>o>d?&?:b>=>>>A>E>n>w>I>>h>> >n?9??b?G?Xf?q0?;.?E?(L>2?=q?8>!m? +?>U>t>??XO?1f>6=D><8>1{>+>j>d> ]l=s=t$>?.= $>z?h̛=a>=橐>>һ>غ?v>`> +>V?.?0>M%??+x? i?@R?N>ݓ>Ϭ>6??/? ս>6=q???6?=?C&?\?B?R?`Y?xr?#?a?u?>ȼ?Kc8>J>Nc>D>T>J>->b?Zt?+>៤?>V>$?:xO?> +`?T>L>q>|>sJ>I>ֶ>Ql>ǩ>>>U?>i?> >ޘ?2~?(?9Z?[n?+>N>8>w)?n?,=} >Dv??f?Od?L? ??I<>8Ÿ?'h?G@?N?g ?`>?6 +?Yhs?A>I?:?F>s4>?B/?:=>?B?z-?3w?:UT?b0?Y>/ߌ=`>%?'>]8>?c?ir? ?"?9>>>>Ԃ? ތ>S??>D>>l>G>>4>\d?A ?HL?8?M?,>Ҷ>9J>L2>aF<>>>}h=xT>^S>>mK>:>>:Z>K??D ?K?LZ?f>5?7L?" ?$j?%#??5χ?1>tZ>?>0>v>!>o>ܹ>㸤>z>r? T?D?+ ?;j?XZ?E$>>y>>^>-??Ǣ=]>x0W>>>g?}`>c:>>RC>a?I}?J\?-?5>Ch>}C?H&?{>H>eP? 2?N>*>eq?1(>>??>f??1r>17=>۶? wT>b>?$j?;?.?Zx?I8?J???,>,>QP>n? ?=,?O_3?$>w=?t>?4̮>>8?1 +>Vm?>_?&j??g>?-=?TP?>>^8?*/P>@>}?Kax?>֏?JB?%??aO>(>$A>}?~?F`>>|>?"?r0?_>Q>l`>Q<>'?w?,??.t>o>l>??0j>>>?>T>&h?{? >>׉>? >ۂ7??)1?&? N>օ>_=$>s,>>vQ>? ?/|>>8?K? D>Ϭ|? %>Z>b&>]?]? (=y>8?5>NY>ϐ>>>??k?O?^8?'fB>B>>(>W>TK>E*>/?Py?>y/?9?0{>o ??ݴ?+KE?">>#>|?>->?wX>p~;= P>*9? r>?hD? #>? l8?Of? /Z>:Ex>B?1?A$?13>!?y?>R>>?&$>n??lo?EJ?;z? K>4n>W>l>b?B >?B=>P?ca?-i>3`?>7>6??E?@8?׈?>c?^?Ut?]{?[?@Q>x> U>A>2?`ɲ?(3?-?]v?]?c>ӏ=x> -?>>?7`?_j?'??/P? +> z>&>q">+g?)?HE? 3R?) ?">>6i`> >=>f>F?Y?YyR?b>dL=E=>">v >H>[??;>?a>l>>e>F >W?H?b=r{0= @>>մ> >!D??=⳼?K?&>->E=C> ?<N?7ب?L??(>>+x>>">U>ꭢ?]r?6>+?n?UqT>4>t?YPe? ܡ>t>D? ??0>P>=>>?L?y" +?0H>G$>?M?uѫ?R??n>`2>:?9~?1]?0DX?<5>>N>> q>? +>V=3Ǹ>b"?x?u>N,>_? ?T^>qb>pS?">7=^@>燼?I>>5>?A~?6 ? O?%P?N?6Z?@>n7>">H>ƍD>]>L>u>X>??)? ?G?k?Esh>?>>>D>b>=>t?F}>=?"> +>¢?I?M>9{?5?q?4((>ϓl>=2=^>:.=L&>?V?>O?'?j?xr>s>#1>>>?'>IU?H:? =d?>F?? > n=%>=>JL>0u>ܒ>3? ? A>P>*??:g?? B>YD?֫> ?'?;?d?6>d>Yk>=+Q>v>ĺ=>?>>h\>Z>Â>>H?-8?]?O[Y?b ?M?}*>u>6>#V>J>D?F?ld?K>;>><>S? m? (?E>!`?? ?~? >\?aE>5>u>G>{?q?K> +?G>$=Y?$?B+>>0>º??U7? +?*fN?>?C>>MY?Ј?*3Z>A?*?`>a?!a?>}(?,A|?RX?@_?4>Z>7B?)>\f??M>O.===c<>#>>|>Bk>?0v?,??,?*K&?$@>7>f>l?6?C?4?A>Q>>>UF?j> >k>$&=H>?Q?)Y?/.?c?Y?.?0hN?>e|v>築?CN? >>1j6=S>^>_`=3K>c?Z*?$ >p>5">_2>K>(? $?55/>ͅ>K?X? +??+,>O>Ip??}4?cce? >f?>?S?C&><>f>S>5?i?z96?j>ݾ=J??G^>?=`h=7 +?OA?S?{:?\?#Z?"?mv?Y=+t??aj?U}?=^*?Q?0r?$~?O?o>>??ʆ?f3?It>? +?>)>>? ?)?Q?p'?_9>z>MF?"|?P>>@}?-A?o?j?z>]0?!v?n-?r=?Tj?5> >(>C? ?=E>|>YV> =L? ?&Tk>2>?,?w?>?9?x\?U$>>Ή>q??k ?<,>Lv?V>? +3?.֠?|? v? b?M?M?>>??>i>E>?S$?B9>x>8Z?t>ѥ/>_>w>2@>ո6? p>^D>?R>Ļ>JZZ? $G?N?r?zL?d?p~?X`?jF?S(?(>o?L$?Uh>f>ѳ?CD>E=h>?>Ǽq?2Ȏ? (=أ$>s>Q> +p?"?>>>7>i >D>L>nPz>??x*??'`?a>xo>__.>r>W>TB>Ƒ>c >r>1>?j>`>t= >>Dh>JXN>hL>E?0C>*>y;?dE>֖>B|?>]?L?I>,>[l?;?>d>>T>֊>1?Z>ҷ?CD?A?=->$>v?>+>ZA?1}b? ?$ >ū+>?Թ>!>=y(>x?NJ?$9?P?*">hl?e>??MB>ĵ>ؐ->_>o>*5?f?>̘??X>|=6=D>sv?0?a>B=? >zk>D=+h>s">y>jW? Q?^?>>v=2 >Ӌ`?[) >>D8>C?5W>?'>e>'??%;V>>2>'? +?t7?zc?}>X.??!?CR0>|>j>a? U>pF>?7?Fݳ>{8>e}P>$>@f>|?DM?t>?^E?'a??g\?\>4?:?h==>>?N?@?Hg?H?8?&?;0?A>M?\>>YO>d>G#>}1>ƨ?y?$?Z?0+>I>>?w=Hh??>ʴ>yA>+>l?5v,>I?%i?=~M?Ut?%?",?-n%>6>a?Pq#?Ԩ?D?dP?'z? w?߾>?7]>>`c>@>e\>N?V>,??&2?/>?!zb?t?%`?:Z>Տ>1>?&Y??e>w=h >@?Xa?qk?=> ? <?Tb?UG>>b?B?T?,@? D>8'>>@>ٔ?Ig>^>.>?3?VR?tm3?AO>l>KԞ>.?->K>ܯ>?$>k>=>=+z>P>Ϻ2>)? 3w>ϩ[?&?$f>q>vp>?P? &b>c?Ed?0e?e?D<>=p>#>ܔH< ?V?>?rh?-d?>b? ?xj?>)>?j=z?>?|?g?>@E>D6>s@>>>>a? ?Pw???eu>K? ֶ?ՙ>҄j>i>>0?B0>?XM?I/?h>>r?g?K> >*?@zL?a`??0?Y?9,?BUd??7d?j??H@?&N?&(?S>7>~???\bh?NS:?I?)' ?J#?uѣ?0A>@?e?8?=b?K4>ֻ=pH>4?>>E>\:>FD>?s?@+J?T??!?I>ۭ?*? u??'=g>i@>Kj>?- >•>s>aTf>٘> P>!? ?8???.9#??>R">? c??JԼ?F]>^>/??m>?"?7?װ?PP?i>\>z +L?^>|>>Xy?Bb ?_@?>>|?*"c?)d?Bd?H?$ >2>??;>D8>g?+[?!?=-2?@>>qv|=/$>LZ>I>>>,?&?T?O>>d?F>ۢ>@>v>i>W>̪i>>T? =?>H>@>XX>>>酴?0u2?/a?)?J>'>z&>_(>3>0>s?9>">? ?2?>үy??B?PK?A?^?M?"?Sϲ? =>Ɛ`>y5>&H>>Q?3V>>j?}?C?~?NOL?) >>>!?$?-?@p`?V">>B>TF>?5>| =,>#>>_H>?N$>>ʴ3?D>;?l?^?t϶?xV?=4x>OM?G2z>]>?p?,> U>>> S>!>>?)L?)z>>>Q3>/?^?Z:??à?%p?+?L >??&b?8?Ck?>=~h>4??.N?H >>~>>}(>ÖY>>V??%j?f&?:(>m>T>? b?W?q>?$7>\?l?>>Z>.?3t> M?N6?+r? +g?&>e>ةg>>sx>+L> ?X$F>DF=d??@4l>!>6%>k}6===w>l?%s?%1.?^?Em?X'>=-H>FJ?0?8? ?|?/;n>Sf?;?3="}>׸?: >/w\@>,>`=6??Ur?>>?$q?AyF?#?$? 0??3(? ?,?H>>>>)>m>??d?y>֞?*?ؔ?A>>u?T>{>lQ?H>>.h?=\>H>Hy(>>?Et8>9\>??#>b>"j????;$?ZՁ?M >">?P? ?2P?J;c??_>]>??_>S'??6?CH>Y>>>>>(>?"F?Th?]ǘ?MG??.>N>Ov>'?>4> X?ժ>>X?CF?EO?4U{>Ě>Ǩ?C?7<>:>ފ?>9?Z?Tg>h>=,8>>=L? i?q?o5>n>?1U?KK?"c?j>m= ?3?92>E>e?L<>f>?YB>|X=`> ?i9?)>2>.9? *?E>6M>?6i +?n?&:c?Fb=uxx>s&? +\>8?&?Qt?e^?L:?'>>k?E2?Is?!">>?>?=?&m>Ƨ?7%? F>=>׉>b>?5k?l>Г>v><>?>2>J3>B?*?>džT?!?C1>R>>>rLD>z?@?9>9>>cu>>>+$>Us>>{>o? ?(J?4?!>?T"S?0]N>f>(???V> +>`(??ee>6>F?>0?>7X>?S>>Y??M?LQ>ܶ>j>2> 4>j">>x=>%?;? Kl>"z>Co?=?60> >ɀG>뗵>Q +>\??2?.>>oa4>V>>ȕ??>=?-]>ɼ>z,>E?[A@?jf>?]>+>?]h?V>b>g? J?4M?dLH?c?mӦ?IȤ>`r?[?K|?K?&> >V ?Uʜ?-0?(0??$>A?v?^a?\?Kͅ?-?>ʻa>??S?C7>>T>X?+:?3*>D>ɤ@?AL?2n?-?5j$> ??~>>??XB???Ol>ƒ>~?.?*=?)??p?O' >f=?>ױ@?MĀ?>?U?j?n?>p>R>,0?>u~~=ӻ4?n?gb?i?o!?6?8=? ?0?>P>[> ?3>E>}T>>>L&?=?=>Y0>[>cS>2:>v>|9?Z>Ҷ>~?=j>>eu>>l>k?Xc?LF?jl?&>v{=Ȩ>z>ě&>*?|?#8?lߞ?h>>9>>]>V? L>>m?D ?d'?2;?!>X>??@>Ͷ?>ƪ`>d>D>,?A>?@ر?A{?.>! =_i=n>W>j=I==Q>H>?Eb? |=c??G>?[k`?(?3"?*>[{?c?F(>f>'>#>r?L>cX>>\>Hc>?D?30?YԒ?L ?S?2,?F5?>|>d>>J>)C??K;>? + p?g?E?6>ip?@>=xf>&>ؘ>CI? U>`?U.>e>?(?)? В>3(>>a>>?b?=[?=\?+">ף>M{? ?O${>ф>m>?m>}Z>+>w?4?oC>Ld>>=??5%)>)>t?ț>>%&?3:>>?>j/>fp?P?D?WUp?*>p={:>K>>r?>pj>>H?d>Uq>? 1=N>???q?-">Y?Ff>>? >$>n+d>>>?S >|? >X>N>yU? +J?18?j?7q>>/A?>ޣ>lj>?.>"g>,>?+?mǢ?Wd>>L? &+?d?0? +??$>g>?w>㞫>킓?D>#X>w>@>mm?$$? >?r>uZ>EW?;t?_v=̿=g?>?>7>Hs==>>V? IJ.??\Zo?>ξ? ?H] ?t?[Y>A4>>D>v??L*? >?8?S+;?_Ls?B?>Ї??84>8>wd?D:?!Y?P?f?.t>>?>>U>%?>r2?_>h=Y?F?Ze???\$?r?{k?D>>n>>I>*>G>ɮ>?P,>>">>t?j>r>kl? ?L[?^\.>֚?O?5?#>*?=r?A?~? ?-?72,?6?'??W>Ų>0? ?>0=r>"?CIN>R>?^ ?t/?C>>?&uz>(N=i> ?o>Q>K>??p=x?5>Q?'n???r"? >gm?Ϡ>>?-S?1`?k`?gq?B?+?W>ޒ>ד>Bj>d?J?'>]8>?,=D/>>CB>o=>I#?L M>P>A_? >1?2?+A>?>?R>Љ?!>T> ?=W> >Q?>c?C>- >@?0?#:?>P?P +?^?q*>Ҕ? ??Hu? >?r;>Z?r?@K>>>DP> +>(>`"g>L@?N%?>]>׺H>>EP?t?!?7>p? ,?cz?)=|>?A?#>>i>?*?>z? r?9'>D`>a$>w?6?n?>׳h?>>Ȱ?>?/>D>eDt>?f?I+?1Z?&>?*>ӹ>ۆ`?Oe>>? *>L>?6#?)G<>>[>#h>R>H>>Q? bZ?6PY?0>V>u?M?6??+h?Q +??,0f?t0?V/~?@>i]>VbT?"wD?Ds>?7?!X? 2?[?T:?3t>??? >">f>?>X&>?W?!y?~?>>4>ո>+jl?R.?(~>?2?\]5?>>r>->̈́??a?1X?z???B?=?UF?`?Ox?8*>؜>![>:>N?>>Ir[>a?*.?$?}?>6>f>>}DT>Z.>>:>Z?D?91>݌?A&?>o>>={T>%?>T>>>V>*>'¸> p=Ģ>A>>?؊?)6?>9?*l>? ?t? >;,?$?~#>=1?=?/>i>{\?$?.?N?]>u 0>>J?>b>v?2?$3&?o?K"?$>m˯>E=@> ??=?2?JU?< >$>&>t>w>z>Z>b.?0 +?C ?"D2? `?Wou?$h?g? H><>}>A? +b>=7>Hr>g?m?Vj?-{*?!?A|>>D>Lp?t>9f>?Pm?M?EZ?C>>>>>s>~Z>N> >r??7U>-2??%>x +? :?@J>D> w>J +?< ?Vj?T?5>">>>*Y?>D>9>>f?y>{>`@>Q)>t>?'?Z?J >@>H>c\?0[??ʴ?Dd?&'?$>=h?s?JQ>q? >E?k*?(?\l?$? >8D=7=Î>A^?>=b>a?'0>>d??&?>Ef?]Z???I>Q>J"?Ȟ?W>z? >vG>c? ?"R?3S>u9>t +?;?Q?d#'?-?.(>? +?Z6?">x*>b>x>?W}?%?6?T<>L>? R>Ң>Nb> ݘ??.5??)~>>W?ut?BX>V >?;>G>Z>>E8>D>0>O>2>=>m>Z>>t>G?,L?,?-C>E0> x>m=W>%?B"? Aj>f?&>^>6?D?1x?1:>>!?U?C^C?;u?? 5 ?S3??>?F8>V>>N> H>@6>?D?;g?=#7n>>Y? B?6>]? +8>ڀ==>?>5 >~>>}Gh>?@"?Li?*?3b? ?-?O,>;>=:>1 +>?G?_Y2?K#>?ٷ?h:J?V/>>ry>/m??fx>۠>?PH?@Z?2/?];?#^>k>T0>l>?=?:v?E?-J=? +R?I֠>C>>†?.!?lHo>??QJ>> @>Ep?K?a>>_>t?7Ӱ?=w:?\? > ?2`>??;?3?xk$?p ?.X>H>L3?X>;l>? +?Kj?L ?60>>w>>0=T?t~?C8??@??? %>>d> >P>L>٠=8 r>9?E:>o>g?!c5>A? +? T\=@>,>6=n>>ɴ>>M??~>G?%~??Ƽ?p>>r>5?">,>^0>:>w?9?2?J?y( +?P>:?`?>c>_>>?j?F̓?EP>V9>?!FL?n?bq?*?b?S|?>O>y>Ϊ^>>>[r>B>q?2*?!>>x<۸>>t0>L?,>p>W>>`6?%?"?>h>6?\?Pb?P$d?i?M?)?>̿?>f>?e? %.?m?}?"?C0E>ث>]'t>D>?Q?pv?D#>Z>%>q>??'6?$ B?^?'2?#(?m > +??Q?"i?2w?Gef>@>`c(>Z?M?E>o>(?H>c>? ?+ ?&5F>q >N>t?>d>U>8 C>?z>n? +>>? p?#?[ ??Gx?"?dM?E>_>?6>ώ>u۩>ļ>v>[>?*?\>Ev> >mq>a??"&8?5+?dd?"yL?;5?Mr?Zn?Su8?' ?(o?~>r? >>??*d>ъ>?̈́>5?>c>ص +>==>?> >#t?#?S>>?)?-'> ?">J@>>~? {~?#Hr?3?3,>v? >/>W,n=w>?=m>B>ˣ>n??8+>>@>T?;p?(y?6 ??>#>ș?T?Ta?4>>>8>?r>>6>6><>aX?/52?h>6>>7?l>8=ݸ>>>c?!?>q?,6;>=l>(H>1?+M?8?&>㉺=Y=q>u#>l?{? +D>y>> L'>2??r ?O?,J? R?9><>b$>r6>٘?>??l?&?*j@?C?Xt?;,>x>\>"=.>0xb>!q=0c +>b'>>Y>>9>&>x>&>`>k'>`c2>h>=>ٱ ?K?NX???=hF?">X>Q>Z>[?] F?k2?l'?c`?v?1ɒ>^b>0?+L?aI?p>?&x?h>?e?ֺ='>Cc>t>|?E?.p2>>J>8?ѧ?S>'?B?6~>R(? ?B>5~>~?,>g?==?o2>?>-???\S?>??P[Y> +>V?N?Q><>qv?7?$;>,>y2>ۊ?>p>Vs>͠>9>r=iIO>@>=}D>]>t$>>q>i>7?fp8? 2?$?c ?b?t>Š?@b?>*?,=?/'s?7(}?2?%>:>>WB>M,?x?I? ??m?;>p??CD>Ɏ >=H?K>Lz>G>B=<1z>3?-?2?b>a>%>?9;? +P>?ņ>$? G?)>?%?p1?TT>Y)>>5>?-+C?-C*?-o?"Ĭ?Xȼ?90?58?(d(>=F?^?[*>s>P?S>~>rҴ?EQ:?3 ?-?2??Xr?:? +R?',B?P>˚> n?%?h? 2[?^?m>F>t>?)&|>>@?/.z?fy>{H>,u?/?hՄ?2> RG>=a>Xd>E=|>u?dYr?'>8??d?'^>d>4?+2>ا=0`=>?Ȗ>>>?1h?h?):6?,? E>h>H>T>=?g"? +O?>f?ev>ڞ>[> >=.>Mp=V>??(\?Bצ?,r?j?~?:?@>>P?h?i?/1:? ?*^?PF?>K>_>p?3V?P?,>]?T?==>? ~?5?I30o>Q?9J>ؾ>p?:?^Y>Kz>p?%>e>֗>>ؤ:?+͐>B> {@>?>>K?5[?)G"?>Ƕ?4h>J>W?0X>Wa>c>U`>v>?.P?P?G?dl?D?M#? |2>jZ?8?Kf?Ng?-???B>>u>P?6?1n?OiF?IY?8_?>>X?P?QI?V'T>G=W>=>l>j>? z?>[h>յE?P?>>XV +?zN?E?d)\???mh?0>{K>+?(?U#?YD ?2.>ǘh?D?HϜ?;?6>W??hZ?) ?C?l??3r>t?W?!>"Hi>@l?E! +>ʱZ> ">?#>~? :>>n?4?? -?Z ?DV> H>D?.j?O‚?? ?mc:? ?ɢ?n?>}?!D4>`9>wo>X? #?e>8>2?:d@?)~?:"?>o?D??,Z?Ӏ? ~?@ |>NO>[>`>8?@G?+J?M?lK?W?U|?qg?h>*> ?y? :?:r? 9>?Pl?gv?J>L,>@.?+d?6Ɠ?al?2?? 2X?)>!n?f?!x>n6>)>>ɺ>bͦ>?*{?X=X>>wB>>v>#?<>y>)R>%>?4t?G?%:>@X>-?]?'<%?n?_>$?x>f>AȤ>?\?X*?mb?L +?Fp?_ >Dp>4?>=>h;>l?'X??)?"]?F>>;> >vjb>,>N>?~?S|?>?)>׆>N?2?U~?>I>\>U?$? >S +>%??#z>>ʴ?14>0%>u[=>?>F*>)?))?->]>r?߾? ?mt>j> ??)?M?;dU?Kݜ?>*>0>~?h?Q>Y>B>$??)h?0:z?=r ?W ?B>䷔>H??d'?n?9C?;F>>>1>?>G>>'N>G>f?a.?a?C|?*r?N?>=䳅>$>ܱ +?0>=N>A?t?C[?Q ?S>q>.>?S?nX?J?|>>>~>D?Z?ï=XN==<==>&?B">(>I? ?3?0??b?w$?MF?2؈?>k?a?K&;>x>?>>{EV>`?W ?H$*>m?.wZ?X?Ux?y?2\?l>> ? T>8>E?!?J>⫌=>7"?(?#?#>=#??)p? >$Z>p?,X?^?S>M?FF>?T?e>>ĥ?Ml4?$K>\ B=.^>)><\>H?5)?WC >V:>>?Q?mu??o?Do?61?5>F>P>>s?&>>݃?ڴ?I6?7s/?&,?N_?yML?P?O>˟?F?AN?? ?9!? ??K~~?j^? +:x?WWT>u>>>}>&>ݖ>䧮? M?H??#?1=?pC?gZ?Ty}?Mo???O~?"?p>8>(1??D.?-?f?QP???R}R?> X>L>=hx>hW>y?K?B >>+>z?v>V>J?>? ?->|>~>B>唴>>t ]>]?$s>>>)I>i ?1S?fj?\~>z>)&>RyM>t? O>zh?_d?@>̗{>G ?f? ]d>>&>"><1?>1>T> +O=>pB>g??:i>,ť>"I>6>FM^>uP>Z>2">?5u?Q)?O>-~?% +?7#U>???mz?eJf?9?Ei?j$"?#=&?#R?O>C? ~? 4>$=ٔ=N=XJ&>u>> +g>~>?9>t?a?/7>2>v?#ۨ?<6?0?,-?H??K(>=>d>#>Ec?8?X?>>5@*>A? T)?R?"2??l)?A?Z?!>T->?= +>+>=Ym>j<>o>7 >(u>ާ&>Ę,? >?2t>>b? ?(?( ?Vd?.[L>͇?5H]?>2y>ʈ?I? > H> >iϾ>>R'>8>O>U>?.?p?=-p?>݇K>R>S>>t>~>?0?WH> >޹?)?>W?H? ?MD?J?4??D?k/?z?? ?I=#=Բ>l>2]>_>@D>l>,>_K?"?1>>8>ln ?t>,?~?X?B?/6?5?>:T>ţ>=>N>?;*?%>o?D?HO?4j?FJ>1?v?#_O?:?*>'.>>2>>p>2?.|>=w>u?H2?sO??L?ch>>ȶ>?`B??#'.?Q?2?CS?_?OY?,E>B?&?Y?Z|?L>F>?+2>u>ik2?$o?~?CP>B?ֈ>_>U?5l2>{9>l ?>x>?#>h>(@>L>>>(>ݗ>u?$?,>Xd>͛?:F?[?)>$?&?>?7A?Av>^>2>J>a3>>|?PZ?Lt?2?B?Z!?d>|$??^X?>Z? b>> ?A?Y?M?\?B4?3t?b@?f~?5D>K>?2?j;?>g?>Р>i?z?&H??v? o?OH>>9?&D?*?1W?m]?,ӆ? :>>? +>e>p?]>;>@?Г>¸>݋5? ?7!?R?)?7?>K>KV>>?3?F]>>|???>>h>N>ь?]?e0?J>@>ig?l&$?`<>Է?7"?P?M,p? -? +ہ?/b?X\?er?F@>>@N>?'>_`>Lh?EF??$?!>3<> ? 7 >ٹ?/">O>?&8x>>KI>҆a?8߽?W?(@>I>8>8j?."p>ht>?!u>Z??{Ӿ?iu?lV? +?S?!%>>Nm>"?M#?IT?x?].u?)?n> >???(?.>~Z2=&> X?$;?T?($d?m>D>>?.A?>?3>>t>?3?>?(? n?D?kN? i>y$>l?[@? +? ?h!? 3>$,>%T>B> >>?>k?"r>˾>N?L?bT?OK?0>A>ZC>ї>$w>O>Q~ +>M=y= =p >7>v=r>}\>0?3?F? z>*>??'(>,?ڒ?j=G>>6?N{y?t}?P >>ku>f?>?M?'&?ϯ?v>`?)B?? E?+G??ES???>5?? I?%?]'H?Su?H;??^?>'> ?4g=?9>ס0>>=@>?>1>H>s?'C?>><>7?@W?c# ? c>>" ?:>l?F?_ +?S.>v?@>Ɉ>J>B?l~?><&?#N?W?CF>й>F?^?>L-B>2>x ?;z?g%?G?1? > +O>%>}>C6^>#K>K?MG?Zw?]?D? ?2? Z>? x?Z=w>)u>??H>><6>O>>?0V?[ ?;??&?0>=1>?78>>?>@ҩ>y$>G>ה>V>d=u>?*V>?/P?7A`>>#>>L>fh>^>55>q#>>ғ>̗?6b?}?]X>ƙ8>\~?4?}?4?8?ad?=>7?)C? {>~?39>>Ƌ?>2? ?%>Ix> ?q:?*??9xk>?*? +?6;?? j^?^?,x!?*Gr?>oN>>9>ߍ?N>~>|*?6>>k'>!4?9=L^>ыo>>~?T>>v?JW?,??Z0?*@??4Z?T>D>Ь?>??N>@>W?'>儾>$ ??R%?B?S>>p?U>8>7?.J?>'>CY>R>>>>[?1 +?> >=8>pȶ>+?@Z>>q??TR>e^>ۓ>h>r&>[HS>nF>粱>$>1Q>ٞ>+>/5> ?^nR?4L>>u?^?in?\?>5?>pN>?7?U> +??_>_>4?WC??פ?,4(?/.O?g?>_?4G?!g>I;@?X>ݍ>㢍? >V"?)>>d>>g?TT>ơ?'?B>>/1*> +>>IA>>h>CT>[?56?A?D>0>N>S">ߵP>~>o >xq>Ӄ>j>>>;_>w ?1>AR>(>pp>=Nf>'B> c>엮>r>L=:>W>v>0`>>?sW?Qu?M.?_ ?(,?>f>>p?3?B>m?]j?,H?+z?!t>?@j?Ŏ?>A>ݓP?A>[>}P>?a>Ew?%p>Y>D>,?[?>q>>->߀>Q>.GQ>i^ >0>o>t?-?>?0>9>%Sz>>!f?e>^|?y8?6$Q?>?SE?mW>>Q?b?-?>,>(0>H>mJl=_?C?lV?U>>̝?]?A^?C?N>>/?5?+.???%}>o?*\>u>%>=B?p?x??dP?Dp?B?L?&>N?G9^?K>s>R?S?;:?zG>n>{ ?f?>`.?'@;?Ƿ?cv>a?U?F}>>`\?>?PyL>=J>0q>޲?AG8?H>?C8?iNZ?ar??E?|?*j?QV?>>?[.>>r?()?V?$>=tn>}.>`> ZV>6?I>>N? 2>Ŀ>? J?(?U2?Rք>Sh>ݏ?#[B>8?b?Kf?"?(?V#?L?:s? 0? TZ>>>>zC>6="??m?.|?1?c/?"+?602?$>[?K?d?-?u>?\?q> >œ>=nZ??p>_?V? +]f>$>WT>|>/>G>ag>?<9?>">?>?i=?-?>?7h?~|?o?U?N>?h)?f,>=,W>?eD?5?3o>U>EB>^>'=T??6? +3? >"n>3I?r?;=>~?w*0?/,\>??:"n?1w?$?+>ա>|a8??5"j?'^>i??UX>>>Ҽ>tN>>f<.>i?? >ٮ=>o? ,>l>?$?[|?q>9q= >/? ?]m?r#?>/n>>?!-?P?%?@??H?ϥ??J>?T]K?@y<>x?*ID?ϖ?"?uO;?(Ѻ>F>>xR>z.?\?Cj>I>(>"x>>~>8 ?,ť?>1@>ux=f?r?*>>X?N?X?N>r>>Q>W?w]>]>s?E Y?#5?|?@j??;ұ? >q?g?>j?-8>+>0>?RC?R/?-JB>0L>{Z?F? 8>QR>?Ip?\?$s?&?>?e0?=>f?kv?=.>V?!?@:?Nf?l?Tx?>O?XF?w>? >>??H? +c>>?X(>ҵz>m>ɟJ>>ᥙ>rM? >@`>3=f!k>ϊ?Fc~>r>?>>ޜ(?2>6>R>h>>h?G{?5? '>ۍ?;?H>?B?2??*"?!2>l>ݭ?^>ۈ? r?Eh? +27=T>G>?F?>si>V>kn>?9?3?? +? +>vV>?Zv>@? +?qg?s>ɡ?9լ?>+?-f?H8?7?ex?_4?->?$?l=wR>>N>?e? +2<9=7>#?PZ>>j> +??u>x>3$?V?>F?@Np?P?s?:^?8d?>ŧp>>k>>>Y>p??7=|>>>?>=?6?E=Դ?u?|ø?s?.>O>}6??R?K>ݗ??By>֡> ?P?B>> ?-u>Ӭ>>^>O,>}"? 3>z>ب>Mj>8???X&>6>۴=?;V~?H?>n> +>4s?I?=u>[F?b>>m?>d?v?$>?e`>a.>V]>?/???">(?-v?P?{?+?LR>~>>AH> x>ۚz>r>?j/>>6>WO>>T>a>O>{>N:?C?Yq>4>?T>ƭ?`?%F>>1?%T6?V?+%>u,?3ھ?O? +ν>b>X>?,0?=NF> T><>I>2>Յ+>6?.?>w?^" >,=΋>5?^v(?M4:?>?J:?j??5P>||> ? n?ʌ>a@>{?0w?+>^? ?)>a>^>$>TV>վ?@C?U?-h>C +??Xv?!͙>@C>(? ?*^>mm>] >f>v>rd>i0>,">>Ϭ?>r>>N<>x>T>Jh?3?#>[==?R?gU?/b>?>}?4e?%Xr?'??&?\?(? ļ==.n>3?QP?)?>6?IK?Gƞ>?*?\>'f>d???E?E?ft? ʐ?oU?Rf>0>#8>a?>)>ٷ?+|?&?&>??>?e?S?R{?R>cj>>tB>Z>pB>ˬ?=;?>r( >R??56>>'(O>W>?%6?R>??M?3?,?(d>>g>>TE>?Z'?`q?1l*?@>>>eW>z>kn>>*> >u.??US~?p?9?1VV?'x>?C>?x>9>?+?(>N=ݏ>F>θ= 6>Y}>|R??5!>>>/>؈y?"?>?~P?=x??a;?^"??2? i>"4[=>QH?<>T>@?2>x=->?,E?> >(\t>?'?F?BA>t>:>? +?.g? !*?>s>Y?>?Bk>眺>.o<>9?!>Ƞ>?/ +?7r?,*?Cm?F)D?H?Md>i>yy?"`?PA?=>r?;L>f>>?%4>f>>2?14?:>Z?D?#K??F> 0>ܧ?1w?>O6>>8 >-'=֑g>/G>t??!6>;>qF>rF?D?^,?BN8? R>d?Rc?8>Lb>?,>ݕz>>޵>ZE? U? ?,&>>}?>K?^g ?c@?I?.3D?]?>-?>6?FUD?t>_>2?>>faX>.=0>>ޚ>C4 >>Ɛ>5[?!e>=Uu>0?/~?L??Vy?@?:?ߞ>xj>k?&X>>>t@>8+? ? >>;?6>?:?>ǣ? +Z?)???(>.>>З>>K? >>th? ?&>^>Tl>T>ؚF>|5>M>>>%I>;>Oi>f?#?>nl?B1j?O>%V??>?< b?3?#>oߞ>>??g?X>L?>>E>Q?$?>~?Atf?F0A>K>>)>? D?6>:z>a?9т?Rծ?y?;?2D?]g?P>IN>G??/1?U>|>v> ?-?/>}>?Kn +>? +p?yl?XI>D>?QK?4?:>C>j?Jx?G~?&>ʙ>j????'V?i:?3|?'?"#?/Y?lv>z>0?/8>?>>c?V?kє?\h>G:>r? O?c/>n>>$>tL?7>IJ??9>h? +J?P?7??2?H ?\?*?Q?1?_?Ni>l=>S:>;+?k!"?b>0?~?>9>!J? >>ߕ>r>V?U?2,> +6>->l&>E_ >psv>^n? %? ?&>=>@>v>#>ܦ>Q?%>,?4>?."{>׌@>p?%r>N?&?j2? +X>چK?_?[? l?aZ?\W?JH>ɒ>+Z>y>H>?<.?>=>$ ?Q?>gL>LQ>9>Q>(f?8ۚ?+?_?1F(>3?6ڀ>Sb?y?I]?$(>z>PH>`>?0H?>@U>z>H>E(>Ml>J>=?&>A>m>G&??!6H>>cW>S?&i>z?/?X?sXx>qL>.?1>??=>l?Gs?&&>>>>*Z?|? +?v?nMn?3V>*">Tc>#/??_>h>1??>>f>1>>S>v?!?j>qY?64?0R?>șf>.?F[&?k&?(?.> >^D? ?X?\?@?'>WX>G>W>? +d>>>˩{>xB?a>>ZP?CL? ,;??#?H >?,v?]ٔ?=?x?5L?->7??`?#e6?*!??GE?F >?A?Hj>g&>>>x>2=3v >(>x? ?p>1_>~B?-g>?N?/l>9,>ό(>{>F>l>=_>~?$t?'>?\?>"J? >?5m?Ot?0?yL?x>r>>,?7,>0L=(]>?[>~A?3C?|<>1>L?>Z>Z?d>>o P>.?9>]=VT> (?G?HB>=Ҩ>W9>g(>S>~;?m?s>.>.??H(>*>ּ?5?Yb?K)4?i>\?A?.>D>??>>rO>.? .?4%>Qd? a?R0 +?V8?d9d?>F>#y>m]>G>_>?T6?f?T?s>=d?EP>{>z?J1?&?Q?LdZ>?>??eC?F>eP?V.?)n> ?k?$>ϮA>?Z??? >>o>Ar>>~I?>>?0UR?G?!J> >]?C>3>Z>3>?2?F<>>e*>\A>u>>?CEh?%/>Gl?J$?Sv? 1?5?0a>'>X=¼>$x?OB ?^ʜ?S>+?*?q0?6?Qd> >xL$?>??J>W>e???*? +"S=>̤?Ԉ?->@>M >NX>X>1n>n>^>i>?r>?\?tt>?#'?pGb?zF?Z"?BO?.?pz>Gn>>Ҍ>>2=~q=n>h?b?f>-=?>U >Xj>@?^>j>~T6?" ?G'>($>ֶ>8?Q?1?d?,>?'Q&?R?^N2?2b?"?o ?I>8@>8>*4>T>W?>ֲ>?>y>O?-->&$?Y??1(?^>{> >D>wd>?A?ohD?I!>>">p>Х>U>,?~?,|?1gD?>L=>~>-Y=j=m5=q>>>?&}?Q? ">b,>V?Ic?({?)?9o2>>ݹ?@y>9??+l> ? ?F:@>>}?ْ??6?Sα>*=>%???& ?;e?C?p\?:>](> >D?-L??:?)t>|?">:>:>T?>ʹ>??1g ?,?k?/~>۪?J?D>[>?>==|.??q?s +D?2+>Q>Uk?'<>ҭ>>i> G??R6?5n?O??>ce>D?K>?1!?Vz?QH>>w?&j4?]`?j?>R?'e>)>`>>HT?)?Y?c>?h?e>y?k[?+R>у> >?'5>V>G?8j>z}=̲?H?aE?d?8?>D>\>t?F? Z>?F>B\>4@>i>ԙ>=?(? ? +#>e-? +?Ba6??$Z?9??!/>>ʪ??MT?9F?'(?miy?ej?Ɣ>ĉ?&>>[?6"b>>=?>L??H??>J(>/?[$u?'b?,a?{>>>~J? +b{?\?> ~?>>sY>_=9>>??!>> N?+?hN?*>>>v0>C|N>??? ?)Y?GS7?'/?;?T?U?g&?z,?G;?'Ɉ>>? A>?X?N >s>?Bp?l,|?p?Q?1>#>{M??>> >>.>O?N?Ze?2?;>\>w=j?> =? +?e?*?h>ᶪ>??5]?E6@>`??c?y?2z?0? p>I?}V?KW?z&?f0!>M>:>$>&?Ң?OT?"b>b?N?U??C?k>H]>L?M>?">>>9V>?v +?3Q>?`?q>>1?0?@7"?;>J>ǘ?(rH>2=>$?2>ݘ=V>>$}>|;>>? 5n?nC?*&>?t?*>?M]>=+> Z>SW=t??G^>?!S>,>? >8>*FT=p?~2?%">)>֠>'>$>> ec>\>`*n>F>j>>^J??>*?+?O?<">"K??f\"?XW +?HD>>{.>7=ӽ=>>s>v?h?M??! +?.?%>?@e?R?.R?U?/m=y>SR]?l?r?!r?3n?Δ>_=4?:B>>K>=E>e+>>?3\?G[?P +?>Z?4Z?7 ?>n>Je?(T?>G>>Sf>h=`>F+.>]>>4!>z>P?z?1~>F?_M???)">]|>p >8?Yx?;o?,^?P>z8>>v>R>f>k2>?X?,a>0= >O??4?J=?: 6?F?c?U?)L?4p?]=\>??9d9?Ca?1?">x>r?08>??W>g(=i>$?>0l>G0=0>?n >7o? '4?A>> >?"O?"l?.>>>Ш[>$tI>? 7>ؑ?N<> ><>W>U>>>?er?u?1?<>? d>&e>Xo>!D>m?B?n*?j?v?1a???aF>>?P?8?d?S?Y?PҨ?~>>Joy>e&>?H>>Z?(> +?>> +?: >>B^> +=>c?:H^? ><>X?#+>:?\j?>#h=3>>|">>"U=? '?}?q?\G@>>r?>EҘ=x=>>>?a|?:? (V?ET?C?d?F?l>3>>ϫ ?KN?>>w>п>w,>? z>>P? 9>>P?%?_?Ec?"?1=? +|F?=? >x>o>08?%?K?Wp?yd?u?R(>;T>p3??JL>>>Y`> +>W>Wp??LD?6N?Hs>%^=?e> `>v>?B?ò>O>֕?Qw?=}\)>>q>d`>y >N>G?|?:l?=.=n>?B>>>m>ֹ?+>p=$c~=Z>0?: >+j>ql>? ?@>v?I?,2?U?9b?Q?50>:G>a?Sb?ts>>5>O +~>c??>ľ?w?"`=z>>6??V2?@?n?7 +>&>9 +>"?v>>>? ^?:S?5f?+7m?>V?AW?4AZ>>?/׹>ރ>I>\ `? +{S?=?X>>Ng?'8>ܞ>?2>f_??$>]!>{}? 4?4h? M?BB?@?]?H7?˷? ??]<?A?LmL?&It? ?Hj?4u?U?V\?M\???>?A?V?*x>Ɓ??7>+>9r>H>1c>=>?nJ^?%?)խ?r?> >^?Զ??%>y:>^=>H>c?Lm?>>Q>%(>ׁ?F>>2}??,R?'>=7?z?$̮>>Y>?>ܷ>->5>>)>֫o?? 0?*p?l1?;>.t?1^?2??0>F>؍^?E??^?@ m? X\>>&>ޠ>>> n>A?t?>۵? )~?0 >A?u??="? >@>ی>*>>۫?6>5<>E>T?Fv?i>0>L]>É? ?S?3C>D>W? S?P ?g0>>l? (?j>:>Nj??jz?E?@%?6?'O>=}==>=D?ZX?FjT?$r?/)>?:Z?Q?pe+?6>???A?H]?E`?D^?BZ?>[9?5V>">>\=I>9Z>U?* ?E>??l>8V?"<>ӪZ?#$?BP?0?(a> =h>٣=>>>[l>:? X?8?)=>>RQ>8>??[>!???>9r?~? >X>͘~>/?Կ?-Q?3?$>N>y>>'==ƼL>?6?vP>>t>5>߼=m>w?Vd?*?Rc>6>@?Rl>Z>B?[%?X"?\3?g9T?>E>6>R"=LP>ɀ?c?8kf?1>b>>?>>8=6??->>?#?a?[6?>q>?#? v>>-?V>i>:h?9)D?I^">Ӓ>2d>h>t?Veb?Ex>r2>?-?.F?H?Ax>>&>ӣ?4??;V?L|p> >??>N>"??8}?^?eW'?m_Z?G??D>>@?:?SEF?#Y>N=A?f?d:?s(?V?{a?aH?0*f>д>Q>Hg>===2>'?62?F? >*>y?%?>>b?V? >J?a>:?L>'U>u|?$*??E?G ?Gx>>fOt>t>>>D?[O?,#^?o?O}0?>r??%m?>F>F>>t><>?>2#>ǯ>T>Y><=>EM?1xb?'\>>|>?5?:,?>N>MH>>?U?Ie?+ >ҡ[>rg>1^?0 >?O >ҧ>#>#?*,>:>I |?W"?>Ϊ=T=̓>>>>2?:P>q74>h?[{>j +>H7>=>?L> +3>?>y>Ԣ?^)?8>^=a(>?U +?D0=>(?.:?<5>>>>>(t?$Er>0z>$t>>>| >fH? >Z>?l?/?>o>@>n=|~=Q= >? A?0ʘ?Rg>|s>-)>ef>z>K\?!>>άj?<]?r?$P>O-=|>>>f? 9e?,w>N=<>\>i?)y?,>1t>>5>#}(>}6>>L>yO?^Q?$d>-=h=.>L$?W?&ʿ>?(4?^?'?Z? >*>N?.^>>2??1? 7>>S>d? 9>v=*=>??h?>I-=~=>V^>?C>G>?5?>d>>vn?C>>?0-g?Z>7>u>V?>nl?s\?=s>m?c?4>Ē>4?2u?`v?>?B"?o3>>">??N@?|=Y>#~?o1?g?:~?b>C>o?#??a>y >> >Ő>>B??+;?O^?_?HL?2??G?0Ql?TL?+? ;?^?x0?Z>Hz:>X>??-ZH>>떀>,.>Ⱦ?s6?3>z>8>\??2(?4%0?Q[?\i?S>~>g?(Ӳ? \?0r?ZD??7g?)cw?2??"g?J>&>>?R֦?x 2>>d!? >>?>i>/O=;|=k>? >n>r{m>??^?=>j>Τ&??3*?>5?>I>:3>>I>->ߝ???IC`?x>Ƚ>v>#?--?;$?$?R?>3$?Hr,?t>6>->,<>>υ? >>>Թ'?%>>j> k??7&A??F?s@?,>l>w~>C='I0>v>-&?z>`T>o?,E>??I?D.?j?g7/?P?)?a?I3?b&>(?p>>O>+0>6>->6.>V?$><>oM>?x?J>i??gy?6 >(>PG? N? +n> =(H>W>?%|? +B>ZC}> c>r{6?~?x?b(?R^? +>)r>/Z>?d?:zG?4>>?B}?Q>??>Ԝ>$:>)>>$?f?)?(>ì? R?H^>??EZ?Lk?8d"??A>Ո?!|>>??>!? ~?A-?y?"?>P?>V(>f>/?">>?.>8>,??N?6c>R>>0>? Q*>xb>L*?-?h?!t>J>a&> +???>Nz>^?&?$>?(e?>K{?2?'϶?fZ??1F>}i>?2? w>Ԭ?CX?@]>n>~> >)f>H>sc>I??j>\>>mx?N? P?fe?.c>(>[>D<>XR?F.?sm?>3p>??@-.? +>>c>?յ?P?e?E&?R>M>CA>?XN>.">0>c?4?>p[>??qv?P>嗟=W=s:=`>+_?6?>48>H>g0>>? &?L??!?[;?wV?K!?l>]%>*>(??)?S(?,>Zj> >/>U>·>2?I?ZKl?)>4? +V>^>à?h>r??Q*?RJ?n??5?M?=\?>Z?7?I ?4,?= 6>=X>6>b???@>i??'?H"H>O>u>?4?w>">{1=?}?C>M>5X>ntZ??D)>>?_ +?s6d?s>=0?%jq>S? \К?)?4H???A2?/^>zk>?#>>l ?+o?^?W?0>߇>>0?c>>L>]>? XN?'X?ĺ?*?*([>'>D?.>l>>}V?>R? H?1>V>'>) ?$C?`?Z,?NO?\>#?6?9?)*?D?Wɘ?F?I>S2?&~ +?'6?6N>>E?A?8y?h>#?:+?[p?|J?5$>?%S?x?l?[$?^F?3??2~?9?)z>U>۾F?+Y>{>F?>?>>R'?'K=??؈>>D?bL{?k?q!? >|?R(?]>:=?$Y$?c??f=>,>1$o>EA>}2>Zż>?YC>h>>ZD?|>.>Á?Gg?S'8?=~U,>׌:?/>QY>Z =B>?>>=ԛK=-2>>?"7?! +>*]>~,>2>? +R>wu=O >YP?+Z?J?>=P>泟? ??9L?B?p?@? V>:?/?,4d?bP?Ү>1?G? >?)??$n?:?`Q?`>?T>?j?*?F ?o>>?W=Z>;?I<8?W>x?? v?,?#q? ?2?T$?Q?3?!>h>椠0>T??br ?PQ?v>*?3e?@ ? n?F>|~>?:>P>B>*?eH>9>ƥ~?G?*J>ǖ> ?(?0>V>}?*>^]?4? +>}>…>??"`r>Ba>>F>?;D?VQX?>??n?_=$?H|?&X#?Z%>?/r?W+>آ>>*9>TL>>8>1D>V?:?C0? +D7>,>ёl>.>2,>?2+? >P>,>?5]?^T? 9?4?Eݖ?CKW? +.p>N>՞?`q>>~ao>U<٤<\[?j?>s?x>{L>v(?/hp?1>Wb>(>\>?n?Z\?$ZT>>ݯ >>A>T>9? ?=M0>"[?4T?5'J?H#?U4>"=>?&O?3D?YJ?'O&? +T?/>> =# +=1>Rl>=>?+?)>? +?S\>>>l]> e>J>F>a?od>Ny??!>?ݔ?,J?0!?Q@? {>>τI>y)?m?0?$>D$>Ԥ?/;?ݾ>B>Y=d=ן>?o?s?W?R$?EH>>>>>>p+>3>h? +??>~=J>>o>N?L<>n> ?!+?Qr?=nD?DB?6[>>`rY>G>>x>h?*> +1?>>"?+{l>>m?,>Ur=7>?V4?)>>$? A)>֘? +?1"?Q?%,F??.>y> ?N?Y?#>}->;6>!?m>?;YR?z6?z0?>I0>w>w >?5>?O>j>ܐ?A!? >=>? A?5?!Tp?F?16>+>u>iF>*?0?0><= >vE?v>? L?Z̪? \h>Y?>.?A>=>#&?,]?Gʈ?:ŕ?Y>p?X +$? >s>/0S>x>}??6?>ޕ?g>8?, ?+Z?=?>?Qӣ? >a>D?!˨?O>P>V> ?6?J>w>>>t?1?"/?6?ކ?? +>? 4? ?>n?Ӧ?rl>>.>x?6>#Z>>ܺ=;>o?->\>>F? ?$`U?>ζ$>&? L|? ?e?HV>>!==[ȃ>3">\?.>=>>>N?C$ +?q?>>.?Q ? +h>4>܀?*?yV?KG>">>>0>c?&W?.K??Oz?>xR>?>Wv@>v?H$?<>՞>V9h>?$?GZ?UY>v>c>ト>e>o=2>n>YW>4~>\ >1>? ?d?>gR?!?B>Rx>9>W

c?s??ތ?2ox??z>1>>sE|>{G?_`>L> + ?4Tn? ? SB>>>1<">z>ӫ?#?G?v>>f? (1>>4?,>??>? "?TX?J>D>ڦ>BJ>k?|>>v??%"m>8>fO>>0>ְ?4j>9=>?)>pk>)>N>n>%>!J>??E1>,>d#?D?b?Q a?]A'?JD?>7? ??]>>?ţ?&1C?<>=+{>L?" +>P=*>>r> +>0rt>\>p`=>Բ>>?>b>Z>)>&>>l=k>?|??_2t? (>>e?>>y? +?<(?`L +?%?'?[]?]I?K?E>>f`q?4?>r?AS?Ko?- d?7צ?OR}?>.?B#/?C?Y>ҫ>>I?0>>_==}>z?'R? BO>a?>B?\?1r8?<<>v=i>>J?p?>6=&?*?F?;>> ?4,?6>? ?8O=>1?B?*1p>{>%)q>E>x>>_>>2>>2>\>?0? +ɧ>>F>>|:?ڈ?Y}?})?@@>?=2?\M>$>>t">Rh>>a?B ?k2?j?``?">{>K?0?Y<Ê>o\ +?-?!r0?%6?N?(A?(>?!Y?;~?>I>P?Q?>>Z>? >?l?*>ֽ?P?90>Ҫ>?>U.>(>݈;=֤>TP?v?-A? >A4?.??.s?% y?e?k ?J?>>#x??`?^D>4>Az>܅>i=>7~?z>.? 0???9?4IJ?& +>%>>G0>x?>h>'>>Ԯ?p? :>Ls>?)2?<>kf?$d:>=J??0|V?r?R?b8?P?t?~.?`>&|>I?>Y>1?>>tP?W>32>;>>S>?A?M?n??>">n">?=> ??f?s?l?bB?>??iOh?6?':>j +=Ӫ>H|c>:@>>k!= =L>dnp>8>j>4Z>>S?=5?_Pl?D4?x>>l>k? !?H?Ov>g>?=>@=>V>\>??:> >K>>.>0:>>d?>(=}>?c?l$? \>͒=??S?<>俪?o?<>?7>?(?8c? +>`{>)y'>?b>ԧ?=?> Y? >"?lY?9?35?3>v>jW?F.?>o1?2?+ ?B==z>2>S>???Yd? +? ?WiC?U?$F? R?x?l?m?]1>1? ? ^>?(>>?qeA?qr?g ?5{>>U6=OƂ>? 9>U>?5?-QF? >Vv?56?>yz?w? >(?`? >*{?J @? Z[??u?8Y=?#Gl?8 >H>k[?=*?5> >>F>px>?..>? E>??N??ɒ>>j>ƾ>6?v?O{n?8?=R??y?,+?`?$>ղ>>>W>l>ڌ:?2>>?:?>E>>->)3>E?>">1y?,oW>B>V>>8 =hP3>b>>c>>->60?X>ʁ? Ѿ?m?_=RB=>">%> >q??Rh?_>#V>b>*p>]L?*?H?5?:M?>:?R>c>[?#<>>v>;> >.>(3>hj?!?\ݔ?[?E +n?*R|?D>ē=6>>ۦ>S>>[Y?7?9> +?n?!?1=?n?'>>O?.?n?v?6P??6 ?5~>:=>Y>R> +?CR?7ҕ>v>w>@;? h?Q-?6r#?A&?kq"? ->? ? h>N>80>=x[>>ž!?>y>ӡF?2f?n4?X? N=>6?'6F?'p6??"?t ?94>1>>J>:?JS@?L>ޒ??(,>>?>>c?^??`>阢?l6>'>vH?p?FS>A>b?47,??I?Mg?*z?0?U>?u?B?lX? K=T>>>y?>c>*>=>DcF>c?"BN?B>Q?0?#>?'&?>=>Un>?/?$h?%&l?[?>}2>s>YU*??Q?/!>-Y??QEV>>H>? F?A?4Ք?J>|@>?V>榘>t=įS??u"?8>?V>a?>`>V>;o +>%>Jn>V^>>GC`>?>>'|?Ԓ?" + +?L?G?? +>>?e}>Eh?p? ?Ch?&J?7R>%`>>N1>dz>MN>?Z?q>u?#?5J? +7|?9f?1$>>m +?8>f=>y?0Ӣ?.'?U"C? ??;}>!?$7N>5>x>.>j?(3>+>&>֔>|>?>(?>>=>>Y?#U>F>g_>>b>??&d>E?4?EU(>>ξ??b1?g;T?? ?B)?:>ԗ>+c>Dm?1 a>>n?8>o>$f?Gz?0>>V?/?L7>ي>Jv>(x>H??A?/Y?0?>u> >ï>+">f>j>?>?]#?_]>(>|4>d>^0?"?e^>P>? #G>|?>ȓe>X>?6?*I>L=mK=>C??CԮ?q??\5?kM>>l>?2?:,?\Ib?$. >'?C?`}?"p>Ҥ?R?Pk?{T>?$c?(J>h>X?4>yt&=J>>h?:3?8>?,.T?+\?A?n? %?-&?,h?+>}>^^>>9= +>ih>-3>6D??/c> +>>p>?d@?t2?.B>^iF>?I>g>p+?)->ɮ? iV?Y8>>T3=ב>j>>d>8V? >>J3>Ƨ>X|D>?K]?b>i=uT>l??6? HY?O +?tu?\q?$>pR>>Un>_>sM>u%<d>Q?&>?*?\f?@>nB=I>l0?x>wN?+?%I"?6>L>)?C??6?Y>_]>>6y>Gp?(=?S`\?))#?78?Fd?*?>F>?1g?L?8??8<>8>?87@? ݔ?e(?>扡?5V?A X?>R=>>yA>{|?K? jl>c>>B?`>`>œt>~>,>sq> ?@‚>R>>?S*?Z"? >qk^=H<=4>!0>~>>ؙj?:4?DI?ii?0???_"? U>r >##> ?&Z>*>%p??(dx?,?.T===>ĉ?w?%Q?3T?FJ>H>ʎ?&f?'z>ɋ?&{?g??l?.? |?:"?>?>a>=?h?> >}(>F???.?&?D^?>c>)o<>?!? 8p?G#?Fne?36?7u?,x>_ >>A>Z??:8? *>>9>>Q??(4?>>N&?o>6>y>>Sh>2>B>q?b? C?#h>>>=?,?P>d>fx>`?8 +>>nC>Y +=#H>}6?|?I>D.>뗚>><>>"?5A?`#?f??HZ> +8==]>uj>G>S]?> >w:=P* >p?s ?:2?h? (>i>2_>?/C?:?/?&Z>g >>l>Z>͎>wV>XW>>9=$P=??U|?N(?>>>Y.>a?? *=w>Q?>F>?1? >Ֆ>{ >n? >|>[?U?kZ?=,>Vc?/>>[>8 +?C?V>qv>>N>:?e>?6f +?7?f>@? a?hx?wk?l?"#F>?NH?Mհ?=”O>H>\?ٛ?E?R>ؾ>b> ?Cu?>J>r?N>8F>->lv>,>>,x>?$ +?=>2S0>K> >?Fv>> ?F]>$= +=b>>C +>2>O>>x>2=2>>>p?`-?h>k??B'?x> n>>J>I;?->5>C>P=h`?v?|-? >8]?<?!>g>8?S?Z0>Cs>hT? >??>*?PW>[>'>>łR= >j)b>Ҭ>Z>D>>?)1?-!,>B?7?p"?vD?H><><@>dʽ??l?>c4>I^>r>ڃ??S3?q?RD?%>I,?u>" >>L>? ?&Ӓ? @>>?*>Z?A?CF>Ok>6?T*??(/"?>H>Z>3>Z=.>i1?>$>`>"?F +?2;?f>>7?6A>Ɖ?B?.iK?3?] ?A.?/l?9L?P$*?*?6?@>Z>?>l?>~?b> ?t>7=HI>RQ>p*> V?0?7 +?$?>*?\'?r?,p?!>8>@>?*?T>b>>>>wU>>,?A?0>M> ?0?Ex?"_??OV?-?6n??/l>S==>~-?'3?Gpl?PP?͍>=!>A0>4K>? 0U??(آ?`p?U>$>8>I[(>^?U?&?-h?? >{d>F >ۿF?2?x? :,? >>oz>>h>>}>?q ? ?D?qJ?K>=&>>E?l?aS >K7? ?Mr? X?,? +>T>?f?N?+? $_?+?*>]>ְU?Am?Wɰ>dN>6p?0?+?U1?]B?d'?P?Zv?Ŷ?? K>۠n>{?>1???#> u"H>?>>v&O>FX?"T?<(>j?I?\?!Uh>Kq >]M?^z?f?_? ,?>˺?!>ȅ>ÿ>&??Q>%?#sP?c0?Pl>f!>2h?R?A>>?xw? 2 ? ?/K\>sJ>@B>O?O?z?8 +>?> >X>?)iH?)`>>a?N>}>]>bZ>L.>>#>r@>> ?@?I>"> +>w? >w{<>{q>jZ?(?>b=H>xV>>>ը>P >*>? +"?Xp?K2>}>me?Va?>>%>?!:?u>h?'9?S?T?1P>s>HD>"(>?ގ? +O>.>b>h>?:?m?%>.??'5?3 +P?l>ĉ?r>9>a6:>T>>,J>߹D>~@Z>'?1<>Ÿ>h < >:>k??U?!> +=+V> +? +>N>?n0?J>~>!>΢>?CZH>䲓>Ȏ?%>E=>@m7>spq>>V>(?8?/.?>6>?Q?K>^X>̢>wv=G==٫>h?+Y?B??-?-?&z?`>Id=J/?P>ܤ>E:>m> ^?sj?@ID>+F>Q ??=B>>/>W???h>N,>0>?B°?{K6?\?9s>z>ːD?T?)?[>}==p? ?qY?[gS>q>>6 >r> @>$?|>2^? h>E>KW>r#6>?I?T ?H>>U>#>>}~?"?7 +?US>l? ?"T>> +?-?K(>~>_>|>/==>r2?'>^? ?P#>=怐>?6? )>?[J?>s>g>6?3?G >>{7?W?>>͠o>˒:?A?t?>? ?E;?o?AF?5c6?5 x? +2>? +?b=?[*0?Q?s>"v>p>а>r{>㌐?#?4>D>…>=ȋ>??f?*W>>'r>c>ع?>m?>2>|42?+?mI?">N??j?C>n >>3>ڗ?}??L? #>4X? +?>N|>n>uy>0>é>?D<>H|> >>dJ>El?>ק}> ?Z>->D^>">*S?\|?t0??̖?;>(>T>6b:>ޕ[?>?Q>Ӷ>"?<{2>>|>cz> ?<>d>4?9?P+f>J>ze>j6>ʎ?4>$?eh?n?=>H>f>>ͪ?.h?̚?[s?0>R>7?rN?3y(>w?? +?Ft?!e?Pz?!;Z>E>?H"?)=b>(?, ?P??c?>?:`>'>s=>C?]>qF?a>ܞ7;M>8>>g>?#? `?3>b>Ɲ??&,?E>?">???, >Sk+>|>k>?ZR?kf?F?\(,?&3>ě??۱?@?5q? +>ڧ2?(R>9>A>L>:??>?6?+>p?A?\'?_?X<|?E?H0?%??'>x?>?B"?'H>Ž?"Q?* >L??C>=%Y>k??;>>cX>*? +?6S?.d?hXD?BH?>A>#?Bk?(>=?x?bw?Tf?5>3e>s?e?7 >?B?#pb?3?#x>^??̦?9@B>?0?4? B>=R)? 2?R>N>|,>|$ >M>?3?8~?|>?8~N?W?8n> <>? 0?c?X2>>?c1 ?4>>>?Uf?ek?>>W?p?@0V?>h>>iM=>">U>H?>>T?x>?`>o??Jr>ˤ8> C> >sV>?A? c>W>>?O +F?dl?\?->~(>@V>H>Ӯ>>`?3?~???k?VY?w?J>>q>D>h?J*?[>j>2>̛X?+?p?2?t?G>$>t?E?T?<>[??C^>$>Sh? {|>>Y? ?>??"Y?>x>1?#?@0f?i>(=s i>G.?j4?Q?62?]x?=E=x?>M?F?r>~C>8f? 5?}?d?n.>B>9X?Æ?K>1=J>?u ?BV>Œ?*?=˹>J>m>q =>3Т>Y?E~?m $>ݢ>F>Q>?Kx@>~F>;?4R>σ:??j >+?>1>h>Sf>??6-#??>7,?X?z?w>ʭ?LZ>A>vZ?*l?8ż? ?L>X=g?b?y0?6M>eJ=7">v?&?[>>?˻>M>:uId>\>>a!?/(>k&=}>2?`l??">ʠ8?/?:8>C>q:>c><>mb?(tJ?RD?Z>X>=R=lM>`>p>>R>Q[i>} ?2t?!>]? ?[/?P>>퀚?3?6?@ v?jn>G=??) >24>!b(? q?P^>Ox>{>R>[>{??.>>?5 +?Nx?`>>> > z?F?8?P?=W?2>?" ?D?f?bV?.~??6?P>Ї? ?WK>T?H3?Ĝ>Q|?>$=K?J??%|?g?=v#>ra>u>>$h>g,? +>&=K>?+> ??i ?>?(:?ھ?4> >>)>M?)z>x@>kC>㥪?L>[0y?S??"?D==-=5>z=r>Gʼ>s>H?&O?'l?? +?pJ?+n><>?d>?UA?$TP> =F=>&)>ӄ?B-N>U >U>х? N?@P>Q\>r?>J?X?G?7PO?E?AFT?X>?z>\?;?f >ڳ=X>?J>{> + >D? n> >֩T?Z-?b\>x?2?N?$??*T>ʗ=\>=F>֡}>I> ?I?4?M@?L:???j|{?S?>r>2?Ѱ>>G?(?"&>{<>?:>N>z>ނ?)q>(>???5?5f>>>^b>m0>r>uF9>R&>>&?Y\>ܜh=t>Y>:>~bG>^>c>?>C>M>kJ>i=p;>&>E>ޠ? kT>.>?[>@? ?=l?u8?{uH?x? 9f?">>\?? r^>>=,>?X?5~?`> >~Q?E>2(g>PF>>c>=OQ>_O?\?>`h0>.j?gn?``? +?dl?v?>?@{?"==l??2Z>*>`>?-B>>e?!? +^>Ԅ?K?e>疡>?/?>ޢ|>ٵ>> >8>$X_=,>>>&?@B~?4 ?>>ͧh??k?6>?5>ͯ>:>I?A??w?>=Ng;>sR?6a?t{A? D>#j >ގ?$?P|?_Ԣ?/>]?S? =>H>? ?]? >oy>??Rh ?nC?Xl?8>&? p?! >͖?%Y?V?]>T>6?Gt[?T?j? 3>[|=$>4>S<>Bth>W<>h>=2>?&.C?L81>ـ?)G?>?>Uz>G7?Mbz?M>L=\>)8??m`"?9f? n>͔>z"?>f?#R>n>\?-? = o>?>?)?% >n>i>T> +?@.>Uܱ> ?73??Cw>o>q?-?N? <>?1?>Yv?(J>>@?3|?H4>>g\2>q? U!?jV?L>X}> >3N>aT>>R)>@? >Q_>?@&> +=Ü0>|?SSn?N?h>a> !a>->CxV>> >>\n?$?)&?T>2>87?CH?50? l> >>K>0Y>ܩ>?A^?`?T>@>0d>Ѻ?'Ih>wN?? .?#>>̉?'>K?? +9'>UB?"۸>?0?gW(?\{n? \>?g>i>\ ?!?96?]>&>6=j=@=>⮝?D>{>->4>J?/l>=4? >R>JQ?F;>V>k4>2>M0>.??MD?/z?;0?~K>RP>W??>D[>}*>]>f%>Ӟ>?"e?9t? Po>*>H?x0:?6>n>ǜ>`1>7>]?>?%>n>?0>>b?@?>K}? |R?W? ?(?I?ۑ>>>@=I>?#z?\%?UJ?>Q>kP?8O ?t?8>1>޸?hS?X?Y?,>>? >^I>X>x{>?4b>x>4?Dݷ?R>9a>Ma=>̰?8h?I=>ݗ?k߲?!=>z>,>]? ?X>><$?, ? >z>X>A|>k{=@>T>i>p>Y0>>ޢ>^>5?>u>XC>p>?>i>FP?8ר>3>T>>=u,>>?>=`>>|>J>\?V؆>mt>>׸>֕?'*?KQ>>>0?>^? =5=>ԧ>o=>=>֭6>>_ +>VF??f?-r>q? ?>.>0??=8>{N?8.?8?>j$>ou>~h>l?P?A`V>{>H>]>0e?0V>[T>|?/f>>z>#T>Mn=|Q>x?i"?*b>2>?4H?b_U?nW?>DN>ր>$>'>H>?Cj?p ? <>>?C8>?.>>=>?~?xlu?~^>\->Lx??>>?Y?>~>YT?$ژ>>?4T>G=>T>u>>V=>)?{>b>!>f?3VZ?+>? +?Bu>y"?#_?M#?>=s>?>> =1>??DV?i0?6??$>>t>+!=[? $?K>a9>r?G?q?>>xz>ή>¬?,>a>lht?} ?%6>F>D??|?X>_Z>ѷ?x>>_{>>ެ>h?5L>>+֮?&=?=ǜ?(?p$>4>(?`?z?8 ??/>5>"?$?U>o=٨T>?*\?k???/(>U5r>{Z?\\?|=[>@c??NT?I>~?z?;>>'>S>ź?z?Jf?0?M?]>6=GW=>z?mu?f?H>y>H8>P>{-?0$?3B>)>Oj>#>t>>($> >7>>,>=z?[f?$>?,>>d?+ct>2>>J>>?$@?Z~Z>=L>)2>O>G??FH?B?e>/6?s-?C?#? J?Lv>?>b?&٪?$R??o?->%>>>6>nG>C?? +V>;?>>q?P?,4d>(>O?|?\r?>F +>> >>Ͷ>>H=>CL>5L>>بX>t>;r??9>n>,>!?(`>Ǥ>?:->$>Ϗ?(?-V> >=9>?0?i|?gnl?H>З>x!?x>և4?K? <>>>|>v?n^?)> >7?;^=>'>&>?NZ>?I6>>KS?%?/Y?5?c?[_z>xxѨ>$>z?'?6jR?>d?B.?'?a>b>?r?>>>>>?>>e?p>G??M? >M>KXh=E>l@>7?i?C>l>B? ?Z&?1+>>?P?O?<?]? ̚?j3?W:>>;>!>>>;? A?<>߀r>?:8?,?!>X?X?He>p?6?I?y>~>(>Ӣ?>ߕ=>)>4>w>`u>>WK>?M?$v>A>?Fhf?4V:?">g*>bo?)-=?Ed>Ph>]>x>VZ??UV?/%?? v?1#b?>?1ֈ>?a&? +}>Z?"?B>>}X>>],>.?X?D?@D3?>?!2>Қ? +F?.?"|?)?>z?=?#>> j(>?-T?E ?-?<>@jx>^qR?>?Q;?' +>z?=?դ?qZ>9>Eh?>? ?$?>qE>?71?R>6>,?Nf4?t?3 >y>??%l?.?Ov?9?N-?;>m"? +*>¬>>? ?=x? +!>/.?Ɔ>@>B>??O3?*? ?>[0? S>h>,>`> +>r>=S?S?|D?ވ>Ӄv>>C?(E8?D{?U]?Z5? ?/??t?BX?lvScD>?.J>*>=_&>2:? u^?J( ?)>2v?0Ϭ?'nV>2>=?6B>g?9?7>s>>>>L>>V=q|>MB6>_?-?s?C?E\?@>$?@n?&2>?:e>1?)E?=x?v>?&?=$?s?P?K? >sS>>|>^?n??6}>X?.?'??V?hv?1>NVr>R̠??'>O>H?9?Lp>ڍ?c*L?6->ک> 0>?R? > +.>>ы?/ W?Z)z?IF>Vv=ڲ?O?A?$>?w?+>u> >>x?6??5?$?H'6?|h?!p>}?3j?FP?M>d>nJ> >#?3>B>6?\?]>>]>v?!C?%>U>M ^>Ӱ?U<? q?s4?H *>↤>`,>b\>g"=q>?%>Ѱq>+,?ѷ?[z2?C>v> >*>??>P8*>q>>>Qt?!ܨ?a?>Ć??-?Y5?5b>>@$? +?g??h>1xS>>,? @?ARd?R??=?B"?,>BR>'? +?e>U?c?Z:?>BL> +>j>R>}><>>?Δ?>_>P?86?!R>&>u> >Q>>>? ?G?? >??2>ȲR?? $>V>?A?W?z>? ?8O>?? >]>9]>?D>>>>? + ?*?Vج?,>6>> d?x$?[\?)>N\>D>}>?e?&ќ?>>ԴP><>Ǿ>>:l>±m>?_Z?Z?.??;?\ +?!>0>:><2??;h >i>HQ>??Y=s>c>O>Vx->TFl?z2?>Q\>,?V?l=O>)>>|??4?SgY?L>?*v?b(?>g6?!?.n? ?&Y>~>L?]2?}@?"z?3f>W=U>Ff>*>ᝎ>x>0t?_?>w>->>p?5? >bw>>?1?3>F>>2Y?d)?pK>? ?X?:?C?H?DG?>m~>J? f?]>^==9;>}S?"? _? ?j$>b>X?\?>v>>f?#`?`߹?dȂ>??LtH?P@?,>>8>.>?l?#y*?2~>? +<> +>6?;?52>7>>\>Z?Q>&>`K,?9?@8?&G?#>>$%>ط4?:t?f>p>҅?")?!g?+ڃ?M@?X ?^?;%^>*??=8??9?$G"? J>>>?S.?Sz> >&>Y?W>Y>C>{9>?l>q>y>?28?>8>$pt> 0=- >?L? ]d?Az?S ?[}?`? J>7=>T>谆>A?%x?1>[(>=M>>@>g> ? +k?9g?>In>?,>?%=z>>}=^>>Y>W^>->;?ig?C&?(??@>>M6l>fێ>?9%?>Y>E?*X>f>,6? C?.>`^>>>I>??m?&> >>ʃ>֨>޷~?4?>1~?P?Ot?L>i?@%? c1?F? \>~2>m>>{JN?3g?z؂?i>.^{>]W>%r>51> >*>2f>n? :>n? Hd?>>O +>?L3?N]?b>?ٴ?*6?>u>1>>'?$>r>K?=|>9>e??Be"?2/>z?(?*w>ß??2Z?IGO>= h>s??>+>F>??>d>H? ?^S? =>b??) >>*>,G>o{j>Uj?,>Q>l[>>@=>F?Q?ݜ?'?!A?0?B>Q>g??a .>>ؐ?0?0>?IM>?"/>=>? ~>)?>]z>e>֡r>>Q=^= =.? ?%>R?1:?[?QL"?+>LP>Ix>B2>K? ??F&>]>>[??u>?%?_ƌ?[:? >xo>.>5>S> ?R`?G>Y>c >L=?O?=><'>O>>?B?LG? b>?5>>L?,>?\?>x=?H? w>,}?0>?!V?18?AB?N>k>]}>Z?W?@|?Gj??> >v>&>ӹ>(>̃?.??V?T>)>??*F?L&?]??73>>?Bw@?B ?:Q>]t>>f>={>C?Oe?N?S?1>X>p?Sx?T?9,? P?{>>>g>48?; ?&^>>>?;HX>tt>>>4>:> ?P+t?>s>F]>y>>>[?>>?G;?9ņ?iH?.o?D^k?+>ʖ>HzR? 9>y>$>?(>{/>_??>>v7k>a=>2?:>}!>>ߪ? ?9`7?n?? ?2'?*UL?b?%B>o|>?@>b>>T>C>>T?\ǁ?H>S?7.>>v?# +?'?Kl?? ? >H? ">> m +>?>=>䌓>Ӓ,>Jh@?5-?@?(p?Y]?>F?2?4iV?>?>=bd?>P?2?]??-`>??s? +0>OO>F??5{>(>?W?%>?1?T?FD?3?M ?N?_H?>{>t =>­e0={v>Y>y>e>>?/>NS>AY=>??t?!Ql?d?Cގ>k>U^*?eF>h>E>P>GB>A?(=?y`?>f4?;>`>侞?C? :>>>gl?8 +?8T???|?$? '?$U;>>%J>VcP> ?@'?^/?JF>d">6>r=et? +>`.>j>ƿ>M ?T\>:>x?6K? ??!]}?:> +>?]@>}>JF>>??&V?++?‘?u>*N>U,?e?5z?>y>JY>>} s>ф>`? ?A5J?.>;?M? ?%>r>1?X7q?@G?p?,*B?Th,?h_>= >d?>B?;>t.? +>>5?->7>K?Cq?Ҭ>.r>T>2>??A"?w0?2?D)?7G!?J!T?F`>e=_b??Pj?#0?7 +?"??ͩ>׹>]>,?*0?g~?Q,?[?W?Ś>=>균?| ,>c>y?jM?P??<>:mb?"?!>")?"?z?+T>˭>?>>t>+=d>? + ?8 ?E@?VN?k?T?1r?+?4?=H>? g@?&]>>>/?hB>Ui6>\y>J?aq??">L'>_H>c>ë?.5?G?8.?&_r?8D>"'=y>?2+?&l>x><8?#[?b?`i?M>>;>?M ?u8?ek4?el?\p?w>>?l>p> ? v>>D>oY?Z?fp?"?n>ϭ0>w>Ș ?-?`,?e>c%<4&>Ʃ?Z~?^?1?>T>> 6>䥞>,?8>T?"?D +?"d(>} L=c>55>b?Z,>(>|b?>s>%>߫>F>?t>>@u>6b>~>>,>:?"7@?2=?!??A?r??)#-?6?< ]>>W?(?N??)=B>5 G?;? +>1T>'>>h>=>I>*>?J?4B>7>?WD?%>?C>̖> ?!E?+9)>e`> >Ԅ?Ch?/d??&">j>F2? e~>X>?*Tr>%? 6)?> ?K?$ >Y? g)?H+?96>r?r? ?,?_p?/>BR>v?B>W&?'? t>ߡ?$t?8*=>>j%?T?/->>ݞ?S?;>>R>->)0>?X?8)>Ϛ>z>ܱ?.Zi>??LX??%?0>s.>N3>">A? ?>?>ZZ?Ҭ?R:v>>(?P? k>%̮>>VR??8?8S>>U?/?ALd>>&>i>>B>,?h`>u>s|>z>-?!c?lSt?'?(?]V?fz???h?(2o?8:2->'>??=\?'>Z>y2????>:>шF=pC>X>^?H?u?M?>S9>(>٤>͔? ΍>ͮ>hr>\n>>?K?9R? +#P??V?T?1Q?+? +$> ?O?,Ln?'??"6?">Ɣ>W&>6?$a?>@>Y?Cȴ?MF>[ =>?-n?<4>;>>{?(8N?>?P?4:?/W?,s?[b>6>*l>i? +{T>`j>8>6=n>ٙ?5pr>?Q?p='>5?? ?n +s?k?">V$>b܋?u>>L>>*4>>Å?+r? ?? -?^"?>ɫ?O2? =ʘ?`+?yQ?M.??0?z(>^?(?>>|n?"?֭>*#>>>>A(?lm?L>|?>{>Y>>8>>a? Ag? +Z?4>>;>M>v=0>Z?`<\?s?I(?x?->*=f>J?B>і>ʄ?Y?6!t?/?6%>w>MZ>@>? dI>K>>^?1W>H@<^=U>bX?ZL? +>>?)N>>;>9t? +>7>٘>{L>&|s>'u>@?U>>>> >3>>؏>rN>g?&?<>?w?6'>L>>>:>p%A>r?8?/I> >>m>:>>đw> +u=&>ɥ>v>{?@? 5_?G >>#?E:>=\=zl>?^:>ٜT>M>$>z> >D(>Pqn?3?B>weV?p?p?.>>g>A??%A?R?5q>`5>t?~>f1>Z>І>DI<2? )?$j>>u>F>9>Vb>?!?y}?>fX??:e?> ->P>y>>> >T;<9d>n?XT?b?B>5?>z=2>v\???[ +? >ܛ>{? ?2H?>(>ij>d>Q>Y??>Z>)>eآ??m\?<\>? k? +? ?U?]??>НS>@=NT>d?;L? K?.5>ݷ<$>U`>+?& ?#>Kb> +>̑>N?!q?BH??f9>>ر?id? 2? 2?h@?<-?G?>F?$ ??EjU?-p4? ?23?L*?H?E>?(rc>¶?iB?wӚ?-@lA"fAA 'A:A A A8A &A}A"r@>u?/-?f?JP?8Ɠ>n>d>?Dl?>d??%?*?P>?k?Z)l?W_6?Ha?,?p>`{>>>:h?LNt?L*?f ?&>x>Ԇ>U?@?4>>> ?d?x?P?>߼L>2&>*>0?@?-Y>u<<>c>?)?G,> >^b>>m=@>'> >kl>>>v>?+?Jf>?%?L? >^>Ӛ>rɀ>!\?5>>M&?1> =p> x>>@?!t> >??&>i>=>AlH>H>|Lx?G3?Q?\?9>.>g?>>`?t?5>G\>@>@?!>>| (?k? ??\'?;)> ?> +?5l?,.>ʸ|>#>Bl?"?->G>iQ=)>w> ?7?&>t>>d?B"?O|A?_ +?QS +?=>a4?^L? d#>>4`??>@>P?(My?!? ?L?>?kx>\?(g?=>/(>0>>Y>?M=?j2?>>3??W,>]b> X>bL?(d?O.>X??>Ku >?P ?p>2>N?X?K?g>^p>= +p>>?!?F/o?1O(>&?/n?5>D ?>B>T>?G> >>|h>)O ?'? +u>2?d?o?66?j=>>T== =J>Gm?L?7C?ү>n>?U?S-?Wh?G?:>ܽ>??J>U = >%?Cb? +T??? >?>x?1t?2Lj?h?->G??:h? z>>l>?->2>_|??VI?_?/>>ϭ~?2?? +>> >|??k?b?4?M(>! >? +M>¿? }B?J*?T>{>?fx>>,?Ev?#~?G>\=? *?D?@?-T>p?>wx??%¬>a|>0?#?!:>P>vX>~=!? +]?U٪?1i?}w> Y>ڌ?Tgj?_Ob? h>2 +>0>$><>T>h>\> (?D? <>=\>*?""F?C6m?.n?R?%{>>f??Pҁ?.?Q?B4=^P> =`= >1>==@>wkl>,l??w?">e|?8>ۈ>>>sZ>?3? >k?^>>I=3>??7>Y?>`@>`??q>>?>>>of>RH? ?<?I?J"?> >ؼ>u>> ? u?t?I?$,?Z/><>۞?.>JH>L>RN>:0> >6x>:> +>k?,I?(?"?HHT>>?'>;f> L>Щ"?L?;Yj?P>>>%8>>2?E?p>~?1 ? +8???r??cD?T>Y~>>(>J? +*>a?Av?z>>ٗ?)3)?%Sv>>2L>1n?%Q?'?i|?ia?9?;"?|p?`?A>.T>cl?ъ?T?f4?c?H|>*>Gp?8Ԇ?tO??u>fx??1Z`?'@b?k?:ߺ?/ >mOt>3>3R?2H>޹`?*9?B??>.>䊤>V{l=}=>xO\>=>P>ݚ>>}?"a?s>u<>,?*n>X>*H>%?1? &>??>?/s[>\>ٜ>>%H?4P?-?*?p?\a?Vn? >Ѵr?.?Y>>)>@>>$>?b??D|?S?T|?!̋?.?^[}?>$4= =f8>?+,?0G>?|h>d=V0?^?@>->|>N >>>/ >b??3f>d=>,? >>݆R>#z>*~>ux>t>%J?N?:F ?-?%ʒ>>?'?0+??Ed? >h>K?+?D?Qu0?h)?>?-T?5r>7>q~>p? +"x?b>6@>x?2\?YW>ξ>F>? ?0d?u}&? t? ?>U?> +==@??i\!? ?[?>??>=F>P?- ?>>΍>L>MQ>B?!>8?p?7G\??m?dD?/l? 'T>p>(>?:?"??,g>B=]`> >>eT?5.?"&>7>x>f<>>>$>n?3?i?8->?>R>\jd?L>Q>=>8>{\>~?#?v?;?F>lV?{?'?1? >>/ ? rD?L8>Y$??#?!?J>L>>ҋ@?\s?kJ?H?>>5>2?B|?`?`?|>1?>?N?/>^*=>8?Bv?L?E>>g>]>N=I>>>)l>F$>U>ƣ?>w>E>\> +>.>Vi?)?.>2>7>s?~?xh?C? ??ڮ? >^? +?.??s?c +w?>v=>?$B?}i?G?ͯ>Op>)9>c?]?+@P??x?>v8?7?9a?+>ȒT??7%??/j?Kt?,J>=>v?P?˶>d=SH =[>.>?>?K?Cڦ>p?N?q 6?@>>K>q>v>>.>#>>1P>ơ$?>>>p>F>Ϗ>,>=>?CRU?h >$l?T?h>9:>ˆT>? ?,?5?;E>w>#p?n>>«z>t>??}>N?/?7?"oK?,]?9a>&T? X?L>y`>f >8>(\>P>n@>?(O?CV?e?Z>=l>H==>>,5>`:?>>>h>ph?#=>>6H>_>Z!$????!(?B>:?=(?>>\>><\?8?C?T?8{>Xh>Y? 8>ی>]$?1}?$>FH>ƭP?\o?`.?@;>:=@>b?)Kx?!>?OO?W^>F>N(?3~?(>+@?>?7Ⱦ?'l>>|>f>~D?E? $~>`>bKX>o>o? +S?n?IH>g?%?Y?Fz>IP>-c>?d'?DZ?-a>>3>#0t>5?/>Ø? +>>*?1>۶>݄?>S@d>i?J.??;>?>u>̈>Ά=`>W?2Ѭ?y?@ >{>X??w>^>?{>x>|>??o?3e?$>hT>,i = >м>X?A? ? +o>D?[?*#?? +:X>>? w?C>>.>>>e>U>h>߾?Nu?0??X|?c]!>@>p>=k>ɥ?E*?Bۆ? ? )?0P>o>S<>\?Ck?q>j>̞>?#?rRq?$<9>>[n>s>P,?>&>?>ш8=;B>ljH>L>T??? ?t?Ck? +&? >>|><>Ӛ?7?] 7?l?a?;>ı? Ӯ?%>'1=@>? +*?b?qg?>]`?>$>>L>=g>>러>θ>Ƈ@?8}?P?$?(N?):_? >>Ѡ>? J?Q?KŶ?wA?7>T>{ > +Z?%?QX?*:>d>>N?:n>=W >*?\V?)>(? +>Wh> Z?.1>)>R?4NG>‎=>]?/n? $?$7?>?&G?j `>۴>?>kn?>A?"<>~j?5> +>u?(?4'?k)"?Zo?D~?)?8?0>>T?T?[ -?P>`?$?/Ķ? .>o8?$Z?){?.?m%>H? I?i?/]d>V`>}%>>J>yp>ΜH?J.?2?z?D?* >??_>@???J?J?D ?³>>,= >>F?&?g]?4>{Ҙ?â??)q?D ?GEA?uHx?>D?d?1>?we?8&?@L?T>B?%X>w??Ge?6Ӷ?$x?%A?D>>ڐ?J?Z?F? ?8?]? +@??>6t>울>|C> ?>? K>qr>=H>裸>4>1??9?a&?mA?l׬? +o>$?&T>>1>l==`>y>\^>?'?6F?4?:?>h?>v>?%>r>D >/d>g>?G>(?(,?](?[ ?ub?:C?;*R?[?X|?`9>`?}?*?rT>P>7>>p?`>??>t>3Z>5?43?4P?v>w>y@>Q>>@P?X?1>n>m>ڠ>(?/ ?T>?Pƌ?`"p?[???'?g?jV?:?4>>?F?G=k>(?`>ed>X??_?To?<^?c>߄4?@ +?VǾ?(>>H>??K>>??2?0!?;76? ?06?>D>v$>>$>&?(N?J?g>p==*>6I<>v>>\T>+n?f:,?^R>P? }>=Q?8N?F?9>x>?>ܜ`?"|?">ĺ??>e?E'>F>Z?>s>Y?>3D?p>Є>d?/?>&?#$>:?I?A>==S@>t>>'?->+`>D>p?5k?4k>"?/O?>k +?\>B>,?lZ?5?*^?>H%>(p?io?D<>=0>)8??>?(W?3>$=`=f>tg`?&-?CV?M5?D >\>(3>D>w8>]>>x~?H-??2?+p>f=+>>pƈ=mP=6`> ?0B?}?q?G|?.??/-H?7ʒ?5?&?>?,>N>yh>>>> x>:?< ?g?NY?R4z?8>RP>>\>ˤ??J>Yx>~l>P>?ou>Q>9|?!?/>L>?*ެ?m=]@>©? +'?"?, ?%=?Y?5?>ɏ@=>_ >h>>$?$_?ݾ? ?L%>0>X(?U?8>t?z>L>Yl?Z>c=>B?)??9?A? >Z@? +i>>8>h1=>)>Z??4$4>n9>l>?4׫?r?le>>>:>?W(?c?,L?>5=b>7L?Z>V= `>aP>T>ڌ??M5?HPF>K>r>~^==p>JS>N>:>ﱐ>&EH>O?>(>8I`>>>??xKV?;@>,==s>L>\ ? ? +?&'?$>pl>>N>/p?h?q2?i8> >>+x=@=U>>p>>$>i0>珔>>Ɵ>?\?-j>R(>>H>?(o?F5'?a?(`>5+=?ϼ>P>?ev/>=? ? ?4?>$>̤> +>>$>Q>QT>_<=>D>NBX>@?TX?\>ܨ>uIX??0Ka?q? +C?C?GG;?ei>Lh>u`??^a?ޤ?P?Ĩ?^k?Id>O>T?/4>P>(?Q?6H>??=F>>K?+V?a/?jC:?I݀>> ?IK?hQT? >\>y?L?V>>e>?/$?> >? >\>x>z>>*>)^P>a?2?Sf>^(>?vI???m?U.>D>IR?5?-c??m>?F>>>>nQX>>a>?6r?5>^>>p>ׇ?? |?IPD?Ӑ?? ??sR?CB>=ق>A$>? ?S?}>i> ?)7?#H>ƀ<>FIH??wa?'e?j?JV?9?7?u=?j/h? +=>n(?>}>?D|?">J?,?j?$>2|?->?>Z?8>>> (???>[:>~z>+>Q?x?>?2?o>6>>J?>Lj?`?X˺>>?C>"?@;3?%?$^z?++2>0?+?:J?Zp?_>`>?`?R>/d? ?Na?b?;\?*!>??= ?p>p?C?:e?(?l ?lPx ??k>;>nu$>X?2?mx?j4?9q>>>g? >~?T>>p?-Q>A>t?>1? ڃ><??~>aT=w>n>>ډ^>$>ء?-r?FU?Sd?D~>>? ?49g>>U?D?Y$>p>^???}=U0>n?^?;Z?G^?=< ? s>>"? ?Qrk?N??3&?>6>>>?kܨ?> >ʈ>!>">j= >d?>E>t>ō?L?>z> >>B>>=8?5 ? ?1??Qb>>4(>?_>OR> >? jj?K >=? ?=?+l>j>N6?q?M ?F?>2h>Y>?f?]?$~>d=P>ܲ?S??+&n?j?n8>ޙ ? q6>_~>? ?CF>>Λ?u?$>s>%4>?7?*?>'=TP>1Հ>G|>V?^&?>6? +n?&>>|>>up>r>_>Ո?D_?!1>֦>ɶ>>>*?&?X΂?Hh?5Qp> >K>w=@>d?>I?!?^.$?@>=J? +n?x?Oj7?"G?>Ɋ>,?2f0?@{?2s>)$? ?:?ܴ?C(?c"?Mh_>;=-= >>>x?"b>t0?B?']q?ۚ?<>ې8>)=fp??B?+Z>׈>,??B?:>>=w>z?? q?P9w?,#? `c>6P>uP?1?Aq?CIH?p?.?8>f=>Lg0?'?[ʪ?Z??6?\>׃(>?>=>?#?,*?K[>y,>̰?*,?k>Bl?`݉?wd?@2>.|>C>T>/>@?.>?uv?;{?6????޸???K?&uD?'?L ?OY? ?X?}>?d>>@?y>|Q>?0:>r=@?*J>=3>b>P>>a$?D?/??y>ׅ>ԑL?Df?U?2>ƉH>T>+܄>5`> >6?".?? l?.>?>N?7??Q?Qp0?*ߖ>Q8=>:x>>N?r?H? ? _?ph>>m~>m?E?&ȕ>_>8l?>>>U%>^?!J?) +>›?ؒ>j>w>>>G?eN?kG$?^O?5?&w?4?!h +>4??J??@a?@? o?.>h2>?2]>> >>ed>ߍT?$a?.$?^4?>6>?7{8?>?w>?p?-?X>][=`>H=p> =i@>m?R>SH>?.?'? j?2t?!G>J>:|>p?$>>>>ϒP>hS??8Z?M,?G?t>>u??'?|>ʚ>)s>BT>Ej> +4=|5=b_`??A=>iNl>>>Qp>:d=]`>?[?&ټ>N?#h?3<=ꑀ?k=?:0?6v?`?4?=Q?#?M?F"?M>`>>>.(?-Ka?ܨ>!B>d?*>y@?! +?M>>1^?&?BV?V>L">?)R>X>L>>s<>״?6 ?">>X>==>=0>{٬?8g?q? ?(?2h>Ȇ?FQ?O?!1`?(f>ɫX>:wP>_? >a>?uQ?&N>]? ?v|?(Q?EN>|>n>@?:N?'|>X>*H?Rx?!V> +>nA>(>>-`>ڮ$?M?av?/z>T?-?C?N?q6>E>[j>rH?”?ZB>>>U)>NB?"x>h>Z>>>A>4?/5?>$b>x>uj?(#>t?B?>*K?q> ??$[>_>?T?G@?E!?3>Idp<>a?Yp??(H?>8?Z$?2]F??)X>,>N>?fx?a +?7>o ?s?.>B>>?X? >D>iP??>> r?Ov>{=̰>E≯|>}0>ꃤ>? g?M?2=?.2T?IO?Wu? +> @>-d?= >(?K??/?Oc>љ>'> >Z? IW?.Hu>z>m>6?8h8?9 R?.>8>>=.7`>v>/2=ـ=PA >\>>&k0>/X??$) ? +o@>{HH==~P>P?O> +>@>>?q>H> >?|?!? ?Bܮ?>҄=7P>o>X> >ߗ>J>>?S?',>>. >d>v=}w? + ?k?}??@?Sx? Ӑ??T>A>6?ݖ><>#?:n?T?Eo>ҿ??W?.&>f>>?9e> +p>-?z><>f? l>>a?F>>:? \?W?y>e>>>?"}>?u?8e ?<0? ?JS>٢??>V=p>h?D>?oz?G?XZ?X?%n? ?Sm?DW?>? ^>?7`? >6P?4?s?BJ?pY>#>q?>>>3@>?>s)>(0>(>>R>E.?T ? s>^?K? f>U>_>>P> +?+|?_{`?#>&>l?>^ +?32W?$Q?H?^?e? ?LrV?#n>l >L???q?`{?>?)&>Jx>M +>??OJ?"'k>>$?+?W'?=? +>x>|L?5>? >,>w>:>>?N?M?N??aR?^>>?8?J>>p>|?0>,>d>*Ƽ??8> >+>>vK>҄?"H>و>|?Ds?">;>bFh?#?a|>I>u~`?޽?_?>>>H`>d>u?\>>??K?\,C?. +?F? ?"? )>>X>B>?F?D}?P?sT>K?>d??>`?d? >Ɏ?l>&l>=@>^>?qL?A>?o=S>?`&?>}I?&?N1>g>>3L>Ϊ?FІ?%?)dH>Gƨ>R>:>~X>킼?T>>>Ԯ`>@>>>%h?Q~?1<|?1S?9">>>q =锠??a?gv#?pV?t:?=>A>>=n=+=%>!?I?>?;*?]V7>(>*?"_>ӯ>@p>?5b?1d?G?k?, +?=?. 6?`tp?FyM?9>|><>>d8>V> >yN>z(>?E?s?FT>J>]P>|??` +?g?s?3&>߿>J$>?J@?\?D|?^%?,V> >>š>$>E>&?E"?(>zT?#9> D=0\>Z>\(>?I? +?x?XP?/>F?7m?3 >Ȥ>!>%y=~>>N>:>y">H->%Ȱ>x?Km?">>t>jh>?-^?EH?$?? 6?d>Ǩ?'?(.?Q ?~>0.?6K?_/>$=>/?8?q + ?lX?G*?.??^?h?'i?2C?d?AC?~?>?Ugf>>6 >;>t>H>wZ?>y?W-?0j>?"?Hl>E>kǐ>?D>!n??-??&/4>>=>&?Ca?\?c]?^? +??4^>>M]p>PZ?P? ?'?:Wt>p0>!@>O?>x>lip?'8? ? +?R\?^>J?q?Q>[>>>7 ?J>z>\?p? +??kΎ?S,@?>T? >>>= p=G>{0>FŠ>s> >?nB??XF0?:?`Z??:>"T>?%?<>\?>| +?j?>>?j&?{T?>2?$??I>x>$>?;@>?\ ??L`>۽>>x,?+S?G?;#?>?n>>`L?$0>>¿z?K??0?=F?,?[]J?@? [z?+*>?X>:z?&yt?m!?N?V_r?z.?P=3>;>\?e/?\*?2>?F?>t?t>8=Q >V>ԭ>>F=M>r >'X>ƌ,>P?b?Zހ?p/?S +>FW>E$>;=>ʳ?H0>s>>л>Ξ,>.>>C>>D?6?I.>mx>?X?3C7?4x>$>,[> >b|?A>:?:0>p>n?.?>=f=5>p>>>;0>k>`>4?7?M? ^?6?e?$,> >aH>?'?4?=>) ?8w?^>s>2>>? + ?L`?B\?">Yl= >oa>FH>?8o"?>-?-?Mp?b??*(J?>>^?*?">*>ܼ?9? +dk>x>>L>>՛>?x>J?vO>6=^>D> ?%i?m"?e8?$\?3?<>>h?*[?>|>>u>&kP>w>5b>R?4>>M0?18?*2>ώ<=>mS?#T?"K> ?|?3&??5G?%|?K?B?F?P̝?Wv?>Ic >$>'=@>_>>">]>=?2?~>>Z0>o?n?@HV?WyF?>x? ?x?+\?Qͦ?(n?)??Z> ڼ=P=):`>qH?3?8\?8T?=!??7\?>?*?R???>߲>2-?{?s.D?K[?R?vt?~? ??;?)>P?&e>8>YV?Z?l?QL]?`|?5d>/>͠?3?_?OP>,>TJ?:p?B?B?>>><>tP?? /? +O`? >?Nj?b5?yʘ?X׊?21?K'?<&D>>ڨ,t>˾>c?m? +`>??o?">$>b >Q?)8>$>`> h>A??>h>?4\?x?G >=e@>ӄ?0nL?9r?6? f>n>a?L>>漌?1p>KF?!?1I?/k?4>t>l>t>GX>?Xb?$:? q?-??">M?!?5>?ݗ>\\>x>>"=`= =)*!>?=0?8>|>x@>nd>t>p>(?">f<>`>n:(> Ü>??T>>s>4><>>>>>>@?rX?~[>?>5>P?2JO?LkI?9V>s>E>P??i.?W?E.C>ܪ>"?=%?dR?X?у>?,@.>&0? +u?QA ?P>ĸ>>jH>>>X>t>t4>8?6W?%|?/0? >??>YH?%? fY>r>DP> +>>?L>.>>? >;>F>9>ڣ?F>9?f?S(??0h?>>L>l>j>=R? +?X|>1^t>?? )? +Q?Q4?Nb>MH>>5?!? ?N= ?S>?2?D`>>>?J|?%ڀ>b>r?*j?{$>=)p>l? ?TT|?x?%??nf>>#> t>k8>ȁ>b>W>ti8?," ?&T?_?-P?$H?S.?Es?(?7H?(F?7b?Ib?>D>l?~+? ?*?R?>H>g=K>s>?!? /? j?X/?@a?r>4?K?  >Pel>?3? %P>TD>>RN>? ">˫? +O?^?RL>*o>?,4?>4l>4?#{?a?K1>ׄx>F}@?*W?f+??">ծ>$>j`? +>?>->:d>T>rt>gq>?# >? +>?;?/R>A*4>s?D>>i>>@?^.?aIx?#g??> N>Ԡ?ִ?'?4|?J]???R?;O?>;=p>F?),h?3>$=>=?2>Yp?b?c@?i?|y?7$>>.?y?$K?L}?&~>j?f?a?:¨? >ξ?T?X?>Y>j>H{F? ?>>UR@>>> > B>&>L>(?>V>L>s ?A?)r?*H>?3>;n>?@o?<> >P>]>o>T>T> 0?Cx?,I?5V?BW)?l>U>޼D>>݊?>i>d$?n>?v>?K>?7~>>l?Y>|>$?J>Y>Ό@>ǥ=b*>>֙?.|?a>8;f>f?A]s>6H>?B?/|?N?B!>B>uh?/>>Ft>>x >?,y?'>m? ?>?01N?7[?>>^=D>s?YY?We?+0?-?^?V>%p??: +>מ>M?!?)Q}>vD>j? Tr>=ɐ>)?Sg>GD?*W?^?Df???ɼ>?"?0>7W,>+ >d?s?F?/ˆ?!?c ?3u>۬>X>s>?37?69s>f=PP>?>>|??B>{>[J>q>Ml??:> >?mL?{ed?1 +? "?'??(? >a?:.>C>VH>,?+c?]? ?[*>v>?PX?ft?4?"T?%r?[`?~??>">?G>D>"~>x>4?JF?j?p>_|>$6? +>>6D?,6?e? ? T?2?/???>&>? k>~=>&? ?#x?5`>N>h8?-@?6?.b ?w?=p?V?:o>>ı,?N?J$?+?$?%е?8M,?>i?>o|>?9? > >U?ښ?N|q>P>x>KX>l?(>n> +?T?hÏ?>R?.ݗ?]?3b?~>.>D?Z? +ؙ>鴎?_@?M>D>et?$E ?3?R>)?>&>>$>>S0>>P>>>u>>N>v? n>x?\@?Zz?!c?;T?_4>-==>W+>p4??LI?>[ =/@>K>>uh>ʔ> +>>T:@>58?&?+gx>u>4?b`>? .?&n? + 2?A@?0>=?P>(>=?c?V/?@;?$ X>nt>aH?X?>6H=L=g =~>+?-(?FQ? >H@=#=>$>L&>vp>_p>OP> @>ԥ@>>)>n>?>Z?6F?(a!>ʤ?G?y?&?$)>?8?0?=?%??4^?=%@>#>>"~?@? +>ފ>r>GP?W4?>??6?~> ? ?[>A>g>+4>H?8p?I?8? G>V>K<>LD=?^?F?BU?_!">>q8?5?!3n>R>L?>%8>=>>ġ>><>N<>?1?>???>?i>>쮄?2>r>?>0>>>i?>@P??>"?,T?d'?S +?!?-C>`>4?? #?:|?;e>V>v> >6>x>/>N?4j>rt>(s>˒.?3N?,q8> >]#d>F>D?im?ps?b-?Ce[?N?k>'`>>Ɗ?#?-?%>t>?>?f?#b>:>|? ?7(>rj?+>]?>&>?$V?d?(/r>Yp=0? v??ܴ? j>>v??)/ >ų=O`=?k?4I> x>>>Z=I >2Ѡ?%?G)?+>ʐ>]X>Y,>B?G`t?k>\>d4> |>)=>ᩜ>>>ԝ?N? =5% >>@>??F?v"??E?p>t(>,>>sZ><>>ߚ>̤?~>>w0P=ۢ@=>\,>d?.>rT>?F?6I>‘D>[O>>}P=+>Xjl>[t>h>w8>Dh=$@>>>0>?,o?8+>rNh>: +>jx>"?Zv4?j?}r>X`>F>?>F?x?)4>f>l?+F>B>>!>>>?f?`p6>׽>$?D?1>?)Y{?e1?AS? +?7?;Ѥ?J4?@J?d>˰?:"?Y?I_?8a>Z>>\f>8h>$>>>>z>D?&?L>>7h?X`??3?l>ې>e?9??^?^?-DL>p>3?Q>*>?8cJ?5?`?[R?:#? VA>H>ly=o> >!>U>><>w>,?/>N>?I?D?&??gl?J^? + +?>?A&p?*g?! p>F>ڦ,? +?3?2?b?2? ??5QF>=L@>*?7>\T>?r?(hu?):>m~>ڦ?0@P?=? >P>kƤ> +>? j>?6?Xe>n> !>V?v?&?^?c?v,?V?'0> ?,,?MHp?9r?>/>,?Yez?_f?#X~>d=>B0(?'?>>|>`>>i?>\?N?k}?+d?2?>r>|6>R|>]?@Q>>?',>|>W̸>G>@>>qP=JP=g>Гb>r>/j>k> ?&><>>(>?9@n?$?$s?r>?">l> ?U_?N~>C>?,.?X;?6A??l>>(>>I>?N>ʬ~?|?9$?1?L?(3>V0>T?>Y>>??>3>T>֢~?,?>???/P?n>d>6>O>?cV?UX>0?4>x>r?*x?*>?>>H?8%t>'.?OC>k>>\?C@v?S5?Y?s? .>]>=>?;?J!?5U??#z? >'j?N?v?k +?X{7?^?>L>>Mt>x?<>[???wf?r?:w? >\>&>|X>L>=L>l>D>>?@x?e?CW?&+P>c>B>و>,>P>ڢ?"?s[5?1xe?&?P?X?CH?m?>2>1<> >^>>dž>`>? ?A >$>>X>?5<>??:>>>K>>P>?.!?1E&?*>c@?J?;>ʳ=P=k`>N>z>y>8h?&g/? G?A?՞>`>>88>H>d>Rj=p>?7?SA>>І?Z,?N?>(=P??,>8? L?R?::>5= >Ҙ?B?>>6?9h?d???1>ᫌ>$>/q>j?"I?fV? 4?h\? _>>?V?>! =jx??-%>b?>>~?+?j_>>Cp=`<>֯? >!?2?Q>?^v>>>x>>Y\=s@=K ?z?oO?l?A?(D?/0?`>t>">)>>"?7>޿>R>df?9i?>_ >O>!@>m?7}?SP?`p?*71?'#?=q>?M>f`>0H? Yv> >>i>>%>J;>8h>1?U ^?leW?^>?`>>D?=٠?8?%?(T?T?:|?>?H?$?P2?3?Z?X?*w/? N>e>ڗ?Vz>>Iv>.=t>YH?"[>^>? >B?4?V;?>\.`>E? >1>Y>??I3?XI>&>8"?A>>x8>ǀ>c?;>l>Р?S&?q!?=>wx> ?7+?Qa>-? ?!L>Ğt?b?8?J>l>6?*yh?: ?G!?>Z>>>ƌ?K?C> o ?8?@G?6wk?%>?p>>5X?%? ? ?@? +>r>.?tLt?<(@?6?;>>? ?*X? Z>R>^u?6??&?>>4=핀>޾>?;=?v>>Yn@>>9? ?b>P==q>?L?2?lV?9I,?P>l>???a&?/[>p8>굼?,{?>+n(>?)?:^S?>T="=>A?F4?{?@>$?>Φ>ƥ?5?eV?d?Oq>?3Z?e>Z>xZ? `?>:>A\>2q>A>>.>}p>?d?>k8>ـ??>ă>?">p>J?Y?5|?? ,>3X>? ?h?E5>V>k(>q?۞?6>H>L֐=P>`>m>˙???*~?b??4?D`?LD8? ?8q? +h>?"h?Rأ?C?B?\&L? >yy>l?JL~>O>bH= +>?$y? +U>S><>h? +>*&>sl?,h??5W??#>!>=!|>>B>x2>?GIx?4>?2E?df?C?>=Q>|>>T>>>/?3n ?%>>!>B??D\>>b? ?? ?;"5?>t<>?.9e?3?>[Q?C^>?,?WZ?3$?2?> w?(?>B#>W>A0>u?1?G.?~cp>>?dr?F>? !|>*8>P>? ?x?>i?Wj+?h'D?.> ? f`?H_}?/*>z$>">?(?Tx?;f>@>>u>l>5L>? C?CY>g<>a?>/>?)ES>? ? ? >?z?+P?@'?*>q? 1 ? u?>->@>?Bp?">I>(?z>`>Ц>H>8>;?=?>[> >>F?-Ij?K>]>`$>,0? ?n>?+5?)>Ք> +6? `?#?<>?'a>v>x?o?\>}$?)??B>v>4? ?=0?(j>?([>8? >>p>>`? ,>(>>==>od>T>~>X? o?,>i>?0?8Z?R%?d?>V#>?_?6>P>? +?Gy?P[>>>n? ?r?bC?{U?@@?}?MY?2P?Aϐ?Z?t?T>T|=9>l6?{)?%?>> +?v>a?5P>`>>p>h >>D(>d?O?k? +s?Y?->>Y> >{>D>T>d>>?2^?C8?Z>6>,|?M>x&??#L?|0?$x>>P4(>>r>;>>X?D;>.>?T.?M>S>HT>N@>彸>`?v?n?>N?a> d>E->i8>lt>t >f>>? ? )>>p?N)?:?->X?*BD>>x&l>,>?g/? ?zm>?>=5S>h?%? ?->4=V? ?V*>??6?P>>@?L ?- f?Q?6>?/"z? +U? l?jI?`?D?%U??*? >>GG(>?/>64>}$?EV->&=?g?2=ш>82?.>@>t?6n>>VX?"???G?f +?1?+?T?Di?ky >> +>l?n?U?n?]t>W>$`? V,>D>><>̨> >a@>2>>~&?et?>r>ї?=?5,?`?Gk:?9$>Bn>>޳V>X\? t?Q6??4>>>C>G>Ŭ?/;b>U=Ӱ? ?"b^>e>g>W>>'@>,M >4P> >n?~w?[J?l?%?2O?;?Z_?G ?E*>>]8>Ҧ>f>!X>>>]> +~>>@?.>?5?C>>y>qL>r?G>Q>2?8^?JB>>?5>Cz? u>>ߌ ?+w?B*>q@H>I>}H>>F}H>j?1?P:?&? +??>>ٰ@?{?H?/?&yp?Bv?Y6l?R?Y1?YM?;}?;oI?'4?:#?]H1?Rx?@~?0?>>??D +?1?2?s>>ևx>>]$>7?L?&>>^?zb>|>? G?0=>z? ?kK +??n?^d???C^?]:?E>1?03?!><>>8Y>w:> ? p>TL=A=>2>|> +?7?Q\>͵>>>R(>?)?v>ު?[?l?2n>:>#>ژ?T??!G?s?1>4?f?K??D>>>_>=u>1$?/>?EP?wO?>>p?g? >??+V?U>a><>\v?Alw?">/?B?`>3>>?>$,>='`>(>?$3?% ?,$?'>\>>?P&^?Nf>&>0><>F|>>1X? B?9b>ԇT? ?K>>p>>rb>V~? +>4??Yڽ>?@? 9>=>Ȇd>а?*>K>?6&>r>x? +>2>o>>#?1?/1!?-D?(?XF?F?;n?>`?.D>g=>G̀>`@4>И?T>2h>n??-W>xx>>,?D>0?~? ?::>|=fH>؛?n>?L?dPj?tʡ?H;?F?nxD?(ɾ>(? +?OD^?.H>r>k?6ih?v?i>^?,̀?k?I=5>z?>>x?>">P>肌>?L>"=q>|>=@>=5?r?4>p>'P>I>(?Bq?;>>.?p?RQ?}T? C$>K?, ?@$>9><><ި?W?p~?+܄>F??|?8G?>>]24>Ȯ?+H?30>h>>>x>,?%^+?-?vF>J??Ak>-p>>*?!?=??J ?EV?c? n>5?4?a?j`>ў>> d>?:>b? >$>D?o>>3`>uB?>$>rJ?O?1'>H>P!D?eT?>o?9?F\? c.>PN>uҼ??}?X?,?@?,?X?4?6>ז? z?k><>+.>?d?j[?,S?9#?{>j>M> +~>>>$>>id><$>9>D>I>?0?>]τ>L7x>S?!`8>>>Rp>s??3>?0??^Mg?;f?;6?UФ>ªx>ɘ?-&?>?>>>|??/vK>k<>|? ?? S>?>\>P?:0???Y:??v>x>$?:?Y?>U ? a?ɚ>l@>``>? +?VB?!f>.D>4?g?0D>>6?ju?k ?Az>YD>X>? +@>=>14?0/&?&v>F=ڴ >%>`>>i.>d? +?>\>k@?#?>?L.h?J>]>t?̞>l>V>xT=>(*8>?/? ?XT(?-Ue>yo>8>Y?P?4+?8`?X? =yp? +?8?%+?*>dl>p?4?M,? {?Ju?>ˀ?)>>br>^h>? <>>h>>>_>}>g?!??H? >%=[>g >$??Ih?:&?<&?4>>0??0>N@>,>(>0>>>?\?->!>7f?'_?${?.Vb?^y>ֈ==p>??5?&&?E>>^?Bl>=t=O>cm?n?R>?-w>=>V3`>&>^>F>`@?Al?KZ?"? y>"??'? />P=>? +ވ>.L>x>&t>'p?#>>?s.?1g?K?eql> >9? |>>*`?J>>?.Y?i?ذ?g?L?/k>>=Sh>gk@??+!>">)T>V= =|=G>T +`?!?3L>u? j?(>z<>Կt>>sE(>F?Ğ>`>>&>&?;N>5>;(?'9?.u?N?Zm?u,?"*>(>d>u4,>H>~?YE>Wx>N@>d>s= >,?3>?*?5? J?6R\>H9R>.? +X?Hz?#>ɞ? h> >?'R?]>>bX>>oH??Pu??i? ?o?:$>-?]J>n>l?˄?.k? } ? +n>(>6?? >,?+K?YM?>>j>? ?U>>?S3?3$?3ą? =>$>K>z>z?p?>]:>?rV?>,&>?6t>r>T>@>K|?a>o? +?n?@z?E?r?=?5?=>?/?FU>0>W- > +? +p>gϠ?"?>h?^T>Z=>E>>*d>ܬ>ӝ?;?6|?X>̮h>ŗ? b?4Z?n??P[?c?> P>L>^>>>'D>,? H?W:>x.>ܯ^?3W?$a>>D>$>4?܎?W>WT>8>?>`><>8>>>a>H?9?29?d?@?l?9!0?8>=]> +(>X??>>zX`>:>>?]?U?W? >Ef >?3?B`>f>Yp>m|>d`>P>`>>5?@>'$>K>ꄄ?"b?Aan?bM>ub>ul>7>?*?$?>>f1> ?.(*?f?K>L&>?#>j? D?oKB?(QZ?* +S>U>m +>RL>h>?P?4>> +P?2|?$J?C +?k\>n??'s?6?V\ ?? b>>R>>>e>"|?.>z>O{?j?>gT?!x?>=ߠ>^}$>>l",>;>Nr@??#?&D?>N?+?,?MC?>D?-n>z&>>?"(? F>]&?g>T?7? +>m,>|>`>,?AK?,DT>h>N? ??'gU?D>p > 0? gI??h?+E?S ?'<>?+?&>Jh>>B?1?F:>>p>:(??(H?f&?"?Jb?#(>N >^`>>7?&Y?Kl?7,>"?"?_N>?jZ??\>>" ?+_>v>>l>Ϛ,>>D?i=?Dp5?:??? +7u>~8>.?BU?7@>꣐?'?W?I>>t>Ў>J`?>l=P=r>d?>>:T??M̖?h??AS>W>3>>[~>H??'_?Cu?F|?r?*? b>2?}A?!u?>|>wp>K>>!? (?ƌ?,O>Ќ=A <>I?e`?L~>`>Ѵ?8Ă?h???^W>}4@>4' >?>pݐ?g`?@9?8?Zn?5??:??ή?">Z?Z~?l>0?#u?[?v?h?C >T?&>߇l>k?,E?]>>H>^?,V?W?4i??>>?š?d>>2>6(?&?x@?q;?5?*?V>0\>?>>b? }?mR>9? wa?pH >:L?(g?W!?]? 5>??.?&Z?Q1?h?5>A>i4?#c?Zn?1??0B?EF?3>jP=?w>ʆ>?d7_?J?Z>Ñ>!H=4?@?Z]?7>H`>:?f,?`J?C><>?MZ~?+.>>]`> ?,? r>+ٜ> ?>̓l>y +>H>|>ʼn>≯?>>NH?*?KY>֢?`?c$?Fg?JC>.4=xp>C8>&>A@>1->$4>?2?>z`?%`4?> ">F?Ea?P[?0?/p?>?@2?ۤ> +?.@ +?6a? >hd>͞$>>??X>ʽp?y?8W>ޜ>2?%???A>>@=D>tZ8??ON?A{>O`>Jv?(n>C>dx>R>Χ>WP??k|q?A0>3,>d`>*?2(?#>>*Z>X>?;x?B='>ˬ>z=4? 9? r?$?4>gP>Ӑ?OX?!= P>> >">?$v?IG?y>|F=P>c>>J?R?@> =g>@>%> |>>4D>j@>XnX>o?6}*?HS?L?&r>݌?s?3?Lf?j>>jt>Z>g>ߊ?<G?0?N>> >Q>aL>V=>?P? b >l> ?t?H?4?5?g?>ux>D? >v>y>Ϡ$>>ィ?9 ?(E> L>ϸ?8c$>&>IpL? ?+.?چ>(>=p??q?;>cx>P?'?b>ZP?$e>,>E>||=_@?&?D?5{?;b?1q?>0?;@>i=0=@=M># ?A>^,>`> > ?'>>ʖT>5=>?ƒ>V>V>?z?(Ko>> >jx>U>0>??U&?i>?>]D?.? ñ??Q0?g"??%2?:>4>>ƈB>>f>]r>?,?*??:? ?#n?"z?:Q?j#?' Q? +>~>,>f>t?"?!>>L>8>c>>B\?N?W>2>><>o?.X?4!\?Gg*?T~?2>(X?)+?*+>6;9=W'??tN?8^?#'?n2s?Z? ? >?>ѐ?L>?c? ? >d?22?/>~?>5h>>V>|C?\?L?Wz ?+?V???%?Av?H?xv?&)>?"?V?(>΂??+>e14>`8>pL?0S#>=>qH?=?;>9 ?>"=$>Z>ˇ0>4?1>͜>`?K??]?(6>eR?U >? +b3?)>9>9?> ? + >(=?> x>P?el?Z>a??E>>?2j?5`?5Q?` +3?Z?b?Wmp?d#?mI? \=>Z>Yl=W>d?I?-_??n8V?1'>|==>A??%?>Qw>V<>b=?>_>?=.!?H>P?&!9? W@?6c? D>[= >!\?Q>??>?7?8>*>?d?A>>1>~g>O(?>4?8f?&2>˔.??>>>>J> ?+ED>Pz>> >z>?i[?um?wT?>P?M +?Ek? |?u?E?QЮ?h~?9>L=u>-?&R?3?$?D>՞>?)?*h>萤?o?33"?3{?>9>} >:p>l8>y>J?9>4>e>?Q;?X7?P 3?<)?K?VQ??9"X?"'?{`?\i?EF>^>l???k{?g>g0>|>?5ۀ?G$>>d? ?]?>_x=y>p?5i@?3>?RA>a>?X?h?Vl>E$>r>? +?E>Dpx>e>Lǘ>>`>˹?9?@|?j?>M?UL?08>=???w?N)N>>>P@>N|>6?=L?T>>p>?>֔>>??=f?PI??M>yh? \c?u+>8> >w>=n >;Z>> ??J?1?'X ?2?B5? W>`q>?,.>}?H?>J==ǀ=]>h>L>P?x}?'>>Oh? 2#>h>x?pb?K?/e3?>->Z?>|>2?e?C?4(?2?Ӧ?!)?>"> 4?Aa?K%_>J>8? k? ?3%>T3>|?8?'? ?o?>i>X>?5O>(>ܯ?Q?"?Ј? B?*L?>$??E ?>??)?[o?^?? +?RU?B\0>s >?5q?FP?&b?^?;Y>?.|?5JL?> >z>Y~?? +>ܬ>n?Ji>V=Ġ>Ț??>X>X?B?$><@>D??O;k?{Y?{>v?%g? <>?;?.M>[=z>i>4=0=p>:?n?v?@F>/=m@=ɛ`? +?Gv>Ǡ>(?,>>b?&?G> ?+?8M)>UL>Ml>/>>N,?=?fu">ب> +l?6{?8>d>p??P?>w(?s>>PH?!԰>I>>3v?$X>Y>귴?$>Q>ռ?7>ט>;d?ڦ?'2?+?(X?Mx?>j>\l??4?>>9>>qQ>V>LJx> >c`>4n?u>> h??D?:3>>,?>T=>@P>>^??C?@->>?6V^?Kq-?Qto>5L>g0?QV?!~?(?D#?>G>>^>? '?->IB>m?X3?f\??74?,?/?1>>?u>Ҽd>t@>D ?2?*g?#>W&>?4?;> >U?=?,n> >#>>M>>?"H?r??>V>>S0?#E>2>??>>xL>?>>EL>?"0V?IE>3>>8>“?'>>>>w>}>>?*_?\?!3s?i.?B^?1y? ?R0?#?S?)>gd>ȇD?+>>2>gx??8l> >???~>>? >L>`?Aie? +>!>z>T >ZB>T֘>Wl? A$>> ?.@?CK?n7? =??H?%?8u?>#?/\?BO?F3?=\>/>r>? >=;>?>^><=>Γ?P? >;x>>p?!?bD?;V?D?K>\>??>8>6\?"C?˱>?X>^>̑,>H?4?)z>>JX>>}>=8>P\>ђ>5r?Μ?'!? 9?W4?r7?F>~?+?I܍?K?(@>>F>ހ>?"G?E?Fo?tb?f?Gv>/L>ཤ?HW?oG>҉?8U?aq?n?q??q? ?!`~?Gv?K>?R> +=p=h>kN?DT{?7A2?*g>t??>t?+?%?!t?( ?Y>\>7>c>n?U_>޼>d>>ɘ>Ȟ6>t >ל>?10?;z?}-? +?T>=>8? d>?2_?_1=m=(`? +?qw?qq?t>h?QK?7>">>>ô?"H?A ?.>>z>wT>>><>iB>`>6>>t>d>-X>?>)?C?@j?!S>΅p>H? h6>π>̑?W?QI?>Q>:>%>?,?4? ?t? ?+f?X?[?[?#>?'B?ho?G(>]&>V,?:s?L,?g[>,?>zR>Z?;.?j?C?#J?%p?B>NL>h??ç>T>9wH????^>p> R?4=?b,'?( +?"?N">>?=><>:?'_> >7H>T>O>?/Ŧ? v>Ah??qe?U?h>Ҿh>ؔ>3>x>*>l>? +;>@>JT=A ??.=>.<0? ?=gJ>H>a>>}> ? ܘ?,t>>AF>>KM>2>}> >C>\>a2>>p?'>>>z|?>Dz?#|?`>>(?3)c>G>Hv>vh?"?P>p>9X> >@={>}>|> 6=>>O>D?! P?S? g>@x>1,? +^?]&?r?rt?f[>\>6>U?R>V=O5`>Ȑ?* ?d>>8>~>R>iL>|>??+/>>X?\?!>b? ^>H?}?>q>}D>ˏ>Z >{? ><)=Zx`>8?O76?S?W?>P?+CW?Y2e>f>*>W>*>ǘ> >V?\>#=?_>昴>Z>ε>2?$?2>?$ >ל> +\>Ev>h=ض>>^>Ң>$> ?@2>T>ɴ?>;>>>;?q?G>k>X ? +d?=D=>?)G?UT?)c>sl? ,?j8??*?a?+v8>h>Qph? t?t?{?W>N>zt?[?U=? ?K?\!>G>L>>L?'#?G~>8>(>P> +>E> ?N[?'> ?+D>H>>4>?%>z>F?Yΐ?[G>ۗl>h?6r?5>??'p?1L? >ܡ>l>*3>Y"?>7>5 ?Op>>ޞ?J`??(h?/d?3>R +?>X>>?cE$?K?S8?t#?K{??/E?,R>ݒ>?1? ->$>$? ?vc>?dV?H>=?VK?>DH>&>w>#>>a ?H>;>@>l>ٰ>ݥf>? z?b?H"?q>E>0r?(>X?%F?)>'? -(?7? 4>b:>@*@>Z?G?d?Wo?$y> +>'>??/>>>˴>B\>t ? d?Qw?Z}K>>?Z4>3>?Z>>d=`>l?3?? B>X>?BE?1?G>d>o?>>8h>ճ.>@\?<>d>Խ$?I\>>?9;?#=?%>X<>b>t?EP?kT>e0>v?6n?6?*Ql? ?ZX?)+>g?eE>mB>?7?D6T>;|>$o0=)P> >,>x],={ >x?U +?B?fyX?n>UOp>>ˤ(>+t>˹:?m>?>&>Y?9(4?L?(TI?C#S?S?z>>b>?e?>Ȳ>2?K>>-? ?O^">X> >P?0)?[>P>>πf>6V>,?'{?/??=?>ր>T?>?D?"%?0U?> +?2 >[,?%>qx>ڲ?B%?<^?&?1f?>!>,?t0>?3>??6{>u<>U>f>y>$>ޮ?!>>?Q?>f>?->?>>V4>>QA>04>1>Z?:մ?%?‡?9??b>>@>,?T?A >S<|>]4>\2>>N??>Z>Ҭ>Ӝ>?TP>>`?(U?=?/O+?>?D~j? '?<>>N?Y?V?-7]?>S?\>?B>c`>.>&>?>̖>@?g>>>h>?/f>?4?l$>&>? ?k:? |?D?B|>??E<>n?WL?L>? +>HX?Ss?;=ݐ>id>4?5 ??&%$?O.? %?x?D~?,??P=>?o? s>@>;,>~>}?S>)?0?2??VX?=n>,?A>(>?G?:>8?>? +`>>u?l?>?J>lX>g ?]?,>>?(>Ğx?'?L?:P8>> ?)a?7>y;? ?9>>C0>@p??]_?-??A-?m?L0?{> L>b=?&D?">?Jd?6F>F>'D>">HL>yw`?_>-:>P>C=<>!-D??0{?2?I??LET?*? 4 ?>c,>.a>( ? ?f?S?Uw?3w? %?q?,?ZL>e =p>`>"??>>>h`?>>]? ?=F>n>>-0>ц>t??c?'%>U?!n?8 ?:>>F>>>>>>EH>? >*>ɴ>f p>D>1.? >>?9 +?M?(.>.=>b?7?K>B> ?TT$?](?g;?l?P?->_@>X! >?ˏ??^k>>>?]T ?nAR?+?,K?M-n?Kš>? >@>gB? Sn>.?C'?@?] ?n?<tC>ɖ?_A?NH? O? ?N?$H`?>¾>Th>k +H>%>4>@>˂ ?$?? W>?'?H?\?t?{ ?>>f4>v?<0?Wr?G?4s?Z[?Qd>?YH?TI?1>~>? +dp? >>7>S>(?SL?g8P>L>x?JH?k}?DH6>K>O$?L?J/?4P?E]?q>?-r?5>:L>">&P?"A?LB?$SV>¨?U>,>3?q? +|?!?eS?=?Y>>?R>u>?7>/>>v>؋">a?cN?H>%>g?L#?-.?",7?6>>><>>{>>?>_>}^>Vh>aD?gF?&%H>? 8n?>?*y;?h?'?!KR?f?q>8AX??+8>~l?@]?Wɼ?/x?'p?H>???7?>?.*?f?>ݨ=>->JMP?%>8=? +?i?jM ?N[D?Vd?!K>Ma?L?h'4??e?" >>l?c:>xX?4 +?I?u.>(>r&?!?V?9$? +>l >H(?"c?%>>ub>ʼ?@e?i?@+>2j>L>)>ZV8>>1?)>_>ò`?+?V{7?A>y>t?2i?Y.?>O4?x>L>E?$G?)3>Lx>N>$J?E.?3x?.?*>T>?D>Ԝ>fL?9?6>? lL? \?/ph>>k?"*v? y?UC?Jt?4?N?E8>η?Lr?(q?0 >>I|>?4h?"-?E?>A> G>\0>8 >ۛ?T>?O?A?v>>>d>2<>џV?H7>>&? >>> +>D?<?5?&?>>vr?R>{t>?:?@|>ܫ[T>ex?i&?5>(>@??K)>~? Q?9> J>@>>>?? ?/X>㩶>P$?Z>w"(? +>T>;>L?.q?!>+>> l=P>P>ܽ? ^>YB>._>$X>sfx>ֆ?$?4$?Jt?\T|>>p=j@?ur?J?>>Ͱ>o`>L)>4H?Ph? tT>* >0??1@>Ԁ>>L? t?_?r\?J}>>[\? ?%q?p>͟?$?{9????W?>z>>ޔT>D>x >~`>3>2>X>x? +?Q?V?z??)?KV>jZ??:?`z?5>D4>V>X>>^>,`>$?95>ѕ>?Z?/?T.>?>>v>h>>Đ=>d>>`>*>Y{>%?9? 4?/??P ? +@>Ŵ>>>|6`=>lP ?4?r?;c?Gv>ڈ>R?$sv?gD?|L>Z>Ҍ> >Y>H??[g??B?8<??F?2>ơP?>{>8n>> $>G>O?#>}>L>LV>=t>(>M>&>=`>v?~>$>B>?/$?7a>x>Q0?LS?>>F$? +ݺ? ?m?GB?'Y? >1,>{Mp>V>?/>n>?k>L>o|>c>ED?0G?gEh?5> > >q>>ᦪ? ?"?ִ><>N>5?3?>>w?d?X^?2>?4>>>->Ⱥ0?C4?E>δ>>H?N>[>ř?FQ8?>g>((>Į?"?`>ſ:>>C>N>?2?v?vC>v?O0> ,> P?kD >Kf>t20>*>x? + L?fO;?Y^h??72>3??W>ᙒ?7 ?< ?+6#>Dh>zML>,r?>"?k>V?:?%Ė? ^?4Q?"? ?)5^? X>`>@>H>?8?kŇ?eIW?9?4?]x?F?I' +?/F ?'j?P]D>4L>)4?S?`>P?? 3l><;>>۳ >$?K3>-?U? +Č>I>u>ڄ8?M?$?f?%!>C>?X1?7?%?`Y+>m(=? J?(B>@Up>>7>? ڲ?'?O?cA>P>?Of??:/?MJ>^?2? I>>?l?5>Ϧ>N>R0>!>? +x>9>4>=b>>?4nV>>l?(?->s">d>h?\?by?Lm>H>U.>b>c">ޤ>P\`= +`>[?4u> >g?Y{>-<=Ȭ=ŀ>>?t?8U.?">>}>\ >?>??N,%?B> >`>Z?$r?Eyv?=>;><>=҈>l>>8??PF?Yϳ?=?$n? (?'???[?.5? Vi?)?8|>ه4=uR@> ? }? ? >Ө>V>h4?)?(?'8?]>Ӹ>>M?'[?-?>q= >8>>i>> Z>4?, >@> +?ؐ>>R? +?('?>s?>@8>x>+>>,h>(p?&?U >N? ? ?f?{?C`>=ᡰ>Q?X?15?F)L>ˢD>>> >? ?$8?!t?>Z:>W>I?>>^<>>9>??L?UI>T>>ä?LR?Y?4~? ;>P>r >>>ǚf>8?>X=>ˍ? >6H>]?@At?3R>>>V?=? ?X>>Z??i?1>> >W?>?5 ?KX?N+Q>f?H?tT?Px?‘?3b>?^?E5?E!?".>g/l?%0?]?9>}>#4> >^p?W?[t?+?'?c-?c? +>ͦ?+?k?7*?Td@>t>h>CR??]^_?Qb>>QL>4? +@>? ?^{? >>C>P>>LN>u><>yl>L=>?W!> >\?$>{?V +?*?%a?q!N? >8>>= >??%?Zy?Tl>>8=>3D>>,T>y>>> ?A*?5>p?P?Wd? >s!>'l=>A?m;?[?fH?6¬?`?&'/? 9>4>>??غ?Q?gR?G?C?"? B|?.+?"|d?I?h>(t>Y>9?"?7ֵ>ϔ>@>>>0y(>d?oN??Z1?)*?`E?\.?1V>g,>P>>4>>"0=1>Ѡ??C >> >?)? >G>>q\?r?-??5k>w>>>>gk?)R> > ?Ej?%? 1z>^>i0>>V>>R??>r=<`> ?&>{H=0?>q>j>Q5 =N>C>GD>Ud>V>P>??>>߀?&?J?JѸ?u?Lۄ?K>7D<+>?G)??!)?D1%?e?y?l?)??*?*(>F8>m? b>>|T??Z>W?M>X>q?*?i?\?cض? Z??qh?8>؈V>+,?? 5?M*?U>9,>p ?N4G?z>?G2>>N>>:>x}>?5hn?>o>>3 ?6?d&>t=p>>t?#?[?>?v3n?#XT>>B? +\>n>c8?EA?v>_z>zh?A?$?;RF>`>H=P0<渀>>l>$>H>b>>>(>8>ܷp>sd>?S?8@>!>%h>?U?(-?*&M>n=e=>?? Q?4*B?3߭??7?ZN?:5{?h?T?*>?#j?>h8>/&h>*>`>?S(7?6?7i?!j?"?/?P&?|>$|h>B?W=?O>?h"p?E?+?>?-?*b>,<>18>>>B>at?͝?(Z?$?@>?Z-r>l>ے~?+/>@:>? +n>>DL>b>u?"? g>te>60?!5?'6H>?Z?0?P?s?vu?A;>-8=p>p0>>㚄?2F>>6 ?3>>? (?,>?>i>?MV?K>;<Ѐ>pK >j^?N?JN>8>?+?M>˄T>Ď>8[?\>w={>>ⷢ>>V?#?D?&?A>A>L??9t??!?k?f>7>y8?sz|?@>?.`>?>?/>>؅?U?Nn>OB>T?\?j?F?>??>+>\>+B?3>y\>`0?/>@>|?z>(?Y?G? +>X&$??42$?!}>? ?;*>@?>^>HL?U>H=a>$&>>n?v??h>} ?Z?2>2D>b\??J>h>l>>>>?+>f>G?t?P`>A??3?&>u>R?TC?x>L?t{>d>Ȅ?6_?%? Wu??Э>V? H?h`c?,E>F|?>>>F?)SZ?7?o?>?i6>$>+H>>s>1?L?+F? (? >??B0?ϫ>V>l?Y:>f<=g@=n>UQ??8b??b?"?f?Cd? >Vx>?:?zI>(>ה>>Yo>8 >"?¤>~'>ml?Wg?VY? >Ql>pPH>?K?--?\ ?dc?C?&>;>>:>Js>>V^>xO>$?J?!SX>.*??T?qe?y8?U? ?:?1?=>'`>? Kc?&q?l>i$$=o>kc>O |>h? g0>"P>2?E|?WP?f"?'?5n?4E?:E?3(>Ȍ>>l>|>?-?~> R> ?3xn?->(>4>ݐ>?C?5v? +>?8>m>,>i">? yw?>K?(?h>=?>*?G$>>? ʂ>(?>?E?"I=x>`>̌D>E?8? ? ??5V>:rp=O>/>> ?[v"?Mq??p>0>>>E9??Z? ?!?N?C]?pp?t?-j+>[#T=@>F>EZ>j>Ӧ>–?Y?/}?h>?^?{>P>H?О>k>j>c?$>>>@?(h?;1?Ai? >ݰ?7>պ>?=>?3? >D>Prh>^?G?F<>7=jp>>>$>vf> >$>δ?6?B^e?$>>>@>L\>>H2?Y >:=)0>K>Q?i ??>>+`>>?n?R?U?">f`@>)>Md>(?P>q>`>>Ҫ> +T?[? +?>@?%g?mN8?9?>>p?qkG?JA?\>>6>>}Ԙ>>=p>]?)A?Jt?>Q?6>?d?l?>?Ac?<4?&fP>[?“?k^?d?@?F4=_>8μ? g?Ҹ>b?e">*?^>~>?H&?M>>_>!J??NK?BO>>E?7W? @n>̵$>>2>]>N? "?!>x(>{@>==>>lX>@(>B>VX>P?$'>===Q<>>>.><@>r?&6>j^>m>|>>"?">a|?j?n?4j?*1}>>?%_O?*->h]h>@?*>ͯ<>u?1v>d=>v?O/?G?/`>K->?:'?M6>=0=p>hB?~?Q*?r?YI?W9,?Z?R>a>YG4>l?.??,>Ґ>-?.G?{b)?S ?58>>? +>? >> ;>)?C>\>#D?]?"7> *8>`?)aF>|>?L? ‹>??ɤ?>n>GҠ>6>>@>ް>J>`?;A7?P? X>PP>d? z?C?Q?G?X>ˀ>| >?>t@>P'>c>SP? J?J?= ?><>?:*?/+?0>{>3?">.>>U:?DI???t>>>>3h??\?5 ???s>s??<`? Id?0?bY?]?>`>l= >/?:>8/(>*?>b?Qq?F>>Kd> ?_?J>|N>p?fz>X>?$Z??,@?A?T?%>e;>? >1>D0?}?2d>>|0>(>?> >aL>V>p>}?*?+ ?4->A>"0P>x?-/?'>>A>R?55?+>oX>(>?>i4?.>>?4>=>>?.?Lx?1y? `> ?#u?e>k?p?&1#>j?6z?%}t>2?>)??7*?.?+>?(=e>SNL>?Pi?> =5>?,u?U?(>?I?R?G>ijf? 7<>>? ? {>Eb? $?Eo>|>?t?.X>>|?fy?>^?/?>SP>N?n? fT??$?N?a?BY?9~>ֿ<=S>앢?%[^???W ?Q?ab?-?f>:>ұ*>6? $?kP.?7?=Ħ?>>IK0>s0>"=L>T>=D?$ |?o?.L>]>5?!S&?BbZ?=?7?1>>i>ڦ>>8gh=g4?V>`=w=t`>x>{>P>j>f>Ӄ>Խ>M>l>>ה?`?,>B>>2p? X>r>>`? F??2l>5>?`?=>>Ш>?3]?Y-?bv?s>F>.>y?I?=^?8f?B?X>ܐ?g~?>E?M|5?M?6>Ԛ? "?Xw>(>>R>dM`>/ֈ>)x>ܡ>>+>"Ā>?%&1? O>X >>8>"h>4>>?@? x?8>~>?=_?( ?>Ұ?H?%ȶ>r?T?N*>p>B$>>ٰ>W?7?]0?B>)>6C?6?m`?@>?,J>M>H?>>}P>?P?D9?h?:?)? +;g>h>~">R>QH>)/>6>^>>o>?3f?Q^? +>8?>1?.D?^M?^B>>c?>at?2f>p>>?&W~> *>Z??W?Dã?wl??r?k?*>Lt?0>">՚?4>cH>9@>Ω,>?GS?D?3?&?\@?9?? >??+X>R>>???k8???L?"?4QO?%ǎ?>??`?o?>>F~>,>O>6>3>>v> ??%5(>H>ʑ?2?15>><>u<>??00>x?́?_>>A@>$RX>?a>',? @?f? 7>?)?3?AC? +>ʧD>ut? v?Z? ;>9"? ?f$?+]L>n >? >?:5?>'? L&?8>?°>0j>>H?;V?Z?(l?=?F?-? + ?(@.?b?>4?6?Kh?0z???Y+?\ ?.>e">h?G>ۥ> +?-?>B>(<>^`>ۨ?/?0>=p>ߛn?P ?(|?1+8??x?? ?Y>#>>ɵ>>[n>>>r*>$>\>KD?Bw>닼?CSC?h\?;t>Wd?#>]X>L? +S><>T?.?>Ds>Y?X?X@?l?Gѳ>4?9?4>?F"?Q>n >(4>w?J>hP? +?<>*?? ?0'>> ?>?4l??Z.>>G?kg>>?ȶ>>?-*?%?u>gh>&J>B|>L>Z??g>h>?? ?t?hvj?c=?^I> >{>ȸ?;?E?z?  ?D ?)?,??>X4=?V?"@>V?R>?T?4?+L?cIx>달>F>ތ>>?& ?dT?Q?#>4?6?yR?>>?,?fz>PN>(?)??&>2>8>i?(?7>*?? +B+>m=@>4>>s?^?7~>*q>>?ԓ?_G??>>.>r?"v8B?. +?c?5y&?:<=?&>f|?]>7`>%>Ih>/>1(>?<,>>?=?&hr?)O?4b>8>">iY?b?Bx>aL>y>?#?>>6^>?'>>cV>N?/?=+|?8R?J?@>kp>?[?W?Pu?j?Y?-b>>>H4>?K>>]?B?E?E?,6??)6??'6?nd?z?3g>t?T>h>d3?&N?HuT?Mo?Fd?>`?Z`?`D=>ִ>YT?>t>z?Yd?>y+??%t?@8?8??M>Ɗ?)?g?cn?H?Y>`>2 >м>,?p?Q?+>&==ɂP>W8?K?OF?J?e?1?Y?Z?%ư?1H?C?6?}a?6>}$>$>W?? +*=m>>=>`>|?4?.=?P?d?1?i?V?t>X?D"?&?jU?+?,?iX>f? ?1Ē? w8?7>?C"M?M[|>k>t?UB>S=->x>>l>8>+?*V?2>s亠`>Q.?۸?B?H`?/?h>y ? O?#>>>E$>>T>a~>a>e>[0> ^?9R? j>Є6>zp>S?$>Ʃ>>V? ?mB?7>,>a$> F=HP>?@6?Q?q?X;?E ?j8?T>H?#F?%Ug?Ls"?E>(??v8f?+T? +v?]r?'^>dQx>@ > ?+S?(>~>*>OD>n>.?H>2H?S?Ry?5?R?l>{X>P>ft?V?>Z T>yP>G>!? ?TB@?PX(>5>=>\? u? Q?>ʯ\>>?L$?W +B?0'>=@>`?Kz>b>o0>~l=ބP>Ę>> ?+?ZD?Wb?b?;ˠ?e?(N>EH>?3V>X? }>|r>q?K>>?>u>U`?Y??)>Ě?~&>J>>0?4?>wF>>0>=I>?j>:>+>H?2>p=g&?DsI?=>7>ה?D?f?f>?= >>>#g`=>>k?Hu?%>?(3?GQ$?2r?"><{>q>e>C>L>Yd?%%?8>6>)]x>mڠ>>l>ɲ?!1e?.?1?\T?>}R>d>"b>>EL?#?5.> ?8?&p>Z?r?%>D>?>>y0?>>:>rL?J?)J?,P?h^?!>>X><>^?.?O=?(> >֯>L>?Mկ?S?m'?=oD>?>f>G>;>\h>?>p>۬> >!jD????j>>?J$?M?6+d?(<>=v>Qx>x+>:>Eh>?l?Z?->π??"??o?b>$>>^?OB?? +b?M?0?>]l?'$?]P>(??KV?G> >0?%O?^D?M>?.?(:?M2?X8?PwP?Y?:SE>? I?Ee>uf>qH?2?{?5?vo>P=D =1>L>>ad?T?V>>?,>>d?,?>???:.>/d>(_h>=h? I">>V>m*>̔>Ap>?ܢ?(n>>oh>}>֭\>?4?jt?CV>LP>n>[l>+?>\?{d?At?>-H>:B==0>`>ԋ|>H?>>i>H>?>&?l??B?@>\>O@=>?G?Y4>1L>\>Q>Հ?2?kKt?AR>>碘>:>SX>;'>?y>> >( ? h>H|=hE>4>(>Ǫ?X"?l?Ct>_>Vd>W>P8>Z>>g\>̼>? ?(>?D?Z$?v[t>N>@(<>ك|? ?7Z?>z>|>S>~?=a?x?>P>[(>L?8S??:B?+>>ȋl>X??;?.?/?Z,? J>t(?9?\ ?_?OH?G?1^>s>lK? ??i?0t?+-~?&?|?&?W?=?7?#?8??_˂?l?F?s?-?OФ?O%?%s>:T>>>L=?h?j%>x>,>='=>V?>>D8>=C`? p?r?G?H?/|>>>I>,?]?FN?Hp?Uc>>X>"qP>c>4>ª@?>cP>r$?&>? ?[}?/?!d?#>xT?4?g?V>B.>w@?"c?cDž?P*>D>kt?J?>>N>?-??$(p?I53>@>>g>:?r~=O`>{@?`2?F?E"?SW?Z?="0=?q`="p? {?~>7(>Z? + h?>հ>=>M?>:><>@? 4?:V>78>eh>op=>>>?!C*?V?)=$>^?j?{ >,>O4>I?|>?H?'=p>?5>H<>H?®??a?>_P?F+?,f>7>"?$3?|>@?s?*>O,`<">:?X8>b>>օP>d?|D?&k?\ܵ>g >28>ɳ?c>D>B?>>9>xX>Ɯ>@;8># ?>>sQx??V^G?6>N>>x=>h?sL? U>P>m$>>j?]?4>x4>k>xM8?s?l >D=P>,R>>!r>>l>\>>=\>WT>>s>>c ?h +???;O?g>gd>I?9 _?O?HJ?&t?+?1.?)3>w>~>>f?%?J ?+?*>V>> R>>h== P??hl@?^?r?'>,?B>ڤ>}?C?j>=Ұ>^\=>>>>z?tI??>:>>ؤ>| ? l=?(?_>2?{>ѐ??KY4>h^>G>np>H>r:>l?g4>>a?&8? +>}j>@==*>}>m?@.?=p?C?rO?b?Q?d ^?_?4?>>>:? 7???QM?j?K?Ir? ފ>9?+(?B1?%̰?6>p?Y5?D>)? +?=rR?L?'9i>_>>f<>,>.>0?Dl? c>'>)>ET?)? gM>,>B<>'>>yX>n>`\>4?h?Ӭ?>=? ?p>>D??E>?n?\>Ѓ>^>>>?G?$FV>E>?+?> ? r?>rP>>.0>!&=0>?l>>t>><>?5?g=e? ?>|?>??& >Ϝ?:?2?%> ,>`? ?>.?#4?->>$bD>7? d?Y?Tw?g???>==2>><<ƀ>\> ?op>Z>]b?n?_E?"*?l>>׾?> >Cx>l?JF?>B?d??j?J>? X>>Ԇ?#H>xl? -2?>1#l>}> >Ϙ?8?'>f,>ah<>3H?1<^?>J>~@>">>|:w?=`?VGh?/\?R?tX?v%?y4?>[r?x?>6>>ͦ>a(>a?>>,?>?j?>Xz? S?K>[>!X?0~N?>>?_dd?"?7?i?`>fH?TR?:>}|>'H>z>??Ǜ> L>>x>(>4> >[>0>>Y> `>8?>rD?? +A?.y>gH>yp?/x?Oh>>>> 4>U4?(?(>w0>͍>>?A?0??%8b?NU?@x?>@>?>&?(ԣ?V$=5p>i>4?A@?,6>g>@?=5???>Z>h>Ai?&?7>>(?&>>,>;>>-?>h>o?|>ќ?O +?oU_?h>ω?>R>0?>|\??`y?>>bl= >Nx>`D>o=>>\t>?' +?O>5N>C >H>@?X>H>?j +?TH?+C?>?{? bL>ʀ>݈^??6 +? Z>D?y?M?r?R?Aa>? '?c?D*?J=7>wF?2i?m>?1/>K|>5z>-">]>,>?!00?#F??q>wF??Mc?V>">L>k&>p? >>Jj?3%?;P>y> `?r?b?>?%?@H ?2x>6>Yi>>p?J>>㾠?_Ґ?[,>g>>Q>L>#>,?>?Rj>>?/?L?$?`?XV>ܳ|? ?2v>>>L(>?*?2? @>-?Ԟ>l> +?Fr?B>$?-?>??2>$? ?@_>?/F?)?M>?>=1>n.>ܓp?N$?2}>>?%t.?H>H>m>,>?NqL?l?:ޤ?M?D??)g3?!IL? ?Qs?^v?l??l"=30>{(>?5?Dޒ?%}>S>4x>>B>?T>>>h>v?ݼ?+>?7J?\SF?r>uH>>ZP??0>=l? +?;?Vu?T ?ڋ>s?/>j>+?4WR?Ga?$_>?>h?`>ۓ??B? >z>>>Ql?0?;/>>?&??E>s$>?#(?N7?$.>O> ?F?1O>b>?GD?N>v>#4>[=g<ꑀ>O>V ={J>0?82>6={>?#K>?(:D?J-?3`3?W^>T>d?>>>X>a?6?Ll?(>@N>56>??1?2\>t?>@?8Z>Č>ƺ??=K?h?g8?? _>,>|>???&>>c`?ky>>T>?$H?d*??>]>i?v?5N>ZT>a>Ǥ>Z>wU >??^8]?]?WEz?L? q>6*>>ʊ^?M _?f?92?>@>FP>? +@>$4>>??xA?N?%&>dT>P? r?Tp> >>>k>?3c?Q>Qp>?`H>>FH?0?"y>(>;>Mh>Z?!?:f>>?U4?>s? ?]?>ꍲ>Ia>>_eh>?E>>t ?8? <>???>/?s>#><?/x?9>PX>>n> D>z>P>8>X>S?C=n>N>p>7<@>>>B=9P={>r?^> ={I=N >p(?P?4d2>1,> ?0?z?7{,?%?*?5T?9IZ>5f??j>>%a=h> +D?3̦?l'r?j3?U? +|>Ê?qN>\>?X?$>f">> >^>!*>3>>6>j?6E>|~x=V`>s?_~?KB?>*>p=5>k>?)i?>|?H?B?G >T<.@>V{x> d?5 ?N?!h?Z`#?>[>,B >%W??>8>>??Bg?9 ?'?>|>%*>>S>?O>oX=P>ʹF?"1>|(P>-*?">jVW> ?]>_~>>̊(>\>??ƚ?omt>>?6Ni?I?7j>T>@? ?|>>?+i>\<>>`,?'?" ?(?$?JW>i<>>?>>P>{(>~>? F>s>>>XH>r,>E,?M ?ϟ??/?>L>KP?ZB?>?R>|`>{=>?T?t>>^x>-A>n>(L>MX? .p?`?Q,?@A?;K??y*?D}?MJ>yZ> ??cE?>s) >M>ܒ?aK?V/5?!Jv>2?;V?c>W>4?">>EP>?>I?P>?>>l>ct??*>x>&\?+ +a?D>>\>0?02>.>vi0>h>к?H?q? >Z>Uz?'>>_ ?Mm?S? 4>?>$=G?L? >T?2?l?]f>c >D>nu>>q?>&h>J?,RT?D,? ?&]?V>@>(?? >x?x>I===3>T>ʖ=>?b?R>>Q>` >?;1?Gf>²? c@?s?CsW?5>>Lp?π>=J`>?B?6.>¦ >ߦ\>>f>sX>"8%?(*~? ? ??i>>>f?,?YM>Nv>h7?R?X)?OZ>|>;>sV>>`>.>>=]@?I? _(>_T????r?>I>1? ?>srX>:??"9L?E^?Rz?@p?86D?Fb>>o? ?gx(?PV?EP4?%>X? Pu?8>=0=j@>L??F?$^'?+Z>Kd???>o>B>>X>>Ƽ>)6>aV>UV?@?Q >x>b>k?X?Wm?i ? 2>>;>?!?)&A?2>Yp?P?,>C*?? >B>>i>`>Mux>>A? ?K??24\?P?v??_?W?5?_?>+?>>|?'W?>dnp>ߺ>9>Ɏ? >ͼ>2_P?*?ckA?d>On?L?/>t>??!H`?Ay ? h>>,>_0>X? C?;5>??;?C?[>j?+??`?bX?gg?VM4?>+T?2V0?B>> =Q>>f?#?KC?'{:?1(?e?#>>X?$ՠ>&>ő?C?4{?4q?HZ?T?Jb?/\?=P>h>>|~>=`=L >?;>$><>H4>}>>^|=>$?9M?Z >=h@? p?DF>P?'@?e?=>Ю??h%?#>̠>̓>>%>>7>$>4?i?q>h>~?<8S?[T\?sU?&>v>*>ؚ=>E (?.?=?@"?WI?n?(|>~?R>=8_`>?l ?'>rT?&>xz>y?*?s>0? ?1?>~f>n׈>J>Vڐ=>??8Z?i????a1>ޥ:>n?0Ʉ>d>ـ?Z? >?;U?[)?W>> p>> >I?QY?U1? >L>U>p?)?b?V?3>2>>?>`? +?/e?:D>:>iɘ>?> h><>*>?f?l?$D>>2>Ʉ>>{t>?&? ? f?TZ8?NJ?c&?Si? e?Km?x~>>L>=>? ?<6? Bp>">>H$???$P>}t=>K>>s?MG?D>[>L>ʅ> Ԭ?>D?W?&?3u?>YX>D(???>1>Ҧ?$?> >в>^=|=p>*>= נ>n?>}f>>`>IT>?>> >A?4>?.? +>?#?)JR> ??]/?#?l?J?27c?'U>>ZP>n? +J?&aw>N?j?K}G?N>#͈>L>r>PD<&??>I>>)(>?.?;>fې==阀>1r>É?<2C?E? @>x>>p?H>g=LJ>N>@>S=e=y>4??>Ph??&z?ny?lU?He?>??~?2>=hO>_?'4?+=?h?4?/?Z>Ȗ>|?F}?j.?\?=}'>P>dߘ>ʘ>Ԛ>^?!>c>?> >.Z(>Sl?$*H?`?1S?R?? +>??$ ???O?f>V0>д>>~> 8>%?8e?L?K:>E>5%P>$>?\?(??>?'(?@>P> >GL>zl>Ü>h>C>>Ժ?5kn?!>>bZ>>wl>?yi>Ѳ>>4|>w"?&Tc?Qp?>a?&A?>?$?[E?Y?[?3>?>z`>[GD>>?:?>^>K-P>? ? =0>Pq>)>.?,T?5?5?X?1(*?5Ph?>>?3p8?l??U?m?bA?]S?^?4k?с?##|?5>r? +?]?40? ?%l?1/T?N?T?>4=F>>>C6>>=6>{1>jX>/$?[?hTD?lj?L?J"?SŤ>>>Q>dW?9?lAJ?n?$|?% >>>xH>Z=7@?;?,?>U>n>]>!>??>Zd>K]0?Uq?N5>b=>'?O:>ۉ>?/>>< ,?d >n>_p?+10?B;??Mf?/H>N>??d?ɮ? қ?>R?L@?h?V:?+?O^?? >DR>p>׎=>??CKt?.>ǀ?.nX?4J>5?? +^?.?K.>>>>>2>>>3??"?~?Rk?>]>p>z>Ӟ?5 >4=l>x?}_?Dg?*?j;?q=t@>>>+t>rU=MM= +>?1$f? V*>b>H>W?(^?-l?:U?j?'˜?c ?P=?^ +?>?M2?F?-e?3?>(>L>>?2?,?(??Ý?z>?l>? ?Z?8??Ll?-l?!`>V>$>Ƴ>*?[׌?G>R?>vP?V?=8>x>? >8??E?! >v>^>Ft>>g>Oz>?V?S6>݇h>@>,>r>$??\>>S>rl?- R?On>>>aOH??>X=9|>^?Nr>=@? sf?=V>X?_?,?| >t,>0??.z?F>0>?x?!?*[2>n?~? :V?2?r\?F{?V/?g?Ll?>1?-d?>p>U?6>3E>?P}B?p? p> (>3>ծ>2>\>2t>8>а? ??+? 5?j?U׈??E?>^?Wh?7)>̊?`??? 2n>x\>O@??W>М?>l=? ?Cy=??:"?x0?.K>ݭ,>g>t>J >M`>&>y,l> ?+?S>_??t>d> +h>>ɘ>F>`>??\7?VUL>T>?V? ?"Q`>.>`?=?C]?`?-p?&?6*?8d?*?X:?XIJ?uv? X>V1p?N>6>>D>L?D>sz>=`?iR>OJ0>>Ix=> ?1>r>+0?T>V>?j>'j>*4>А>c?7?R>>)q`>)0>^>d? v>?#?e?n%?xd? &>X>>?*p9??4?)>s>N?N1?L9|?J>Ь?R?x>P>J +='k@>m?:T?(?86?502?E:|?o?2b>qc>a?>EX>x1L>'>2s>^?z>>v?S>ΰ>Ǯ?IHh? ?#-f?\>]0??$ >>;?F?No$?>??,?v7R?+>>&>h>}Z=?,?o?͎?Rm?,u?\k)?l>e>,?R>.??@+1>x??3B>?XB?>?\>U>^>;=Vp? +?2>^= >9>>ԇb>`>(=p>F?>>?3&?P;T>ƫ>7? >"<>d>>$L>Ps> p> ? +a>?6? >G?F??F?Q?H%_?fY>>>&?)?K>>U,>Bl? N6?_r>>b?J4?T?>nx??Q\N?5>^?) H?$>U?0>[(>$>|>c>P>,>Sv>ө?,;">۲>oW?(V?0?18?3(n>>n>c>,? +>">}J>„,? F>_u>>>D?HT? +$*>K??D?3?G>Ղ?$?O>խ>D>Ϲ??WL?}>s>$N>9? +Z[?}?f+a?V?2T>=`?@? =Р>?e?M7>ܲ >U>>ͬ?)>̝<>|;>7?n8>>>4?S2>>0? ?@?g?!?5ߌ?n?mVp?Zp>?6 ?'a$>P>꽐?K?ygZ?:n?.cv?>ţ>T?4?3)v>H?p?Mp?=2?6?>5??)>g>?I{>ɋ>\b>>>v? ?>n?6>O>#h?)?X|?<>S!>s?/> ?$?+>WA>Ø>>vq\=$=5>VĐ>n?i>(?!S?ObT?V>ش>@@>>׾> 8>@?>P4? +n?>B?R\?C!x???BF?Hl??E?h ?6->^b?&0?>E>?Ft??Il?~>H>S\(?? +?>>ݻh?/?;"?n>p>?;7?"?m6?XA?s>^>U`?+r?*?;?'?60>夠>@h>]<7>Χ?i? +T?*MD>w,>骐?>>>P>?~>-?1,V?OT~?UB?p??P>>>>)??!@?6?@k?@c>>b>(>$>6T?'?>i?M?I=Z?v̿?/a>z>9@?R"?"E?|?Y!?g?]b?V,?:?!P?I>?G?4>t>d-h>w?,? +>H ??Fg?B> +?1K>9,>Z =?>l>Gr<>>&p?˶?o~?" M>ɬ8>@?2?7>? >>p>>>뺨?G?.?=e?#>>?->>T>1?t>>>d(>2|>u>T>?Q&?<Q>>Q>=?F?Tf?֓>ch>2>>>??5?Ex?=?!?D5>%(>Q??:`?Fa?Q?4?$"e>o>>?x??NP?0$?U?@>M=I@>>{,>?(|?{ ?Q?>4>>4?ۖ?$ ?&yX?u+?94>β>Ձ>x:?>?@?>Ԩ>|>?,z?* ?+@?7í???$??*n>>ݨ?,>ͨ>Ő>U{x>p=>(>c>zP?>m>> M>m?=?@?>$<>>\>v>>???dd?>?5?19>z>L?P?IY??.?e>YH>~>d>?)c?6w?CL?? +C&?&\d> +t>>դ>5\>E>>>bx=̯<>,>ڤ>?!Tx?J:?.l?@?>O8?r?a?(L???W?'?MN?g|?&?#B?f??2?H ?:?A>t>h?=P?M>_,?J1?H?T?S?>r@?!>8>>???.>c>vx`?7>W<=>? ?=s>>a>>U8>~? >l>h`>?2>?"%?1? >p$>gf>޶> +>9>֚?5?>?X?>8]8>H?޲? \?W2?:?!>?}?' \>>+>w?#~?X?!Q??C?UR(?2I>Եx?ӊ?I?MB!?sm?>ah>Ҳ>>:?:? z? [?FY$? *y>[?^>> ??_K?(k>d>_p? d?Dh*>"R?A;?3~?Mj?qj?$m>J@=֐> >>??K.->l>0>X?"x??5dv?k?V'(>>Q`>ÿ>J>su>D?2v? F>?6?>y?D_???W ?j>%>4>*?? >G9>?FB?z?M>>u >>zN?5?>>:> d> >%?Q?G=>_6>@>4X>y8,>>>?9`?>P>F>=>0>S>2> +`>?Kv?fS? H>ƅ>v>^?3??]>!>?O9 ?iw?I>>>H=>Z>_?m8?Ql>D>3Q8>? ?8[?#hm?.?T??ƀ?>V >t?J)?)?L(2?? >B=D>?2q0?CL@=;@>h>k ?ϴ?f ?$l??Gh?T1?0>J?/?(Q?\$k? y?>\>r>?+?U?Nb?*?2??* +I?C'??M>>??D%?"h?L>?(̖? g?R?N>“<>??TXd?m?ʔ>q8?IK8?Jc?W;?I >˓>5H>,?j>B>>&>$>>Ք?R>i|>? 9>H?.m?4>>? r>>=?X?ʂ>R>d>-P?x?%W>‚?*Q?L*?O,?n ?? $?5n>>e= =+ ??G?Hp?CB?0R?V,\?bR2?D;?;r?>>N? 3<>`>3>L?NP?>l>d>>n?Ra?P?+ä>??@j>>(,>P?>֧?2(,?>0?.>>Զ>ףj? >2? J?LeP?^? >K>`??h>8>!|??? 7P?:?x?I.?Mo?^> ?">|>n>>>Ùn>k,>>c>z>>??(?5(?8?j`?vn'?=;>P?b?$a>?>N>?!3N>^C>b? >^x?-\?<6?#~S?M)5?>Ҥ?x?&yX?>Hx?j?FZ?> h?>h>f>%P>>@?3R?l?&,>W>.?@0?Qg?Na>X>kU?b?_?#y?7>K>,>=><>ʓ>&>?5>$>x>h?%?j=d??:F>|>h>Z*>z>m>X?z?Y}>㸘>p?? >??)T>0>$?.>>3>'4=Ia@? +>fv>ml?q? ,>ߗX==֐>? #>r>+h?4>>E,?>˓?,?&>><>/>ټd>Y?"Z?u?gY?yh?>ln>1p>gj>l?a?jWR?m[?i>>`>?l+?\>Ǖ?8^>ɰ??u?->޼>>T?>?# E? +a>?PT?o?|>T? _?q>A>?4z?[ i>d>m>P>ݜ?q? >B0>L?#>D>|>C>OH?+@>J>[?t=,w>t>E?9? >mC>5? >h=f>ߠ?HB?B>>>>(~?yw?;>j>N`>3?UQ>{>?2S? +h ?*?jO,>N?>D>>?I ?F> >>>l>>Ԧ>Z>/IH>|>껴>d?(i?D֔?1?"N>?*c?`7?)?>:>h>e>?*{?>},?#>b?;?>y;|>?Z?> ?F??+Y?8t_?PH?nQ?>ߟ?L?J??WH?4V? k>s2>Y >6?w?@@(?>,?j??I >h?7?7:>ܼ?>N>?MF?@B>|>H>4>b= `>P>>>(> ?K%?'F>s>|>+4>̀>>>T?W?>ڠ>h?2E>> > +8? ?5?Cԝ?8> ? ?? +n>[:?>T,???tL?cݿ?0>>N>Y>1LP??pU? +>u>Ձ>>d>@>3>Pt=@=>V>xH=>?r?a\?&>0>>U><>mB> +>?!A>O>e>ëL>68>ˍd>h? 6?Bmj?.c>nP=>HP>!$??S?8?Q +?l?M):?7`?>T>I?)>2>:T?S?i>=P>c<>>U >K?,.?'>R> >_l?$ۤ?-O>P/>M>0=c?^?B>$=y> A8>>s?638?1>NcD=>8>>>"?8?D"?%O?(T?C? >>Σ>?E?Z"x?6">t>?eb>C"?4@?M?]g?]ʅ?>F>nj?(?_>?T>t>?3>">Ҩ?>Z8? Z?0t\>o~?*?>D??JXh?`#?ie?a`> >,n>>%?h?D?o0#>>[?%B?W?)N>>?# +>^>(>>=l =S@>.ǘ>M? gC?.n`?5??=@>u? +Y?J.?93?0D>px>$?2>2>@>b?A(T>=d6X>Ajh>ů\??d ?CNW?6U)>?*6?>{o$? j(>MP>|>^>=x>V>?\w? a>7> E?-T?=|>3?q?Wג>=>b? _?7K?O? +?l>0> ?pq?itu?R~>.>q>u>2>FF? h?c>~U>n?88@?.>] >X?D>=|>=?Ue?/? +>Q>P?O~?Y>Hp>n,??Hܘ>?F?FO>G>v>}>P?>??Qr?d? >0>nX?3?\j$?Ez>@>*>:Z>Hn>Ũ>W$>>? +f?c?GԊ??/2?S??Z>=`> ?%R>;d>>r<>Xk=>j>!g>L?!`?a>mL??%1?@1L?IK>?+Ѫ?&>;o>?H>6>N?O?Db>K>:^ >V_>T?i>ȫ??)@>p> (>(>L>>??.-? +?}>~>>t>???? +$?K$+?;o&>[>?'+>>??_zQ?vN?;t??@?H|V?`>30>Ӝ?,>9>8>(>_L? ?X?=d?7?F?; ?5?H?`?Xz?D>>6(>ob@>A¸>WR?2?>>XO>|,?g?:?x?,6`>>h>=>Q?S? i%?N?a|? >Q>?>b$?? ?q?|?2[?*?a?B?$?M?=?.{H>>5>I>ZT=&=]>?7 +? >S=x@?>l>">>bT$>kH?H?S'j? b>B?@V ??>[>4>(?=|?hx>X>l>L>n>=??-??k?>%?A>>\?\?9F>?bp??;?(A>sD>͚?d>ǫp>>H>>t>m?5?]?Dr>>/V>>ƕ?tw?`?m+? :>>:>>fn??#?(m>:l?(?4vq?6?j< +>ᢖ>? ?>*F>?41?8?&/>T>>겸>F? ?4> l> >>?J?c ?Gi>[T??>>P>??8>?F@\?M>c >.>xF?a+>c? ?P? >>đ? cb?Rn(?E*? O?>>h?U?$4?qN?h?+?r?=]y@>m?q?&#?$/>?r??P>E>>v>.Z>Ꙑ>>D>1>??\9P?.>]*X>mrh??)>W>>L?5>7>_Ơ>> ?8?8>wF>`4?5a>T>p?9dN??VC?Pve?V? >!?+A`?;?!#?g?*?Fm?t7i>p$>(U>ڜ>D> ?{2?>b?6u>?a>?[>P<>8?(>6d>6h>dL?Ez? $>jp>*:0>B>]>ƽV>^b>^\??"?#?~5>>Η>i>q(>F>t>?&?T>u=@>?>5|>J$? +>ч? 3?!>fh>B?@δ?->F>?-L?03m?T,>f>>$>8f?f?8n?PZ?=|>>s>p>(> ?*>I?D?@؇?R?8?2d>|> ?X?C> +>MX>ru>>P>O?o?E>=P0>k>g?1[?@?6?cb4?P|? 0?2V?t>&v>? ?okK?mp?;1@>%>D?A*?L?Jj?> ?(r>=j>Gu>O>u$>,???!>{h>e?pX?(?>}Oh>`?4?"{?(H>Ҳt>И?_?,?OV?i?? >k"= >?Mz?U>>GX?u?Ka? ?a?#`>>K?i?nX?X"->??? +L?> ?:L?&`? :?b֢?d??P>>@?bz?;,>d>? +>b?[>> 2? $?">>>8>a>W>" =>/8?-?9@?)@?>ad??\7r?R>*z>>8>(D=>(?bi?I/?@z?>=?sh? +>Ϯ?]k?v?wU?NH?.B>f= +>4>P>>>'>>>,4>i`? Ϧ?C˼?4T>i=DP>??>_>9?g>?>>??,?R'?IE?Y7?6>>y>E8>-??="?k?>d?^lP?һ>\4?&v>>Y28=O?O?/v?5?!? ~?p?&)??u ?i=??&?Oc?{o?>L?4O?4n?>WX>d>&l0=Jw(32768,1,1,1) Ta FREQ-OBSAH1@Z RA @\HU&GDEC @A=Michael Fanelli unknown OnOff:PSWITCHON:TPWCAL Rcvr1_2 ?HYOPTI-HEL@2YAH1@䎼k@q9T6Y@E < @pf`@?^5@A*jA*j@Z @@FK5 @\33333@A +