codecov-io: # [Codecov](https://codecov.io/gh/spacetx/starfish/pull/1602?src=pr&el=h1) Report
> Merging [#1602](https://codecov.io/gh/spacetx/starfish/pull/1602?src=pr&el=desc) into [tonytung-fix-dims-alltest](https://codecov.io/gh/spacetx/starfish/commit/005b513b753f36540021331ae7ccf1fc78ff9448?src=pr&el=desc) will **decrease** coverage by `31.94%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/spacetx/starfish/pull/1602/graphs/tree.svg?width=650&token=kliQHejt6T&height=150&src=pr)](https://codecov.io/gh/spacetx/starfish/pull/1602?src=pr&el=tree)

```diff
@@                      Coverage Diff                      @@
##           tonytung-fix-dims-alltest   #1602       +/-   ##
=============================================================
- Coverage                      87.54%   55.6%   -31.95%     
=============================================================
  Files                            145     145               
  Lines                           5036    5041        +5     
=============================================================
- Hits                            4409    2803     -1606     
- Misses                           627    2238     +1611
```


| [Impacted Files](https://codecov.io/gh/spacetx/starfish/pull/1602?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [starfish/core/codebook/codebook.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvY29yZS9jb2RlYm9vay9jb2RlYm9vay5weQ==) | `83.11% <100%> (-13.53%)` | :arrow_down: |
| [starfish/test/full\_pipelines/api/test\_dartfish.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvdGVzdC9mdWxsX3BpcGVsaW5lcy9hcGkvdGVzdF9kYXJ0ZmlzaC5weQ==) | `19.67% <0%> (-80.33%)` | :arrow_down: |
| [...e/experiment/builder/test/factories/all\_purpose.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvY29yZS9leHBlcmltZW50L2J1aWxkZXIvdGVzdC9mYWN0b3JpZXMvYWxsX3B1cnBvc2UucHk=) | `21.27% <0%> (-78.73%)` | :arrow_down: |
| [starfish/test/full\_pipelines/api/test\_iss\_api.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvdGVzdC9mdWxsX3BpcGVsaW5lcy9hcGkvdGVzdF9pc3NfYXBpLnB5) | `23.07% <0%> (-76.93%)` | :arrow_down: |
| [starfish/test/full\_pipelines/api/test\_merfish.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvdGVzdC9mdWxsX3BpcGVsaW5lcy9hcGkvdGVzdF9tZXJmaXNoLnB5) | `24.39% <0%> (-75.61%)` | :arrow_down: |
| [...ilder/test/structured\_formatter/test\_single\_fov.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvY29yZS9leHBlcmltZW50L2J1aWxkZXIvdGVzdC9zdHJ1Y3R1cmVkX2Zvcm1hdHRlci90ZXN0X3NpbmdsZV9mb3YucHk=) | `24.63% <0%> (-75.37%)` | :arrow_down: |
| [...re/spots/DetectSpots/local\_search\_blob\_detector.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvY29yZS9zcG90cy9EZXRlY3RTcG90cy9sb2NhbF9zZWFyY2hfYmxvYl9kZXRlY3Rvci5weQ==) | `25% <0%> (-70.2%)` | :arrow_down: |
| [...re/spots/DetectPixels/combine\_adjacent\_features.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvY29yZS9zcG90cy9EZXRlY3RQaXhlbHMvY29tYmluZV9hZGphY2VudF9mZWF0dXJlcy5weQ==) | `28.44% <0%> (-69.73%)` | :arrow_down: |
| [starfish/core/spacetx\_format/test\_fuzz.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvY29yZS9zcGFjZXR4X2Zvcm1hdC90ZXN0X2Z1enoucHk=) | `31.03% <0%> (-68.97%)` | :arrow_down: |
| [starfish/core/experiment/builder/\_\_init\_\_.py](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree#diff-c3RhcmZpc2gvY29yZS9leHBlcmltZW50L2J1aWxkZXIvX19pbml0X18ucHk=) | `29.21% <0%> (-67.42%)` | :arrow_down: |
| ... and [76 more](https://codecov.io/gh/spacetx/starfish/pull/1602/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/spacetx/starfish/pull/1602?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/spacetx/starfish/pull/1602?src=pr&el=footer). Last update [005b513...a29ddc6](https://codecov.io/gh/spacetx/starfish/pull/1602?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

diff --git a/notebooks/ISS.ipynb b/notebooks/ISS.ipynb
index d6bf6dbc..ad5fe1b5 100644
--- a/notebooks/ISS.ipynb
+++ b/notebooks/ISS.ipynb
@@ -450,4 +450,4 @@
  },
  "nbformat": 4,
  "nbformat_minor": 2
-}
\ No newline at end of file
+}
diff --git a/starfish/core/codebook/codebook.py b/starfish/core/codebook/codebook.py
index 62a912bb..c531625d 100644
--- a/starfish/core/codebook/codebook.py
+++ b/starfish/core/codebook/codebook.py
@@ -651,7 +651,16 @@ class Codebook(xr.DataArray):
                 distances=(Features.AXIS, np.empty(0, dtype=np.float64)),
                 passes_threshold=(Features.AXIS, np.empty(0, dtype=bool)))
 
