diff --git a/docs/source/conf.py b/docs/source/conf.py index 252f257b6..81acabae1 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -4,6 +4,8 @@ import datetime import os +from sphinx.domains.python import PythonDomain + from sasdata import __version__ as sasdata_version if os.path.exists('rst_prolog'): @@ -31,4 +33,26 @@ # -- Options for HTML output ------------------------------------------------- html_theme = 'default' -html_static_path = ['_static'] + +# Ignore missing references to sections in SasView documentation +def on_missing_reference(app, env, node, contnode): + if node["reftarget"] in [ + "file_converter_tool", + "image_viewer_tool", + "sans_calculator_tool", + ]: + return contnode + else: + return None + +# Bypass stupid sphinx handling of multiple classes with members named *type* +class PatchedPythonDomain(PythonDomain): + def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): + if 'refspecific' in node: + del node['refspecific'] + return super(PatchedPythonDomain, self).resolve_xref( + env, fromdocname, builder, typ, target, node, contnode) + +def setup(app): + app.connect("missing-reference", on_missing_reference) + app.add_domain(PatchedPythonDomain, override=True) diff --git a/docs/source/dev/dev.rst b/docs/source/dev/dev.rst index 47b820804..ee73ad7c9 100644 --- a/docs/source/dev/dev.rst +++ b/docs/source/dev/dev.rst @@ -8,4 +8,6 @@ Developer Documentation .. toctree:: :maxdepth: 8 - SasData \ No newline at end of file + SasData + + Modules diff --git a/pyproject.toml b/pyproject.toml index 71b1b2cff..83970595e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,8 @@ requires = [ "h5py", "lxml", "numpy", + "scipy", + "matplotlib", ] build-backend = "hatchling.build" @@ -94,6 +96,7 @@ header = "SasData" [[tool.hatch.build.targets.wheel.hooks.sphinx.tools]] tool = "build" format = "html" +warnings = true source = "source" out_dir = "../build/docs" environment = { PYTHONPATH=".." } diff --git a/sasdata/data_util/averaging.py b/sasdata/data_util/averaging.py index 2e9f0f1b0..84d34e2c8 100644 --- a/sasdata/data_util/averaging.py +++ b/sasdata/data_util/averaging.py @@ -273,8 +273,8 @@ def __call__(self, data2d: Data2D) -> Data1D: class CircularAverage(PolarROI): - """ - Calculate I(|Q|) by circularly averaging 2D data between 2 radial limits. + r""" + Calculate I(\|Q\|) by circularly averaging 2D data between 2 radial limits. This class is initialised by specifying lower and upper limits on the magnitude of Q values to consider during the averaging, though currently @@ -290,13 +290,13 @@ def __init__( nbins: int = 100, base: float | None = None, ) -> None: - """ + r""" Set up the lower and upper radial limits as well as the number of bins. The units are A^-1 for the radial parameters. - :param r_min: Lower limit for |Q| values to use during averaging. - :param r_max: Upper limit for |Q| values to use during averaging. - :param nbins: The number of bins data is sorted into along |Q| the axis + :param r_min: Lower limit for \|Q\| values to use during averaging. + :param r_max: Upper limit for \|Q\| values to use during averaging. + :param nbins: The number of bins data is sorted into along \|Q\| the axis """ super().__init__(r_range=r_range, center=center) self.nbins: int = nbins @@ -396,12 +396,12 @@ def __init__( nbins: int = 100, base: float | None = None, ) -> None: - """ + r""" Set up the lower and upper radial limits as well as the number of bins. The units are A^-1 for the radial parameters. - :param r_min: Lower limit for |Q| values to use during averaging. - :param r_max: Upper limit for |Q| values to use during averaging. + :param r_min: Lower limit for \|Q\| values to use during averaging. + :param r_max: Upper limit for \|Q\| values to use during averaging. :param nbins: The number of bins data is sorted into along Phi the axis """ super().__init__(r_range=r_range, center=center) @@ -549,7 +549,7 @@ def __call__(self, data2d: Data2D = None) -> Data1D: class SectorQ(PolarROI): - """ + r""" Project I(Q, φ) data onto I(Q) within a region defined by Cartesian limits. The projection is computed by averaging together datapoints with the same @@ -558,7 +558,7 @@ class SectorQ(PolarROI): This class is initialised by specifying lower and upper limits on both the magnitude of Q and the angle φ. These four parameters specify the primary - Region Of Interest, however there is a secondary ROI with the same |Q| + Region Of Interest, however there is a secondary ROI with the same \|Q\| values on the opposite side of the origin (φ + π). How this secondary ROI is treated depends on the value of the `fold` parameter. If fold is set to True, data on opposite sides of the origin are averaged together and the @@ -579,14 +579,14 @@ def __init__( fold: bool = True, base: float | None = None, ) -> None: - """ + r""" Set up the ROI boundaries, the binning of the output 1D data, and fold. The units are A^-1 for radial parameters, and radians for anglar ones. - :param r_range: Tuple (r_min, r_max) defining limits for |Q| values to use during averaging. + :param r_range: Tuple (r_min, r_max) defining limits for \|Q\| values to use during averaging. :param phi_range: Tuple (phi_min, phi_max) defining limits for φ in radians (in the primary ROI). :Defaults to full circle (0, 2*pi). - :param nbins: The number of bins data is sorted into along the |Q| axis + :param nbins: The number of bins data is sorted into along the \|Q\| axis :param fold: Whether the primary and secondary ROIs should be folded together during averaging. """ @@ -709,14 +709,14 @@ def __init__( nbins: int = 100, base: float | None = None, ) -> None: - """ + r""" Set up the ROI boundaries, and the binning of the output 1D data. The units are A^-1 for radial parameters, and radians for anglar ones. - :param r_range: Tuple (r_min, r_max) defining limits for |Q| values to use during averaging. + :param r_range: Tuple (r_min, r_max) defining limits for \|Q\| values to use during averaging. :param phi_range: Tuple (phi_min, phi_max) defining limits for φ in radians (in the primary ROI). :Defaults to full circle (0, 2*pi). - :param nbins: The number of bins data is sorted into along the |Q| axis + :param nbins: The number of bins data is sorted into along the \|Q\| axis """ super().__init__(r_range=r_range, phi_range=phi_range, center=center) self.nbins: int = nbins @@ -791,11 +791,11 @@ def __init__( nbins: int = 100, base: float | None = None, ) -> None: - """ + r""" Set up the ROI boundaries, and the binning of the output 1D data. The units are A^-1 for radial parameters, and radians for anglar ones. - :param r_range: Tuple (r_min, r_max) defining limits for |Q| values to use during averaging. + :param r_range: Tuple (r_min, r_max) defining limits for \|Q\| values to use during averaging. :param phi_range: Tuple (phi_min, phi_max) defining angular bounds in radians. Defaults to full circle (0, 2*pi). :param nbins: The number of bins data is sorted into along the φ axis. diff --git a/sasdata/data_util/binning.py b/sasdata/data_util/binning.py index fdacda103..6eae17cd8 100644 --- a/sasdata/data_util/binning.py +++ b/sasdata/data_util/binning.py @@ -153,7 +153,7 @@ def get_bin_index(self, value): 2pi to 0 discontinuity. :param value: A coordinate value in the binning interval along the major axis, - whose bin index should be returned. Must be between min_value and max_value. + whose bin index should be returned. Must be between min_value and max_value. The general formula logarithm binning is: bin = floor(N * (log(x) - log(min)) / (log(max) - log(min))) diff --git a/sasdata/data_util/manipulations.py b/sasdata/data_util/manipulations.py index b7d17f41c..004b61d93 100644 --- a/sasdata/data_util/manipulations.py +++ b/sasdata/data_util/manipulations.py @@ -323,6 +323,7 @@ class SlabX(SlabX): Old signature: SlabX(x_min=0, x_max=0, y_min=0, y_max=0, bin_width=0.001, fold=False) + New signature uses nbins; translate bin_width -> nbins using ceil(range/bin_width) """ def __init__(self, x_min=0.0, x_max=0.0, y_min=0.0, diff --git a/sasdata/metadata.py b/sasdata/metadata.py index 588a4de76..12cd450fc 100644 --- a/sasdata/metadata.py +++ b/sasdata/metadata.py @@ -763,11 +763,11 @@ def meta_tags(obj: dataclass) -> list[str]: Example: - >@dataclass - class Thermometer: - temperature: float - units: str - params: list + > @dataclass + > class Thermometer: + > temperature: float + > units: str + > params: list > item = Example() > item.temperature = 273 > item.units = "K" diff --git a/sasdata/model_requirements.py b/sasdata/model_requirements.py index 3773c86ee..a2bdd5a43 100644 --- a/sasdata/model_requirements.py +++ b/sasdata/model_requirements.py @@ -410,8 +410,8 @@ def slit_resolution(q_calc, q, width, length, n_length=30): where $I(u_j)$ is the value at the mid-point, and $\Delta u_j$ is the difference between consecutive edges which have been first converted - to $u$. Only $u_j \in [0, \Delta q_\perp]$ are used, which corresponds - to $q_j \in \left[q, \sqrt{q^2 + \Delta q_\perp}\right]$, so + to $u$. Only $u_j \in [0, \Delta q\_\perp]$ are used, which corresponds + to $q_j \in \left[q, \sqrt{q^2 + \Delta q\_\perp}\right]$, so .. math:: @@ -447,8 +447,8 @@ def slit_resolution(q_calc, q, width, length, n_length=30): \left[q-\Delta q_\parallel, q+\Delta q_\parallel\right] However, we need to support cases were $u_j < 0$, which means using - $2 (q_{j+1} - q_j)$ when $q_j \in \left[0, q_\parallel-q_i\right]$. - This is not an issue for $q_i > q_\parallel$. + $2 (q_{j+1} - q_j)$ when $q_j \in \left[0, q\_\parallel-q\_i\right]$. + This is not an issue for $q_i > q\_\parallel$. For both $q_\perp > 0$ and $q_\parallel > 0$ we perform a 2 dimensional integration with diff --git a/sasdata/quantities/absolute_temperature.py b/sasdata/quantities/absolute_temperature.py deleted file mode 100644 index 045c7de97..000000000 --- a/sasdata/quantities/absolute_temperature.py +++ /dev/null @@ -1,14 +0,0 @@ -from typing import TypeVar - -from sasdata.quantities.accessors import TemperatureAccessor -from sasdata.quantities.quantity import Quantity - -DataType = TypeVar("DataType") -class AbsoluteTemperatureAccessor(TemperatureAccessor[DataType]): - """ Parsing for absolute temperatures """ - @property - def value(self) -> Quantity[DataType] | None: - if self._numerical_part() is None: - return None - else: - return Quantity.parse(self._numerical_part(), self._unit_part(), absolute_temperature=True) diff --git a/sasdata/quantities/si.py b/sasdata/quantities/si.py index 947cc4a11..24023c1d7 100644 --- a/sasdata/quantities/si.py +++ b/sasdata/quantities/si.py @@ -7,72 +7,72 @@ -DDDDDDDDDDDDD NNNNNNNN NNNNNNNN tttt -D::::::::::::DDD N:::::::N N::::::N ttt:::t -D:::::::::::::::DD N::::::::N N::::::N t:::::t -DDD:::::DDDDD:::::D N:::::::::N N::::::N t:::::t - D:::::D D:::::D ooooooooooo N::::::::::N N::::::N ooooooooooo ttttttt:::::ttttttt - D:::::D D:::::D oo:::::::::::oo N:::::::::::N N::::::N oo:::::::::::oo t:::::::::::::::::t - D:::::D D:::::Do:::::::::::::::o N:::::::N::::N N::::::No:::::::::::::::ot:::::::::::::::::t - D:::::D D:::::Do:::::ooooo:::::o N::::::N N::::N N::::::No:::::ooooo:::::otttttt:::::::tttttt - D:::::D D:::::Do::::o o::::o N::::::N N::::N:::::::No::::o o::::o t:::::t - D:::::D D:::::Do::::o o::::o N::::::N N:::::::::::No::::o o::::o t:::::t - D:::::D D:::::Do::::o o::::o N::::::N N::::::::::No::::o o::::o t:::::t - D:::::D D:::::D o::::o o::::o N::::::N N:::::::::No::::o o::::o t:::::t tttttt -DDD:::::DDDDD:::::D o:::::ooooo:::::o N::::::N N::::::::No:::::ooooo:::::o t::::::tttt:::::t -D:::::::::::::::DD o:::::::::::::::o N::::::N N:::::::No:::::::::::::::o tt::::::::::::::t -D::::::::::::DDD oo:::::::::::oo N::::::N N::::::N oo:::::::::::oo tt:::::::::::tt -DDDDDDDDDDDDD ooooooooooo NNNNNNNN NNNNNNN ooooooooooo ttttttttttt - - - - - - - - - dddddddd -EEEEEEEEEEEEEEEEEEEEEE d::::::d iiii tttt BBBBBBBBBBBBBBBBB -E::::::::::::::::::::E d::::::d i::::i ttt:::t B::::::::::::::::B -E::::::::::::::::::::E d::::::d iiii t:::::t B::::::BBBBBB:::::B -EE::::::EEEEEEEEE::::E d:::::d t:::::t BB:::::B B:::::B - E:::::E EEEEEE ddddddddd:::::d iiiiiiittttttt:::::ttttttt B::::B B:::::Byyyyyyy yyyyyyy - E:::::E dd::::::::::::::d i:::::it:::::::::::::::::t B::::B B:::::B y:::::y y:::::y - E::::::EEEEEEEEEE d::::::::::::::::d i::::it:::::::::::::::::t B::::BBBBBB:::::B y:::::y y:::::y - E:::::::::::::::E d:::::::ddddd:::::d i::::itttttt:::::::tttttt B:::::::::::::BB y:::::y y:::::y - E:::::::::::::::E d::::::d d:::::d i::::i t:::::t B::::BBBBBB:::::B y:::::y y:::::y - E::::::EEEEEEEEEE d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y y:::::y - E:::::E d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y:::::y - E:::::E EEEEEEd:::::d d:::::d i::::i t:::::t tttttt B::::B B:::::B y:::::::::y -EE::::::EEEEEEEE:::::Ed::::::ddddd::::::ddi::::::i t::::::tttt:::::t BB:::::BBBBBB::::::B y:::::::y -E::::::::::::::::::::E d:::::::::::::::::di::::::i tt::::::::::::::t B:::::::::::::::::B y:::::y -E::::::::::::::::::::E d:::::::::ddd::::di::::::i tt:::::::::::tt B::::::::::::::::B y:::::y -EEEEEEEEEEEEEEEEEEEEEE ddddddddd dddddiiiiiiii ttttttttttt BBBBBBBBBBBBBBBBB y:::::y - y:::::y - y:::::y - y:::::y - y:::::y - yyyyyyy - - - - dddddddd -HHHHHHHHH HHHHHHHHH d::::::d -H:::::::H H:::::::H d::::::d -H:::::::H H:::::::H d::::::d -HH::::::H H::::::HH d:::::d - H:::::H H:::::H aaaaaaaaaaaaa nnnn nnnnnnnn ddddddddd:::::d - H:::::H H:::::H a::::::::::::a n:::nn::::::::nn dd::::::::::::::d - H::::::HHHHH::::::H aaaaaaaaa:::::an::::::::::::::nn d::::::::::::::::d - H:::::::::::::::::H a::::ann:::::::::::::::nd:::::::ddddd:::::d - H:::::::::::::::::H aaaaaaa:::::a n:::::nnnn:::::nd::::::d d:::::d - H::::::HHHHH::::::H aa::::::::::::a n::::n n::::nd:::::d d:::::d - H:::::H H:::::H a::::aaaa::::::a n::::n n::::nd:::::d d:::::d - H:::::H H:::::H a::::a a:::::a n::::n n::::nd:::::d d:::::d -HH::::::H H::::::HHa::::a a:::::a n::::n n::::nd::::::ddddd::::::dd -H:::::::H H:::::::Ha:::::aaaa::::::a n::::n n::::n d:::::::::::::::::d -H:::::::H H:::::::H a::::::::::aa:::a n::::n n::::n d:::::::::ddd::::d -HHHHHHHHH HHHHHHHHH aaaaaaaaaa aaaa nnnnnn nnnnnn ddddddddd ddddd +# DDDDDDDDDDDDD NNNNNNNN NNNNNNNN tttt +# D::::::::::::DDD N:::::::N N::::::N ttt:::t +# D:::::::::::::::DD N::::::::N N::::::N t:::::t +# DDD:::::DDDDD:::::D N:::::::::N N::::::N t:::::t +# D:::::D D:::::D ooooooooooo N::::::::::N N::::::N ooooooooooo ttttttt:::::ttttttt +# D:::::D D:::::D oo:::::::::::oo N:::::::::::N N::::::N oo:::::::::::oo t:::::::::::::::::t +# D:::::D D:::::Do:::::::::::::::o N:::::::N::::N N::::::No:::::::::::::::ot:::::::::::::::::t +# D:::::D D:::::Do:::::ooooo:::::o N::::::N N::::N N::::::No:::::ooooo:::::otttttt:::::::tttttt +# D:::::D D:::::Do::::o o::::o N::::::N N::::N:::::::No::::o o::::o t:::::t +# D:::::D D:::::Do::::o o::::o N::::::N N:::::::::::No::::o o::::o t:::::t +# D:::::D D:::::Do::::o o::::o N::::::N N::::::::::No::::o o::::o t:::::t +# D:::::D D:::::D o::::o o::::o N::::::N N:::::::::No::::o o::::o t:::::t tttttt +# DDD:::::DDDDD:::::D o:::::ooooo:::::o N::::::N N::::::::No:::::ooooo:::::o t::::::tttt:::::t +# D:::::::::::::::DD o:::::::::::::::o N::::::N N:::::::No:::::::::::::::o tt::::::::::::::t +# D::::::::::::DDD oo:::::::::::oo N::::::N N::::::N oo:::::::::::oo tt:::::::::::tt +# DDDDDDDDDDDDD ooooooooooo NNNNNNNN NNNNNNN ooooooooooo ttttttttttt +# +# +# +# +# +# +# +# +# dddddddd +# EEEEEEEEEEEEEEEEEEEEEE d::::::d iiii tttt BBBBBBBBBBBBBBBBB +# E::::::::::::::::::::E d::::::d i::::i ttt:::t B::::::::::::::::B +# E::::::::::::::::::::E d::::::d iiii t:::::t B::::::BBBBBB:::::B +# EE::::::EEEEEEEEE::::E d:::::d t:::::t BB:::::B B:::::B +# E:::::E EEEEEE ddddddddd:::::d iiiiiiittttttt:::::ttttttt B::::B B:::::Byyyyyyy yyyyyyy +# E:::::E dd::::::::::::::d i:::::it:::::::::::::::::t B::::B B:::::B y:::::y y:::::y +# E::::::EEEEEEEEEE d::::::::::::::::d i::::it:::::::::::::::::t B::::BBBBBB:::::B y:::::y y:::::y +# E:::::::::::::::E d:::::::ddddd:::::d i::::itttttt:::::::tttttt B:::::::::::::BB y:::::y y:::::y +# E:::::::::::::::E d::::::d d:::::d i::::i t:::::t B::::BBBBBB:::::B y:::::y y:::::y +# E::::::EEEEEEEEEE d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y y:::::y +# E:::::E d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y:::::y +# E:::::E EEEEEEd:::::d d:::::d i::::i t:::::t tttttt B::::B B:::::B y:::::::::y +# EE::::::EEEEEEEE:::::Ed::::::ddddd::::::ddi::::::i t::::::tttt:::::t BB:::::BBBBBB::::::B y:::::::y +# E::::::::::::::::::::E d:::::::::::::::::di::::::i tt::::::::::::::t B:::::::::::::::::B y:::::y +# E::::::::::::::::::::E d:::::::::ddd::::di::::::i tt:::::::::::tt B::::::::::::::::B y:::::y +# EEEEEEEEEEEEEEEEEEEEEE ddddddddd dddddiiiiiiii ttttttttttt BBBBBBBBBBBBBBBBB y:::::y +# y:::::y +# y:::::y +# y:::::y +# y:::::y +# yyyyyyy +# +# +# +# dddddddd +# HHHHHHHHH HHHHHHHHH d::::::d +# H:::::::H H:::::::H d::::::d +# H:::::::H H:::::::H d::::::d +# HH::::::H H::::::HH d:::::d +# H:::::H H:::::H aaaaaaaaaaaaa nnnn nnnnnnnn ddddddddd:::::d +# H:::::H H:::::H a::::::::::::a n:::nn::::::::nn dd::::::::::::::d +# H::::::HHHHH::::::H aaaaaaaaa:::::an::::::::::::::nn d::::::::::::::::d +# H:::::::::::::::::H a::::ann:::::::::::::::nd:::::::ddddd:::::d +# H:::::::::::::::::H aaaaaaa:::::a n:::::nnnn:::::nd::::::d d:::::d +# H::::::HHHHH::::::H aa::::::::::::a n::::n n::::nd:::::d d:::::d +# H:::::H H:::::H a::::aaaa::::::a n::::n n::::nd:::::d d:::::d +# H:::::H H:::::H a::::a a:::::a n::::n n::::nd:::::d d:::::d +# HH::::::H H::::::HHa::::a a:::::a n::::n n::::nd::::::ddddd::::::dd +# H:::::::H H:::::::Ha:::::aaaa::::::a n::::n n::::n d:::::::::::::::::d +# H:::::::H H:::::::H a::::::::::aa:::a n::::n n::::n d:::::::::ddd::::d +# HHHHHHHHH HHHHHHHHH aaaaaaaaaa aaaa nnnnnn nnnnnn ddddddddd ddddd diff --git a/sasdata/quantities/units.py b/sasdata/quantities/units.py index 7d03abda0..8615c5ca4 100644 --- a/sasdata/quantities/units.py +++ b/sasdata/quantities/units.py @@ -7,72 +7,72 @@ -DDDDDDDDDDDDD NNNNNNNN NNNNNNNN tttt -D::::::::::::DDD N:::::::N N::::::N ttt:::t -D:::::::::::::::DD N::::::::N N::::::N t:::::t -DDD:::::DDDDD:::::D N:::::::::N N::::::N t:::::t - D:::::D D:::::D ooooooooooo N::::::::::N N::::::N ooooooooooo ttttttt:::::ttttttt - D:::::D D:::::D oo:::::::::::oo N:::::::::::N N::::::N oo:::::::::::oo t:::::::::::::::::t - D:::::D D:::::Do:::::::::::::::o N:::::::N::::N N::::::No:::::::::::::::ot:::::::::::::::::t - D:::::D D:::::Do:::::ooooo:::::o N::::::N N::::N N::::::No:::::ooooo:::::otttttt:::::::tttttt - D:::::D D:::::Do::::o o::::o N::::::N N::::N:::::::No::::o o::::o t:::::t - D:::::D D:::::Do::::o o::::o N::::::N N:::::::::::No::::o o::::o t:::::t - D:::::D D:::::Do::::o o::::o N::::::N N::::::::::No::::o o::::o t:::::t - D:::::D D:::::D o::::o o::::o N::::::N N:::::::::No::::o o::::o t:::::t tttttt -DDD:::::DDDDD:::::D o:::::ooooo:::::o N::::::N N::::::::No:::::ooooo:::::o t::::::tttt:::::t -D:::::::::::::::DD o:::::::::::::::o N::::::N N:::::::No:::::::::::::::o tt::::::::::::::t -D::::::::::::DDD oo:::::::::::oo N::::::N N::::::N oo:::::::::::oo tt:::::::::::tt -DDDDDDDDDDDDD ooooooooooo NNNNNNNN NNNNNNN ooooooooooo ttttttttttt - - - - - - - - - dddddddd -EEEEEEEEEEEEEEEEEEEEEE d::::::d iiii tttt BBBBBBBBBBBBBBBBB -E::::::::::::::::::::E d::::::d i::::i ttt:::t B::::::::::::::::B -E::::::::::::::::::::E d::::::d iiii t:::::t B::::::BBBBBB:::::B -EE::::::EEEEEEEEE::::E d:::::d t:::::t BB:::::B B:::::B - E:::::E EEEEEE ddddddddd:::::d iiiiiiittttttt:::::ttttttt B::::B B:::::Byyyyyyy yyyyyyy - E:::::E dd::::::::::::::d i:::::it:::::::::::::::::t B::::B B:::::B y:::::y y:::::y - E::::::EEEEEEEEEE d::::::::::::::::d i::::it:::::::::::::::::t B::::BBBBBB:::::B y:::::y y:::::y - E:::::::::::::::E d:::::::ddddd:::::d i::::itttttt:::::::tttttt B:::::::::::::BB y:::::y y:::::y - E:::::::::::::::E d::::::d d:::::d i::::i t:::::t B::::BBBBBB:::::B y:::::y y:::::y - E::::::EEEEEEEEEE d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y y:::::y - E:::::E d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y:::::y - E:::::E EEEEEEd:::::d d:::::d i::::i t:::::t tttttt B::::B B:::::B y:::::::::y -EE::::::EEEEEEEE:::::Ed::::::ddddd::::::ddi::::::i t::::::tttt:::::t BB:::::BBBBBB::::::B y:::::::y -E::::::::::::::::::::E d:::::::::::::::::di::::::i tt::::::::::::::t B:::::::::::::::::B y:::::y -E::::::::::::::::::::E d:::::::::ddd::::di::::::i tt:::::::::::tt B::::::::::::::::B y:::::y -EEEEEEEEEEEEEEEEEEEEEE ddddddddd dddddiiiiiiii ttttttttttt BBBBBBBBBBBBBBBBB y:::::y - y:::::y - y:::::y - y:::::y - y:::::y - yyyyyyy - - - - dddddddd -HHHHHHHHH HHHHHHHHH d::::::d -H:::::::H H:::::::H d::::::d -H:::::::H H:::::::H d::::::d -HH::::::H H::::::HH d:::::d - H:::::H H:::::H aaaaaaaaaaaaa nnnn nnnnnnnn ddddddddd:::::d - H:::::H H:::::H a::::::::::::a n:::nn::::::::nn dd::::::::::::::d - H::::::HHHHH::::::H aaaaaaaaa:::::an::::::::::::::nn d::::::::::::::::d - H:::::::::::::::::H a::::ann:::::::::::::::nd:::::::ddddd:::::d - H:::::::::::::::::H aaaaaaa:::::a n:::::nnnn:::::nd::::::d d:::::d - H::::::HHHHH::::::H aa::::::::::::a n::::n n::::nd:::::d d:::::d - H:::::H H:::::H a::::aaaa::::::a n::::n n::::nd:::::d d:::::d - H:::::H H:::::H a::::a a:::::a n::::n n::::nd:::::d d:::::d -HH::::::H H::::::HHa::::a a:::::a n::::n n::::nd::::::ddddd::::::dd -H:::::::H H:::::::Ha:::::aaaa::::::a n::::n n::::n d:::::::::::::::::d -H:::::::H H:::::::H a::::::::::aa:::a n::::n n::::n d:::::::::ddd::::d -HHHHHHHHH HHHHHHHHH aaaaaaaaaa aaaa nnnnnn nnnnnn ddddddddd ddddd +# DDDDDDDDDDDDD NNNNNNNN NNNNNNNN tttt +# D::::::::::::DDD N:::::::N N::::::N ttt:::t +# D:::::::::::::::DD N::::::::N N::::::N t:::::t +# DDD:::::DDDDD:::::D N:::::::::N N::::::N t:::::t +# D:::::D D:::::D ooooooooooo N::::::::::N N::::::N ooooooooooo ttttttt:::::ttttttt +# D:::::D D:::::D oo:::::::::::oo N:::::::::::N N::::::N oo:::::::::::oo t:::::::::::::::::t +# D:::::D D:::::Do:::::::::::::::o N:::::::N::::N N::::::No:::::::::::::::ot:::::::::::::::::t +# D:::::D D:::::Do:::::ooooo:::::o N::::::N N::::N N::::::No:::::ooooo:::::otttttt:::::::tttttt +# D:::::D D:::::Do::::o o::::o N::::::N N::::N:::::::No::::o o::::o t:::::t +# D:::::D D:::::Do::::o o::::o N::::::N N:::::::::::No::::o o::::o t:::::t +# D:::::D D:::::Do::::o o::::o N::::::N N::::::::::No::::o o::::o t:::::t +# D:::::D D:::::D o::::o o::::o N::::::N N:::::::::No::::o o::::o t:::::t tttttt +# DDD:::::DDDDD:::::D o:::::ooooo:::::o N::::::N N::::::::No:::::ooooo:::::o t::::::tttt:::::t +# D:::::::::::::::DD o:::::::::::::::o N::::::N N:::::::No:::::::::::::::o tt::::::::::::::t +# D::::::::::::DDD oo:::::::::::oo N::::::N N::::::N oo:::::::::::oo tt:::::::::::tt +# DDDDDDDDDDDDD ooooooooooo NNNNNNNN NNNNNNN ooooooooooo ttttttttttt +# +# +# +# +# +# +# +# +# dddddddd +# EEEEEEEEEEEEEEEEEEEEEE d::::::d iiii tttt BBBBBBBBBBBBBBBBB +# E::::::::::::::::::::E d::::::d i::::i ttt:::t B::::::::::::::::B +# E::::::::::::::::::::E d::::::d iiii t:::::t B::::::BBBBBB:::::B +# EE::::::EEEEEEEEE::::E d:::::d t:::::t BB:::::B B:::::B +# E:::::E EEEEEE ddddddddd:::::d iiiiiiittttttt:::::ttttttt B::::B B:::::Byyyyyyy yyyyyyy +# E:::::E dd::::::::::::::d i:::::it:::::::::::::::::t B::::B B:::::B y:::::y y:::::y +# E::::::EEEEEEEEEE d::::::::::::::::d i::::it:::::::::::::::::t B::::BBBBBB:::::B y:::::y y:::::y +# E:::::::::::::::E d:::::::ddddd:::::d i::::itttttt:::::::tttttt B:::::::::::::BB y:::::y y:::::y +# E:::::::::::::::E d::::::d d:::::d i::::i t:::::t B::::BBBBBB:::::B y:::::y y:::::y +# E::::::EEEEEEEEEE d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y y:::::y +# E:::::E d:::::d d:::::d i::::i t:::::t B::::B B:::::B y:::::y:::::y +# E:::::E EEEEEEd:::::d d:::::d i::::i t:::::t tttttt B::::B B:::::B y:::::::::y +# EE::::::EEEEEEEE:::::Ed::::::ddddd::::::ddi::::::i t::::::tttt:::::t BB:::::BBBBBB::::::B y:::::::y +# E::::::::::::::::::::E d:::::::::::::::::di::::::i tt::::::::::::::t B:::::::::::::::::B y:::::y +# E::::::::::::::::::::E d:::::::::ddd::::di::::::i tt:::::::::::tt B::::::::::::::::B y:::::y +# EEEEEEEEEEEEEEEEEEEEEE ddddddddd dddddiiiiiiii ttttttttttt BBBBBBBBBBBBBBBBB y:::::y +# y:::::y +# y:::::y +# y:::::y +# y:::::y +# yyyyyyy +# +# +# +# dddddddd +# HHHHHHHHH HHHHHHHHH d::::::d +# H:::::::H H:::::::H d::::::d +# H:::::::H H:::::::H d::::::d +# HH::::::H H::::::HH d:::::d +# H:::::H H:::::H aaaaaaaaaaaaa nnnn nnnnnnnn ddddddddd:::::d +# H:::::H H:::::H a::::::::::::a n:::nn::::::::nn dd::::::::::::::d +# H::::::HHHHH::::::H aaaaaaaaa:::::an::::::::::::::nn d::::::::::::::::d +# H:::::::::::::::::H a::::ann:::::::::::::::nd:::::::ddddd:::::d +# H:::::::::::::::::H aaaaaaa:::::a n:::::nnnn:::::nd::::::d d:::::d +# H::::::HHHHH::::::H aa::::::::::::a n::::n n::::nd:::::d d:::::d +# H:::::H H:::::H a::::aaaa::::::a n::::n n::::nd:::::d d:::::d +# H:::::H H:::::H a::::a a:::::a n::::n n::::nd:::::d d:::::d +# HH::::::H H::::::HHa::::a a:::::a n::::n n::::nd::::::ddddd::::::dd +# H:::::::H H:::::::Ha:::::aaaa::::::a n::::n n::::n d:::::::::::::::::d +# H:::::::H H:::::::H a::::::::::aa:::a n::::n n::::n d:::::::::ddd::::d +# HHHHHHHHH HHHHHHHHH aaaaaaaaaa aaaa nnnnnn nnnnnn ddddddddd ddddd