Skip to content

Generalize model operations: - #5

Merged
agahkarakuzu merged 26 commits into
mainfrom
fix/misc-cleanup
Jul 22, 2026
Merged

Generalize model operations:#5
agahkarakuzu merged 26 commits into
mainfrom
fix/misc-cleanup

Conversation

@agahkarakuzu

@agahkarakuzu agahkarakuzu commented Jul 22, 2026

Copy link
Copy Markdown
Member

Description:

Makes the model contribution surface fully generic, so adding a qMRI model is a module + trait impls + one registry line — no shell edits. Also folds in the doc/dead-code fixes and the recipes/ reorganization done along the way.

Core change — one seam per operation, dispatched via the registry:

  • Shared build pipeline (ModelConfig → build_model/describe_model/dump_model): every model composes its acquisition protocol from the resolved BIDS sidecars via ingest_protocol, in one place. qMT now fits through --bids-dir like IR — no special-casing.
  • dump-config and bidsify are generic (registry dump capability + the BidsVolume write-seam n_volumes/bids_volume). Deleted IrSidecar/QmtSidecar/bidsify_ir/bidsify_qmt and every match model.
  • Source-agnostic .mat (MatDataset { data, mask }); removed the IR-shaped ProtocolSource.

Also in this branch:

  • prots/ → recipes/{bids,non-bids,sim}/ with a README; fit --grouping to override the bundled BIDS grouping manifest.
  • Numeric-aware entity matching (flip: "1" matches flip-01); short/full BIDS entity keys both accepted.
  • Doc/code lockstep fixes (R1map suffix, engine::run arg order, wasm README) and removal of dead config fields + temporal-narrative comments.

Notes for reviewers:

  • Behavior change: the .mat fit path now takes its protocol from the recipe (in data order), not the file's embedded vector. Guarded by the *_bids_fit_matches_mat_fit round-trips and OSF integration — please run CI (those need OSF data).
  • One known follow-up: run_dump_sf (a qMT Sf-table debug command) still reads the qmt_spgr key directly — the last model-specific spot, out of scope here.

Summary by CodeRabbit

  • New Features
    • Added generic, model-driven BIDS export with per-volume NIfTI outputs, JSON sidecars, optional masks, and model-declared auxiliary inputs.
    • Added --grouping manifest support for BIDS fitting.
    • Added registry-backed model describe and config dump.
    • Updated wasm interface: fit_voxel/forward/fit_volume now use JSON payloads (measurement + volume IDs).
  • Bug Fixes
    • Improved BIDS entity matching with tolerant numeric ordering (e.g., zero-padded indices).
  • Documentation
    • Refreshed guides and examples to the recipes/ layout; updated BIDS grouping and wasm usage docs.
    • Clarified timing inputs: BIDS fitting uses dataset JSON sidecars (not .mat inversion times); non-BIDS .mat inversion-time overriding is removed.

Agah added 19 commits July 21, 2026 17:09
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b258e758-97dd-4975-a86b-bf8b061ecdef

📥 Commits

Reviewing files that changed from the base of the PR and between fc7363f and cdc15a2.

📒 Files selected for processing (1)
  • CLAUDE.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • CLAUDE.md

📝 Walkthrough

Walkthrough

The PR centralizes model configuration and protocol handling, adds model-driven BIDS writing and grouping overrides, removes MAT inversion-time overrides, introduces recipe directories, and updates BIDS resolution, documentation, tests, and integration commands.

Changes

Model-driven configuration and BIDS execution

Layer / File(s) Summary
Shared model lifecycle and BIDS contract
crates/qmrust-core/...
Adds shared model configuration hooks, registry describe/dump callbacks, protocol ingestion, and per-volume BIDS metadata contracts for inversion recovery and qMT-SPGR.
MAT input and fit orchestration
crates/qmrust-cli/src/io/mat.rs, crates/qmrust-cli/src/commands.rs, crates/qmrust-cli/src/main.rs
Replaces IR-specific MAT data with MatDataset, removes MAT-derived inversion-time overrides, and adds optional BIDS grouping manifests.
Generic BIDS tree generation
crates/qmrust-cli/src/bidsify.rs
Writes BIDS volumes, sidecars, masks, auxiliary derivatives, and custom-suffix handling through model-provided metadata.

