Skip to content

fix: replace dead streamlines URL with Allen mesoscale connectivity via cloud-volume#438

Open
AdityaGupta716 wants to merge 13 commits intobrainglobe:mainfrom
AdityaGupta716:fix/streamlines-url
Open

fix: replace dead streamlines URL with Allen mesoscale connectivity via cloud-volume#438
AdityaGupta716 wants to merge 13 commits intobrainglobe:mainfrom
AdityaGupta716:fix/streamlines-url

Conversation

@AdityaGupta716
Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes the broken streamlines functionality by replacing the defunct
neuroinformatics.nl cache with the official Allen mesoscale connectivity
dataset hosted on Google Cloud Storage.

Why is this needed?

Closes #266

The URL https://neuroinformatics.nl/HBP/allen-connectivity-viewer/json/streamlines_*.json.gz
returns 403 Forbidden. This was a third-party cache that is no longer maintained.

Changes

  • Replaced dead URL with precomputed://gs://allen_neuroglancer_ccf/allen_mesoscale
    accessed via cloud-volume — the official source recommended by AIBS (@fcollman)
  • Rewrote get_streamlines_data() to fetch skeleton data using cloudvolume.CloudVolume
  • Added _skeleton_to_dataframe() to convert the new precomputed skeleton format
    (vertices in nm + edges) back to the {"x", "y", "z"} dict format expected by
    Streamlines._make_mesh()
  • Added DV axis flip (y = 8000 - y) to convert from Allen CCF PIR space to
    brainrender's ASR orientation
  • Added _get_injection_site_um() to fetch real injection coordinates from the Allen
    Brain Atlas API (ProjectionStructureUnionize) instead of using an approximation
  • Added graceful fallback to vertex centroid if Allen API is unreachable
  • Added cloud-volume to pyproject.toml dependencies
  • Preserved the existing local JSON caching behaviour and force_download flag

How was this tested?

  • Verified the GCS bucket is live and accessible
  • Fetched skeleton for experiment 479983421, confirmed 602 streamline components
  • Verified coordinate ranges match Allen CCF atlas mesh ranges for TH after axis correction
  • Confirmed real injection site coordinates match expected values from Allen API
  • Verified output DataFrame format is fully compatible with existing Streamlines actor

Is this a breaking change?

No — the public API (get_streamlines_data, get_streamlines_for_region) is unchanged.
The output DataFrame format is identical to the old format.

Does this require a documentation update?

Yes — users will need cloud-volume installed. This is now listed as a dependency
in pyproject.toml so it will be installed automatically.

@AdityaGupta716
Copy link
Copy Markdown
Contributor Author

Hey @alessandrofelder @adamltyson, please review!
Replaces the defunct neuroinformatics.nl cache with the official Allen mesoscale GCS dataset via cloud-volume (as suggested by @fcollman). Handles coordinate conversion, DV axis flip, and real injection sites from the Allen API. Full visual render testing wasn't possible here due to Python 3.14 C++ dependency issues — would appreciate if someone could run examples/streamlines.py to confirm visual alignment. Closes #266.

@adamltyson
Copy link
Copy Markdown
Member

Thanks for raising this @AdityaGupta716. This seems like a fairly big change, could you add some tests? Also could you make sure this works locally for you before asking reviewers to check it?

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 2, 2026

Codecov Report

❌ Patch coverage is 98.24561% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 87.82%. Comparing base (42c6ef1) to head (c1c1938).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
...er/atlas_specific/allen_brain_atlas/streamlines.py 98.24% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #438      +/-   ##
==========================================
+ Coverage   86.60%   87.82%   +1.21%     
==========================================
  Files          27       27              
  Lines        1239     1281      +42     
==========================================
+ Hits         1073     1125      +52     
+ Misses        166      156      -10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AdityaGupta716
Copy link
Copy Markdown
Contributor Author

Hi @adamltyson, I've added unit tests with mocked I/O covering the main functions and also verified it works locally — attached a screenshot of the render for experiment , you can see the brain mesh, injection site, and streamlines all coming through correctly. Let me know if there's anything else you'd like me to change!

Screenshot 2026-03-03 at 1 38 36 AM

@RobertoDF
Copy link
Copy Markdown
Contributor

Hi, I tested this and there is still a small issue :

from https://connectivity.brain-map.org/projection/experiment/298004028?imageId=298004308&initImage=TWO_PHOTON&x=22791&y=11608
image

here from this pull request
image

it is somhow flipped. tried to modify this but coludnt solve it:


        points = [
            {
                "x": float(v[0]),
                "y": float(dv_extent_um - v[1]),  # flip DV axis
                "z": float(v[2]),
            }
            for v in verts_um
        ]
        lines.append(points)

Amazing work getting this to work again!

@RobertoDF
Copy link
Copy Markdown
Contributor

RobertoDF commented Mar 26, 2026

solved it here AdityaGupta716#1

image

AdityaGupta716 and others added 2 commits April 5, 2026 20:35
Numerical verification showed brainrender's atlas mesh vertices use raw
Allen CCF (PIR) coordinates, so no PIR→ASR conversion is needed.

Removed _get_atlas_extents_um, _get_dv_extent_um, and all axis flip logic.
Skeleton vertices are now passed through as-is after nm→um conversion.

Co-developed-by: RobertoDF (identified the flip issue in brainglobe#438)
Copy link
Copy Markdown
Member

@IgorTatarnikov IgorTatarnikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AdityaGupta716, this is great, thanks!

There seems to be a LR mirror/flip that's missing in the current code. The below screenshot was generated using the below code. According to https://connectivity.brain-map.org/projection/experiment/298004028?imageId=298004308&initImage=TWO_PHOTON&x=22791&y=11608, the streamlines should be in the right hemisphere, whereas in brainrender they show up in the left hemisphere (I specifically added right TH instead of both). I think this needs to be addressed before we can proceed further.

Code
from pathlib import Path

from myterial import orange
from rich import print

from brainrender import Scene
from brainrender.actors.streamlines import make_streamlines
from brainrender.atlas_specific.allen_brain_atlas.streamlines import get_streamlines_data

print(f"[{orange}]Running example: {Path(__file__).name}")

# Create a brainrender scene
scene = Scene()

# Add brain regions
scene.add_brain_region("TH", hemisphere="right")

# Get streamlines data and add
streams = get_streamlines_data([298004028])
scene.add(*make_streamlines(*streams, color="salmon", alpha=0.5))

# Render!
scene.render()
Image

@@ -1,4 +1,5 @@
import pandas as pd
import requests as http_requests
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to alias unless absolutely necessary! It adds a bit of extra friction when reading the code as requests is a common library that's used across many Python projects.

Suggested change
import requests as http_requests
import requests

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have at least one test that downloads a small experiment and an injection site to make sure the data sources are still accessible.

@AdityaGupta716
Copy link
Copy Markdown
Contributor Author

hi @IgorTatarnikov, thanks for the review , i added a Z (medial-lateral) axis flip (z = ml_extent - z) to fix the hemisphere issue and also renamed import requests as http_requests to just import requests and added an integration test that downloads experiment 479983421 from GCS to make sure the data source stays live,also moved cloud-volume out of hard dependencies since the code already handles it being missing .
Screenshot 2026-04-08 at 11 39 31 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG streamlines URL has changed

4 participants