-        max_channels = intensities.argmax(Axes.CH.value)
+        intensities_without_nans = intensities.fillna(0)
+        max_channels = intensities_without_nans.argmax(Axes.CH.value)
+        # this snippet of code finds all the (feature, round) spots that have uniform illumination,
+        # and assigns them to a ch number that's one larger than max possible to ensure that such
+        # spots decode to `NaN`.
+        max_channels_max = intensities_without_nans.reduce(np.amax, Axes.CH.value)
+        max_channels_min = intensities_without_nans.reduce(np.amin, Axes.CH.value)
+        uniform_illumination_mask = (max_channels_max == max_channels_min).values
+
+        max_channels.values[uniform_illumination_mask] = intensities.sizes[Axes.CH.value]
         codes = self.argmax(Axes.CH.value)
 
         # TODO ambrosejcarr, dganguli: explore this quality score further

decoding method in seqFISH
after generation of intensityTable by LocalSearchBlobDetecor I use codebook.decode_per_round_max(intensities) to decode each spot. It does not work(error: all-Nan slice encountered).
<img width="923" alt="Screenshot 2019-08-06 at 19 43 20" src="https://user-images.githubusercontent.com/50377927/62563690-d24d0400-b883-11e9-9582-5d20d8d2449e.png">
                                                  
diff --git a/starfish/core/codebook/test/test_per_round_max_decode.py b/starfish/core/codebook/test/test_per_round_max_decode.py
index d7cd5a07..29077cec 100644
--- a/starfish/core/codebook/test/test_per_round_max_decode.py
+++ b/starfish/core/codebook/test/test_per_round_max_decode.py
@@ -155,3 +155,42 @@ def test_argmax_selects_the_last_equal_intensity_channel_and_decodes_consistentl
 
     decoded_intensities = codebook.decode_per_round_max(intensities)
     assert np.array_equal(decoded_intensities[Features.TARGET].values, ['nan', 'GENE_A'])
+
+
+def test_argmax_does_not_select_first_code():
+    """
+    When all the channels in a round are uniform, argmax erroneously picks the first channel as the
+    max.  In this case, it incorrectly assigns the wrong code for that round.  This test ensures
+    that the workaround we put in for this works correctly.
+    """
+
+    data = np.array(
+        [[[0.0, 1.0],
+          [1.0, 1.0]],  # this round is uniform, so it will erroneously be decoded as the first ch.
+         [[0.0, 1.0],
+          [1.0, 0.0]]]
+    )
+    intensities = intensity_table_factory(data)
+    codebook = codebook_factory()
+
+    decoded_intensities = codebook.decode_per_round_max(intensities)
+    assert np.array_equal(decoded_intensities[Features.TARGET].values, ['nan', 'GENE_A'])
+
+
+def test_feature_round_all_nan():
+    """
+    When all the channels in a round are NaN, argmax chokes.  This test ensures that the workaround
+    we put in for this works correctly.
+    """
+
+    data = np.array(
+        [[[0.0, 1.0],
+          [np.nan, np.nan]],
+         [[0.0, 1.0],
+          [1.0, 0.0]]]
+    )
+    intensities = intensity_table_factory(data)
+    codebook = codebook_factory()
+
+    decoded_intensities = codebook.decode_per_round_max(intensities)
+    assert np.array_equal(decoded_intensities[Features.TARGET].values, ['nan', 'GENE_A'])
diff --git a/starfish/test/full_pipelines/api/test_iss_api.py b/starfish/test/full_pipelines/api/test_iss_api.py
index b197ce89..7fb2ec7f 100644
--- a/starfish/test/full_pipelines/api/test_iss_api.py
+++ b/starfish/test/full_pipelines/api/test_iss_api.py
@@ -105,7 +105,7 @@ def test_iss_pipeline_cropped_data(tmpdir):
     assert np.array_equal(genes, np.array(['ACTB', 'CD68', 'CTSL2', 'EPCAM',
                                            'ETV4', 'GAPDH', 'GUS', 'HER2', 'RAC1',
                                            'TFRC', 'TP53', 'VEGF']))