BIDS grouping resolution

Layer / File(s) Summary
Grouping grammar and entity normalization
crates/rust-bids/src/config.rs, crates/rust-bids/src/default_grouping.yaml
Canonicalizes short and full entity keys and loads the default grouping grammar from embedded YAML.
Entity-aware ordering and matching
crates/rust-bids/src/entities.rs, crates/rust-bids/src/resolve.rs
Uses numeric comparison for integer-like entity values in sequential ordering and named-set matching.

Recipes and documentation migration

Layer / File(s) Summary
Recipe manifests and command wiring
recipes/*, README.md, CLAUDE.md, ci/integration_osf.sh, scripts/make_bids_examples.sh, docs/getting-started.md
Adds or updates BIDS, non-BIDS, and simulation recipes and changes examples and integration commands from prots/ to recipes/.
Model and pipeline documentation
docs/agents/*, docs/bids.md, docs/models.md, crates/qmrust-wasm/README.md
Documents the shared model lifecycle, BIDS grouping conventions, input sourcing, and updated wasm calling examples.

Estimated code review effort: 4 (Complex) | ~60 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main goal: generalizing model operations across registry-driven pipelines and generic model handling.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/misc-cleanup

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
CLAUDE.md (2)

111-111: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Specify the fenced-block language.

markdownlint-cli2 reports MD040 on this fence. Change the opening fence to ```text (or another appropriate language).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` at line 111, Specify a language on the fenced code block in
CLAUDE.md by changing its opening fence to use text (or another suitable
language identifier), while leaving the block contents unchanged.

Source: Linters/SAST tools


119-125: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Document the complete ModelConfig contract.

The example declares ModelConfig: DeserializeOwned, but crates/qmrust-core/src/core/model.rs also requires serde::Serialize + Default. Make this snippet match the actual trait so contributors do not omit required derives or implementations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` around lines 119 - 125, Update the ModelConfig contract in the
surrounding documentation to include serde::Serialize and Default alongside
DeserializeOwned, matching the bounds defined in the model configuration API.
Ensure the snippet clearly communicates that implementations must provide all
required derives or implementations.
🧹 Nitpick comments (4)
crates/qmrust-cli/src/commands.rs (1)

1159-1169: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Trim the historical-narrative sentence from this test doc comment.

"...so this would catch it where the old (grouping-content-insensitive) version of this test could not" narrates the test's prior state rather than describing what the test verifies now.

✏️ Proposed trim
     /// A `--grouping` manifest overriding the built-in default is actually
     /// threaded into collection resolution — not read and then ignored in
     /// favor of `rust_bids::default_config()`. Proven by contrast: the same
     /// synthetic IRT1 dataset that resolves and fits under the default
     /// grouping (`run_fit_bids_recovers_t1_from_a_synthetic_dataset`) fails
-    /// to resolve any `IRT1` collection under a custom manifest that omits
-    /// the `IRT1` set entirely. A regression that silently discarded the
-    /// custom grouping and fell back to the default would still resolve and
-    /// fit here, so this would catch it where the old (grouping-content-
-    /// insensitive) version of this test could not.
+    /// to resolve any `IRT1` collection under a custom manifest that omits
+    /// the `IRT1` set entirely. A regression that silently discarded the
+    /// custom grouping and fell back to the default would still resolve and
+    /// fit here, so this test would catch it.
     #[test]

As per coding guidelines, "Comments and docstrings must explain what code does and the invariant or contract behind it, not author decisions, alternatives, historical narratives, reviewer asides, or task references."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/qmrust-cli/src/commands.rs` around lines 1159 - 1169, Trim the doc
comment above the test by removing the historical sentence beginning with “A
regression that silently discarded...” and ending with “the old
(grouping-content-insensitive) version of this test could not.” Keep the
remaining description focused on verifying that a custom grouping manifest is
used during collection resolution.

Source: Coding guidelines

crates/qmrust-cli/src/io/mat.rs (2)

70-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the redundant/self-correcting comment lines in the 2D reshape branch.

Lines 71-73 restate and second-guess themselves ("But more commonly...", "Actually MATLAB 2D means...") before lines 75-77 give the actual, clear explanation. This reads as in-progress author reasoning rather than an invariant description.

🧹 Proposed cleanup
         2 => {
-            // (rows, cols) in MATLAB = (spatial, n_vol) — treat as (rows, 1, 1, cols)
-            // But more commonly the source data has shape (x, y, n_vol) stored as 2D
-            // Actually MATLAB 2D means (x*y, n_vol) or (x, n_vol)
             let (nrows, ncols) = (data_size[0], data_size[1]);
             // Treat as (nrows, 1, 1, ncols) — each row is a voxel, cols are volumes
             // MATLAB column-major: data is stored column by column
             // Column j values are at indices j*nrows..(j+1)*nrows
             let mut arr = Array4::<f64>::zeros((nrows, 1, 1, ncols));

As per coding guidelines, "Comments and docstrings must explain what code does and the invariant or contract behind it, not author decisions, alternatives, historical narratives, reviewer asides, or task references."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/qmrust-cli/src/io/mat.rs` around lines 70 - 78, Remove the
self-correcting comment lines in the 2D reshape branch before the nrows/ncols
assignment, specifically the “But more commonly...” and “Actually MATLAB 2D
means...” remarks. Keep the concise invariant comments explaining the resulting
(nrows, 1, 1, ncols) shape and MATLAB column-major storage.

Source: Coding guidelines


44-63: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Hardcoded model-specific variable names sit at odds with the registry-driven "add a model in one place" goal.

read_mat_file still special-cases the exact qMRLab variable names (IRdata/IRData/MTdata/MTData) for the two known models. A third model with a different .mat naming convention would require editing this file too, contradicting the PR's stated goal of "module + trait implementations + one registry entry."
Not a blocker today (only 2 models registered), but worth tracking if a third model with a different export convention lands.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/qmrust-cli/src/io/mat.rs` around lines 44 - 63, The read_mat_file
measurement-array lookup is hardcoded to qMRLab-specific names, preventing
registry-only model additions. Replace the IRdata/IRData/MTdata/MTData chain
with a registry- or model-provided naming strategy, while preserving the
existing missing-array context and available-name diagnostics.
crates/qmrust-core/src/models/qmt_spgr/sf.rs (1)

8-12: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move matfile to [dev-dependencies]. Its only remaining uses are under #[cfg(test)] in crates/qmrust-core/src/models/qmt_spgr/sf.rs, so it no longer needs to be a regular qmrust-core dependency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/qmrust-core/src/models/qmt_spgr/sf.rs` around lines 8 - 12, Move the
matfile crate entry from qmrust-core’s regular dependencies to its
dev-dependencies, preserving the test-only imports in sf.rs and ensuring test
builds continue to resolve MatFile.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/qmrust-core/src/models/inversion_recovery/fit.rs`:
- Around line 209-210: Update the comment immediately above extract_params to
document its contract: state the parameter quantities it computes and returns,
and specify that ind indexes valid entries, n is within the available
sample/data range, and rho_norm_vec[ind] is nonzero before the division. Replace
the argument-grouping description while keeping the existing argument names and
function behavior unchanged.

In `@crates/rust-bids/src/config.rs`:
- Around line 111-119: Update the named-set constraints construction for
EntityConstraints so each key is canonicalized with full_key before filtering
out description. Ensure both desc and description are excluded after
normalization, while preserving value prefix handling. Add a regression test
covering a named set containing both short and full description keys.

In `@crates/rust-bids/src/entities.rs`:
- Around line 7-15: Update entity_value_cmp in
crates/rust-bids/src/entities.rs:7-15 to establish an explicit ordering between
numeric and non-numeric values, then compare numerically within the numeric
class and lexically within the non-numeric class; ensure the related entity
ordering at crates/rust-bids/src/entities.rs:153-168 and sequential sort usage
at crates/rust-bids/src/resolve.rs:83-88 use this total comparator without
separate changes unless required.

In `@docs/agents/ADDING-A-MODEL.md`:
- Around line 119-125: Update the ModelConfig trait declaration to include
serde::Serialize and Default alongside DeserializeOwned, matching the complete
supertrait contract required by model implementations.

In `@docs/agents/ARCHITECTURE.md`:
- Around line 345-347: Update the ingest_protocol worked example to remove the
`.mat` reference, stating only that BIDS sidecars supply InversionTime values.
Keep the example aligned with the documented contract that MAT inputs provide no
Protocol and acquisition parameters remain in --config.

In `@docs/getting-started.md`:
- Around line 23-24: Update the recipe description near the getting-started
documentation to reference only recipes/non-bids/ as fully explicit, and clarify
that BIDS recipes obtain acquisition protocol values from sidecars. Preserve the
existing self-documenting explanation for the non-BIDS examples without implying
it applies to all recipes.
- Line 63: Update the BIDS output path documentation near the
`<out>/<subject>[/<session>]/<map>.nii.gz` example to include the required
`qmrust` directory: `<out>/qmrust/<subject>[/<session>]/<map>.nii.gz`. Keep the
remaining path structure unchanged.

In `@recipes/bids/irt1_config.yaml`:
- Around line 3-4: Update the comment in the IR recipe to state only the
parameters actually declared and ingested by the model’s protocol_schema(),
removing RepetitionTime unless the schema and related fixtures are explicitly
updated to support it.

In `@scripts/make_bids_examples.sh`:
- Line 70: The BIDS fitting examples must use the BIDS-specific qMT recipe while
preserving the non-BIDS recipe for bidsify. In scripts/make_bids_examples.sh,
keep QMT_CONFIG for bidsify, add a BIDS qMT configuration variable, and use it
for the qMT fit --bids-dir invocation; in docs/getting-started.md at line 139,
change the example to recipes/bids/qmt_config_ramani.yaml.

---

Outside diff comments:
In `@CLAUDE.md`:
- Line 111: Specify a language on the fenced code block in CLAUDE.md by changing
its opening fence to use text (or another suitable language identifier), while
leaving the block contents unchanged.
- Around line 119-125: Update the ModelConfig contract in the surrounding
documentation to include serde::Serialize and Default alongside
DeserializeOwned, matching the bounds defined in the model configuration API.
Ensure the snippet clearly communicates that implementations must provide all
required derives or implementations.

---

Nitpick comments:
In `@crates/qmrust-cli/src/commands.rs`:
- Around line 1159-1169: Trim the doc comment above the test by removing the
historical sentence beginning with “A regression that silently discarded...” and
ending with “the old (grouping-content-insensitive) version of this test could
not.” Keep the remaining description focused on verifying that a custom grouping
manifest is used during collection resolution.

In `@crates/qmrust-cli/src/io/mat.rs`:
- Around line 70-78: Remove the self-correcting comment lines in the 2D reshape
branch before the nrows/ncols assignment, specifically the “But more
commonly...” and “Actually MATLAB 2D means...” remarks. Keep the concise
invariant comments explaining the resulting (nrows, 1, 1, ncols) shape and
MATLAB column-major storage.
- Around line 44-63: The read_mat_file measurement-array lookup is hardcoded to
qMRLab-specific names, preventing registry-only model additions. Replace the
IRdata/IRData/MTdata/MTData chain with a registry- or model-provided naming
strategy, while preserving the existing missing-array context and available-name
diagnostics.

In `@crates/qmrust-core/src/models/qmt_spgr/sf.rs`:
- Around line 8-12: Move the matfile crate entry from qmrust-core’s regular
dependencies to its dev-dependencies, preserving the test-only imports in sf.rs
and ensuring test builds continue to resolve MatFile.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 344ecaa6-967c-43ff-bba4-f94ec7c91a2d

📥 Commits

Reviewing files that changed from the base of the PR and between 03c80ec and eb1d999.

📒 Files selected for processing (43)
  • CLAUDE.md
  • README.md
  • ci/integration_osf.sh
  • crates/qmrust-cli/src/bidsify.rs
  • crates/qmrust-cli/src/commands.rs
  • crates/qmrust-cli/src/io/mat.rs
  • crates/qmrust-cli/src/main.rs
  • crates/qmrust-core/src/core/model.rs
  • crates/qmrust-core/src/engine.rs
  • crates/qmrust-core/src/lib.rs
  • crates/qmrust-core/src/models/inversion_recovery/config.rs
  • crates/qmrust-core/src/models/inversion_recovery/fit.rs
  • crates/qmrust-core/src/models/inversion_recovery/mod.rs
  • crates/qmrust-core/src/models/inversion_recovery/model.rs
  • crates/qmrust-core/src/models/qmt_spgr/adapter.rs
  • crates/qmrust-core/src/models/qmt_spgr/config.rs
  • crates/qmrust-core/src/models/qmt_spgr/mod.rs
  • crates/qmrust-core/src/models/qmt_spgr/pulse.rs
  • crates/qmrust-core/src/models/qmt_spgr/sf.rs
  • crates/qmrust-core/src/protocol.rs
  • crates/qmrust-core/src/registry.rs
  • crates/qmrust-core/src/sim/mod.rs
  • crates/qmrust-core/src/sim/noise.rs
  • crates/qmrust-wasm/README.md
  • crates/rust-bids/src/config.rs
  • crates/rust-bids/src/default_grouping.yaml
  • crates/rust-bids/src/entities.rs
  • crates/rust-bids/src/resolve.rs
  • docs/agents/ADDING-A-MODEL.md
  • docs/agents/ARCHITECTURE.md
  • docs/agents/DATA-PIPELINE.md
  • docs/bids.md
  • docs/getting-started.md
  • docs/models.md
  • recipes/README.md
  • recipes/bids/irt1_config.yaml
  • recipes/bids/qmt_config_ramani.yaml
  • recipes/bids/qmt_config_sledpikerp.yaml
  • recipes/non-bids/irt1_config.yaml
  • recipes/non-bids/qmt_config_ramani.yaml
  • recipes/non-bids/qmt_config_sledpikerp.yaml
  • recipes/sim/qmt_sim_ramani.yaml
  • scripts/make_bids_examples.sh
💤 Files with no reviewable changes (4)
  • recipes/non-bids/qmt_config_ramani.yaml
  • crates/qmrust-core/src/sim/noise.rs
  • recipes/non-bids/qmt_config_sledpikerp.yaml
  • crates/qmrust-core/src/protocol.rs

Comment thread crates/qmrust-core/src/models/inversion_recovery/fit.rs Outdated
Comment thread crates/rust-bids/src/config.rs
Comment thread crates/rust-bids/src/entities.rs Outdated
Comment on lines +7 to +15
/// Compare two BIDS entity *values*. Index entities may be zero-padded and the
/// padding is not semantic, so compare numerically when both parse as integers;
/// otherwise compare lexically (string labels like `off`, `brain`).
pub(crate) fn entity_value_cmp(a: &str, b: &str) -> std::cmp::Ordering {
match (a.parse::<i64>(), b.parse::<i64>()) {
(Ok(x), Ok(y)) => x.cmp(&y),
_ => a.cmp(b),
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail
python3 - <<'PY'
def cmp(a, b):
    try:
        ax = int(a)
    except ValueError:
        ax = None
    try:
        bx = int(b)
    except ValueError:
        bx = None
    if ax is not None and bx is not None:
        return (ax > bx) - (ax < bx)
    return (a > b) - (a < b)

assert cmp("2", "10") < 0
assert cmp("10", "1a") < 0
assert cmp("1a", "2") < 0
print("non-transitive comparator counterexample reproduced")
PY

Repository: qMRLab/qmrust

Length of output: 203


Make entity ordering total before using it in sequential sorts.

entity_value_cmp is not a total order for mixed numeric/string values ("2" < "10" < "1a" < "2"), so sort_by in crates/rust-bids/src/resolve.rs can see an inconsistent comparator. Define an explicit order between numeric and non-numeric values first, then compare within each class.

📍 Affects 2 files
  • crates/rust-bids/src/entities.rs#L7-L15 (this comment)
  • crates/rust-bids/src/entities.rs#L153-L168
  • crates/rust-bids/src/resolve.rs#L83-L88
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/rust-bids/src/entities.rs` around lines 7 - 15, Update
entity_value_cmp in crates/rust-bids/src/entities.rs:7-15 to establish an
explicit ordering between numeric and non-numeric values, then compare
numerically within the numeric class and lexically within the non-numeric class;
ensure the related entity ordering at crates/rust-bids/src/entities.rs:153-168
and sequential sort usage at crates/rust-bids/src/resolve.rs:83-88 use this
total comparator without separate changes unless required.

Comment thread docs/agents/ADDING-A-MODEL.md Outdated
Comment on lines +345 to +347
fn ingest_protocol(&mut self, proto: &Protocol) -> Result<()> {
// BIDS sidecars (or a .mat) supply the InversionTimes here.
if !proto.volumes.is_empty() { /* pull InversionTime values into self.inversion_times */ }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Remove .mat as a Protocol source from the worked example.