-    assert np.array_equal(gene_counts, [20, 1, 5, 2, 1, 11, 1, 3, 2, 1, 1, 2])
+    assert np.array_equal(gene_counts, [19, 1, 5, 2, 1, 11, 1, 3, 2, 1, 1, 2])
 
     masks = iss.masks
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-cov pytest-xdist
3.6
REQUIREMENTS.txt REQUIREMENTS-CI.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
async-generator==1.10
attrs==22.2.0
Babel==2.11.0
backcall==0.2.0
bleach==4.1.0
boto3==1.23.10
botocore==1.26.10
certifi==2021.5.30
cffi==1.15.1
charset-normalizer==2.0.12
click==8.0.4
colorama==0.4.5
comm==0.1.4
commonmark==0.9.1
coverage==6.2
cryptography==40.0.2
cycler==0.11.0
dataclasses==0.8
decorator==4.4.2
defusedxml==0.7.1
diskcache==5.6.3
docutils==0.18.1
entrypoints==0.3
execnet==1.9.0
flake8==3.7.9
flake8-import-order==0.18.2
idna==3.10
imageio==2.15.0
imagesize==1.4.1
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
ipykernel==5.5.6
ipython==7.16.3
ipython-genutils==0.2.0
ipywidgets==7.8.5
jedi==0.17.2
jeepney==0.7.1
Jinja2==3.0.3
jmespath==0.10.0
joblib==1.1.1
jsonschema==3.2.0
jupyter-client==7.1.2
jupyter-core==4.9.2
jupyterlab-pygments==0.1.2
jupyterlab_widgets==1.1.11
keyring==23.4.1
kiwisolver==1.3.1
m2r==0.3.1
MarkupSafe==2.0.1
matplotlib==3.3.4
mccabe==0.6.1
mistune==0.8.4
mpmath==1.3.0
mypy==0.971
mypy-extensions==1.0.0
nbclient==0.5.9
nbconvert==6.0.7
nbencdec==0.0.10
nbformat==5.1.3
nest-asyncio==1.6.0
networkx==2.5.1
notebook==6.4.10
numpy==1.19.5
numpydoc==1.1.0
packaging==21.3
pandas==1.1.5
pandocfilters==1.5.1
parso==0.7.1
pexpect==4.9.0
pickleshare==0.7.5
Pillow==8.4.0
pkginfo==1.10.0
pluggy==1.0.0
prometheus-client==0.17.1
prompt-toolkit==3.0.36
ptyprocess==0.7.0
py==1.11.0
pycodestyle==2.5.0
pycparser==2.21
pyflakes==2.1.1
Pygments==2.14.0
pyparsing==3.1.4
pyrsistent==0.18.0
pytest==7.0.1
pytest-cov==4.0.0
pytest-xdist==3.0.2
python-dateutil==2.9.0.post0
pytz==2025.2
PyWavelets==1.1.1
PyYAML==6.0.1
pyzmq==25.1.2
readme-renderer==34.0
recommonmark==0.7.1
regional==1.1.2
requests==2.27.1
requests-toolbelt==1.0.0
rfc3986==1.5.0
s3transfer==0.5.2
scikit-image==0.17.2
scikit-learn==0.24.2
scipy==1.5.4
seaborn==0.11.2
SecretStorage==3.3.3
semantic-version==2.10.0
Send2Trash==1.8.3
showit==1.1.4
six==1.17.0
slicedimage==4.0.4
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinx-autodoc-typehints==1.12.0
sphinx-bootstrap-theme==0.8.1
sphinx-gallery==0.10.0
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-programoutput==0.17
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
-e git+https://github.com/spacetx/starfish.git@81b1f7685317c9e6ec9581d5ae4d6260afede392#egg=starfish
sympy==1.9
terminado==0.12.1
testpath==0.6.0
threadpoolctl==3.1.0
tifffile==2020.9.3
tomli==1.2.3
tornado==6.1
tqdm==4.64.1
trackpy==0.5.0
traitlets==4.3.3
twine==3.8.0
typed-ast==1.5.5
typing_extensions==4.1.1
urllib3==1.26.20
validators==0.20.0
wcwidth==0.2.13
webencodings==0.5.1
widgetsnbextension==3.6.10
xarray==0.16.2
zipp==3.6.0

name: starfish
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - argon2-cffi==21.3.0
      - argon2-cffi-bindings==21.2.0
      - async-generator==1.10
      - attrs==22.2.0
      - babel==2.11.0
      - backcall==0.2.0
      - bleach==4.1.0
      - boto3==1.23.10
      - botocore==1.26.10
      - cffi==1.15.1
      - charset-normalizer==2.0.12
      - click==8.0.4
      - colorama==0.4.5
      - comm==0.1.4
      - commonmark==0.9.1
      - coverage==6.2
      - cryptography==40.0.2
      - cycler==0.11.0
      - dataclasses==0.8
      - decorator==4.4.2
      - defusedxml==0.7.1
      - diskcache==5.6.3
      - docutils==0.18.1
      - entrypoints==0.3
      - execnet==1.9.0
      - flake8==3.7.9
      - flake8-import-order==0.18.2
      - idna==3.10
      - imageio==2.15.0
      - imagesize==1.4.1
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - ipykernel==5.5.6
      - ipython==7.16.3
      - ipython-genutils==0.2.0
      - ipywidgets==7.8.5
      - jedi==0.17.2
      - jeepney==0.7.1
      - jinja2==3.0.3
      - jmespath==0.10.0
      - joblib==1.1.1
      - jsonschema==3.2.0
      - jupyter-client==7.1.2
      - jupyter-core==4.9.2
      - jupyterlab-pygments==0.1.2
      - jupyterlab-widgets==1.1.11
      - keyring==23.4.1
      - kiwisolver==1.3.1
      - m2r==0.3.1
      - markupsafe==2.0.1
      - matplotlib==3.3.4
      - mccabe==0.6.1
      - mistune==0.8.4
      - mpmath==1.3.0
      - mypy==0.971
      - mypy-extensions==1.0.0
      - nbclient==0.5.9
      - nbconvert==6.0.7
      - nbencdec==0.0.10
      - nbformat==5.1.3
      - nest-asyncio==1.6.0
      - networkx==2.5.1
      - notebook==6.4.10
      - numpy==1.19.5
      - numpydoc==1.1.0
      - packaging==21.3
      - pandas==1.1.5
      - pandocfilters==1.5.1
      - parso==0.7.1
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pillow==8.4.0
      - pkginfo==1.10.0
      - pluggy==1.0.0
      - prometheus-client==0.17.1
      - prompt-toolkit==3.0.36
      - ptyprocess==0.7.0
      - py==1.11.0
      - pycodestyle==2.5.0
      - pycparser==2.21
      - pyflakes==2.1.1
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pyrsistent==0.18.0
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - pytest-xdist==3.0.2
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pywavelets==1.1.1
      - pyyaml==6.0.1
      - pyzmq==25.1.2
      - readme-renderer==34.0
      - recommonmark==0.7.1
      - regional==1.1.2
      - requests==2.27.1
      - requests-toolbelt==1.0.0
      - rfc3986==1.5.0
      - s3transfer==0.5.2
      - scikit-image==0.17.2
      - scikit-learn==0.24.2
      - scipy==1.5.4
      - seaborn==0.11.2
      - secretstorage==3.3.3
      - semantic-version==2.10.0
      - send2trash==1.8.3
      - showit==1.1.4
      - six==1.17.0
      - slicedimage==4.0.4
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinx-autodoc-typehints==1.12.0
      - sphinx-bootstrap-theme==0.8.1
      - sphinx-gallery==0.10.0
      - sphinx-rtd-theme==2.0.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-programoutput==0.17
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - sympy==1.9
      - terminado==0.12.1
      - testpath==0.6.0
      - threadpoolctl==3.1.0
      - tifffile==2020.9.3
      - tomli==1.2.3
      - tornado==6.1
      - tqdm==4.64.1
      - trackpy==0.5.0
      - traitlets==4.3.3
      - twine==3.8.0
      - typed-ast==1.5.5
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - validators==0.20.0
      - wcwidth==0.2.13
      - webencodings==0.5.1
      - widgetsnbextension==3.6.10
      - xarray==0.16.2
      - zipp==3.6.0
prefix: /opt/conda/envs/starfish

starfish/core/codebook/test/test_per_round_max_decode.py::test_argmax_does_not_select_first_code starfish/core/codebook/test/test_per_round_max_decode.py::test_feature_round_all_nan
starfish/test/full_pipelines/api/test_iss_api.py::test_iss_pipeline_cropped_data
starfish/core/codebook/test/test_per_round_max_decode.py::test_intensity_tables_with_different_numbers_of_codes_or_channels_throw_value_error starfish/core/codebook/test/test_per_round_max_decode.py::test_example_intensity_decodes_to_gene_a starfish/core/codebook/test/test_per_round_max_decode.py::test_example_intensity_that_has_no_match_is_assigned_nan starfish/core/codebook/test/test_per_round_max_decode.py::test_argmax_selects_the_last_equal_intensity_channel_and_decodes_consistently
notebooks/ISS.ipynb starfish/core/codebook/codebook.py
notebooks/ISS.ipynb starfish/core/codebook/codebook.py