docs/agents/DATA-PIPELINE.md documents that .mat inputs provide no Protocol; acquisition parameters remain in --config. Saying “BIDS sidecars (or a .mat)” supplies inversion times contradicts that contract and may reintroduce MAT protocol ingestion.

Proposed documentation fix
-        // BIDS sidecars (or a .mat) supply the InversionTimes here.
+        // BIDS sidecars supply InversionTimes here; non-BIDS builds pass an
+        // empty Protocol and keep acquisition values from the config.

As per coding guidelines, docs/agents/ARCHITECTURE.md must stay synchronized with the current system design.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn ingest_protocol(&mut self, proto: &Protocol) -> Result<()> {
// BIDS sidecars (or a .mat) supply the InversionTimes here.
if !proto.volumes.is_empty() { /* pull InversionTime values into self.inversion_times */ }
fn ingest_protocol(&mut self, proto: &Protocol) -> Result<()> {
// BIDS sidecars supply InversionTimes here; non-BIDS builds pass an
// empty Protocol and keep acquisition values from the config.
if !proto.volumes.is_empty() { /* pull InversionTime values into self.inversion_times */ }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/agents/ARCHITECTURE.md` around lines 345 - 347, Update the
ingest_protocol worked example to remove the `.mat` reference, stating only that
BIDS sidecars supply InversionTime values. Keep the example aligned with the
documented contract that MAT inputs provide no Protocol and acquisition
parameters remain in --config.

Source: Coding guidelines

Comment thread docs/getting-started.md Outdated
Comment thread docs/getting-started.md Outdated
Comment thread recipes/bids/irt1_config.yaml Outdated
Comment thread scripts/make_bids_examples.sh

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/qmrust-core/Cargo.toml`:
- Line 26: Move the matfile dependency back from dev-dependencies to the normal
dependencies section in crates/qmrust-core/Cargo.toml, preserving availability
for the non-test code in the qmt_spgr::sf module.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ce933a2d-9e00-4eed-9fe8-137d11c6b982

📥 Commits

Reviewing files that changed from the base of the PR and between eb1d999 and 3d890cd.

📒 Files selected for processing (12)
  • README.md
  • crates/qmrust-cli/src/commands.rs
  • crates/qmrust-cli/src/io/mat.rs
  • crates/qmrust-core/Cargo.toml
  • crates/qmrust-core/src/models/inversion_recovery/fit.rs
  • crates/rust-bids/src/config.rs
  • crates/rust-bids/src/entities.rs
  • docs/agents/ADDING-A-MODEL.md
  • docs/agents/ARCHITECTURE.md
  • docs/getting-started.md
  • recipes/bids/irt1_config.yaml
  • scripts/make_bids_examples.sh
🚧 Files skipped from review as they are similar to previous changes (10)
  • recipes/bids/irt1_config.yaml
  • crates/qmrust-core/src/models/inversion_recovery/fit.rs
  • scripts/make_bids_examples.sh
  • crates/rust-bids/src/entities.rs
  • crates/rust-bids/src/config.rs
  • docs/agents/ADDING-A-MODEL.md
  • crates/qmrust-cli/src/io/mat.rs
  • docs/getting-started.md
  • docs/agents/ARCHITECTURE.md
  • crates/qmrust-cli/src/commands.rs

plotters.workspace = true

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n --glob '*.rs' '\bmatfile\b' crates/qmrust-core || true

cargo test --workspace
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings

Repository: qMRLab/qmrust

Length of output: 783


Keep matfile as a normal dependency crates/qmrust-core/Cargo.toml:26
crates/qmrust-core/src/models/qmt_spgr/sf.rs imports matfile, so moving it to dev-dependencies will break non-test qmrust-core builds.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/qmrust-core/Cargo.toml` at line 26, Move the matfile dependency back
from dev-dependencies to the normal dependencies section in
crates/qmrust-core/Cargo.toml, preserving availability for the non-test code in
the qmt_spgr::sf module.

Source: Coding guidelines

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLAUDE.md`:
- Around line 35-40: Update the “Behaviour-preserving refactors do not change
fitting results” section in CLAUDE.md to remove the unresolved TODO and either
provide the actual snapshot/golden-output regression command or describe the
manual verification procedure without any TODO/task reference. Preserve the
requirement that fitting-output differences are treated as regressions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fbd02433-cf89-49ec-b840-11a012133061

📥 Commits

Reviewing files that changed from the base of the PR and between 3ac40dc and fc7363f.

📒 Files selected for processing (18)
  • CLAUDE.md
  • README.md
  • crates/qmrust-cli/src/bidsify.rs
  • crates/qmrust-cli/src/commands.rs
  • crates/qmrust-core/src/config.rs
  • crates/qmrust-core/src/models/qmt_spgr/config.rs
  • crates/qmrust-core/src/models/qmt_spgr/fit.rs
  • crates/qmrust-core/src/quad.rs
  • crates/rust-bids/src/entities.rs
  • crates/rust-bids/src/resolve.rs
  • crates/rust-bids/src/scan.rs
  • docs/agents/ARCHITECTURE.md
  • docs/agents/DATA-PIPELINE.md
  • docs/bids.md
  • docs/browser.md
  • docs/getting-started.md
  • docs/models.md
  • recipes/non-bids/qmt_config_ramani.yaml
🚧 Files skipped from review as they are similar to previous changes (10)
  • recipes/non-bids/qmt_config_ramani.yaml
  • crates/rust-bids/src/entities.rs
  • docs/bids.md
  • docs/agents/DATA-PIPELINE.md
  • crates/qmrust-core/src/models/qmt_spgr/config.rs
  • README.md
  • docs/getting-started.md
  • docs/agents/ARCHITECTURE.md
  • crates/qmrust-cli/src/bidsify.rs
  • crates/qmrust-cli/src/commands.rs

Comment thread CLAUDE.md Outdated
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.

1 participant