Skip to content

Releases: adamaske/NIRWizard-releases

NIRWizard 0.2.4

Choose a tag to compare

@adamaske adamaske released this 01 Oct 08:21

NIRWizard 0.2.4 — tester builds for Windows and Linux (x64).

An installation release. NIRWizard now sets up its own dependencies: Tools ▸ Install dependencies… downloads the preprocessing engines, ffmpeg and MCX into the app's own folder for your user account. No administrator rights, no PowerShell, no environment variables, no signing out.

Install dependencies from inside the app

  • One dialog, three parts, each optional. Preprocessing (choose Cedalion + MNE, both engines with Cedalion as the default, or the lighter MNE only), ffmpeg (video export of animations) and MCX (the GPU Monte-Carlo forward model). Every line says what you get or what still works without it, and the dialog shows the total on disk before you start.
  • Per user, nothing system-wide. Everything lands in the app's data folder (tools/), shown in the dialog with an Open button. There are no PATH or registry edits, so shared lab machines install once per Windows account. Remove installed tools deletes the folder.
  • Works without restarting. When the install finishes, preprocessing picks up the new environment straight away. The External tools panel and the Preprocessing panel re-check themselves.
  • Offered when it's needed. At first launch, and only if no Python on the machine can run MNE or Cedalion, a prompt offers the one-time download (~1.5 GB, a few minutes). Either answer is remembered. The dialog is also reachable from Install… in the External tools panel and in the Preprocessing panel's "Cedalion unavailable" banner.
  • MCX is pre-ticked only when an NVIDIA GPU is found. Without one, the analytic engine is used and the dialog says so.
  • Your own setup still wins. A NIRWIZARD_PYTHON_PATH, NIRWIZARD_CEDALION_PYTHON_PATH, NIRWIZARD_FFMPEG_PATH or NIRWIZARD_MCX_PATH you set takes precedence over the managed install, and the dialog tells you when one is set. Users with their own working Python never see the first-launch prompt.
  • Nothing updates by itself. When a new NIRWizard version moves a pin, installed parts show Update available and you start the update.

Safe by construction

  • An install never leaves you worse off. Each part is built beside the current one, checked with the same tests the app runs at runtime (the worker answers, MNE and Cedalion pass their version gates, ffmpeg runs, MCX finds a GPU), and only then swapped in. A failure or Cancel removes the half-built copy, and your previous setup stays in use.
  • Parts are independent. If MCX fails, the preprocessing install still completes, and each failure names what still works.
  • Pinned and checked. Every download (uv, Python 3.11, ffmpeg, MCX, and the Cedalion source) has a fixed version and a SHA-256 that is checked before anything is unpacked. The Python packages come from a hash-locked list with identical versions on Windows and Linux, and no git client is needed.
  • Checks before it starts. It refuses up front, with numbers, when the disk is too full, and says so when github.com can't be reached (connection or proxy).
  • A log for every run, with Show log and Copy log path in the dialog.

Also in this release

  • Tools menu (between Theme and Help) with Install dependencies… and External tools…; the statusbar shows a chip while an install runs with the dialog closed.
  • examples/easy-installation is now a short README (install the app, accept the prompt). The elevated PowerShell scripts are gone.

Downloads

  • Linux: .AppImage, .deb, .rpm (tester builds — no licence key needed).
  • Windows: .msi and -setup.exe are uploaded separately.

NIRWizard 0.2.3

Choose a tag to compare

@adamaske adamaske released this 30 Sep 08:11

NIRWizard 0.2.3 — tester builds for Windows and Linux (x64).

A contrasts, DOT correctness and provenance release. Contrasts now live in the protocol, so the channel GLM, the group GLM, the group image and the projected GLM on the cortex all fit the same contrasts. Short channels no longer flip the sign of the projected GLM on a block that already had short-channel regression, and the projected GLM on a concatenated session now agrees with the channel GLM. Censoring, AR-IRLS and the provenance records were tightened as well.

Contrasts live in the protocol

  • One owner. A contrast is a set of weights over the protocol's conditions, so the protocol (.nwproto) now holds both the conditions and the contrasts. Session and study protocols both carry them.
  • Edit them in the Event Manager, next to the conditions. The GLM panel shows them read-only, including the contrasts the per-run route fits.
  • Every fit reads the same list. The channel GLM, the group GLM and the group image all take their contrasts from the protocol, and every record still states the balanced weights (contrastWeights).
  • Contrasts restored from a plain .nirw are no longer lost. Before, the panel showed only a study's contrasts and overwrote a project's contrasts on its next sync.
  • Older files are converted on open. Contrasts saved in the GLM settings of an older .nirw or .nwstudy are moved into the protocol once, including a study embedded in a project, and the file is marked as changed. A protocol that already holds contrasts is never overwritten. Neither file format changes version.
  • A study protocol with only contrasts now counts: the study keeps it, and each run's events stay as they were recorded.
  • Reset from session rebuilds the conditions and clears the contrasts. The confirm text now says so.

Contrasts on the cortex

  • The projected GLM reads the protocol. It used to build its design from the file's raw event names and ignore contrasts entirely, even though editing a contrast marked it stale. It now fits the protocol's merged conditions, the same ones the channel GLM fits, and forms each contrast as an effect, the way the group image does.
  • Pick an effect. The GLM on cortex row in DOT ▸ Cortex analyses lists the conditions, then the contrasts. Editing a contrast marks the result stale, and now the result actually changes on re-run.
  • Export L has an effect_type column and contrast rows, matching export Q. Measurement prediction reads the same effect list.

DOT fixes

  • Short channels flipped the projected GLM negative after short-channel regression. On a block whose long channels were already regressed against the short ones, keeping the short channels as operator rows removed the scalp signal a second time, and the cortex went negative at both wavelengths while the channel GLM, block average and epoch image were positive. The inverse now has a Short channels as rows setting: auto (the default) leaves them out when the reconstructed block's own history shows short-channel regression, and keeps them otherwise; include and exclude override it. Each dropped row is an exclusion entry, the Inverse stage shows Short rows: n of m excluded, and every image record states the rule.

  • The operator refuses a block it wasn't built for. An auto operator built for a regressed block (or the reverse) refuses to apply, names the block, and tells you to rebuild the inverse on it or set the rule by hand. This covers the cursor image, the epoch image and its export, the projected GLM and the materialised block average and connectivity. The group image applies the rule to each run separately.

  • The projected GLM on a concatenated session dropped the run intercepts and the whitening that restarts at each seam, so under AR-IRLS it could contradict the channel GLM. Each wavelength's fit now uses the same runs as the channel GLM.

  • One invariant for superficial removal. Whatever scalp component is removed from the long rows is now removed from the short rows too, on every image route. The materialised block average and connectivity used to leave the short rows untouched, which took the scalp share out of the long rows twice on an unregressed block. include on a regressed block is still allowed and its record states the double removal; an include operator now refuses a block with the other regression fact, as auto does. The projected GLM record states its route and whether the invariant holds (Parameters.Model.superficial_route).

  • A changed bad-channel record refuses the built operator. The operator fixes its rows when it is built, so marking channels afterwards left projected-GLM re-exports unchanged. The cursor image, epoch image, projected GLM, image-domain reads and the L-curve now refuse by name, and the Inverse stage goes stale when the bad set changes.

  • Epoch image with every epoch censored refuses by name instead of returning an all-zero image.

  • The epoch window and inverse parameters survive reopen. The study owns the epoch-image window and the session GLM design; a .nirw carries them, and opening a study subject seeds the Inverse stage from the study's DOT setup. The GLM design follows the study even with the GLM panel closed.

  • Display ▸ Image reconstruction now holds the forward stage's sensitivity-volume settings (channel, colormap, render mode, threshold, opacity, gain, MRI backdrop) beside the operator maps. A new forward result resets the volume channel.

Censoring and GLM

  • A censor mask that would remove over half the record is refused. Nothing is removed, the record states refused (coverage) with the would-remove numbers, and the QC GVTD view shows the flagged share of the run and warns past the limit.
  • AR-IRLS drops the partly whitened rows after every restart. Whitening restarts at each censored gap or run seam, and the first rows of each span were mostly raw data that inflated t on heavily censored records. A single uncensored recording is bit-identical to before.

Coordinates

  • Optode positions are stored per project and per study subject. A .nirw keeps the session's placement and a study subject keeps its own; both install on a recording with the same montage. The head cache keeps its registration through landmark and grid saves and states when, on which recording and from which source it was baked. A restore skipped for another montage warns.
  • Keep this move in the probe transform editor keeps a hand move as manual positions.
  • DOT Head and Coordinates show the montage identity, positions hash and any warning under the Positions line.

Preprocessing

  • The session export reads the active block's pipeline. Export P used a global record that a failed apply or a file load could leave describing another block. It now exports the active block's own lineage and refuses a block no pipeline produced.
  • The short-channel threshold shows in the step editor. Steps that use it (short-channel regression, pick long/short channels) show the session's "short if ≤ N mm" value instead of "No configurable parameters". It is still edited in Info's Signal card and the Montage channel table.

Provenance

  • Every record and export names the build. Each provenance record's GeneratedBy and each export part's header now carry the git commit the binary was built from (build g<sha>, with -dirty for a tree with uncommitted changes), so two binaries with the same version number can be told apart from their outputs.

  • Every sidecar states a digest of its inputs (InputsDigest, SHA-256 over Sources, Parameters and Exclusions), so identical and recomputed results can be told apart.

  • Image and GLM records name their channels. They list the fitted rows and each left-out channel with its criterion and reason, and the projected GLM now writes an _exclusions.csv.

Downloads

  • Linux: .AppImage, .deb, .rpm (tester builds — no licence key needed).
  • Windows: .msi and -setup.exe are uploaded separately.

NIRWizard 0.2.2

Choose a tag to compare

@adamaske adamaske released this 24 Sep 17:11

NIRWizard 0.2.2 — tester builds for Windows and Linux (x64).

A DOT release: the image domain gets one home with five stages, a study gets a group image, a planned study gets a predicted measurement and a power curve, and the cortex gets atlas parcels you can build ROIs from. The 3D viewport shows up to six views at once and exports them as one figure, and the signal panels move their settings into a sheet.

DOT has one home

  • A five-stage rail. The DOT column is now Head → Forward → Inverse → Cortex analyses │ Plan, one light per stage, with staleness travelling downstream and a cost line in the footer. A Session | Study scope switch sits above it.
  • Cortex analyses in one place. The epoch image, the GLM on cortex, and the image-domain block average and connectivity (run from their own panels) are rows of one stage. The GLM panel no longer launches cortex fits; a one-line strip under its warnings shows the cortex result and opens DOT.
  • Cortex fits use the GLM design's own solver. Under OLS the vertex fit is exact; under AR-IRLS each channel's β is projected through W. Either way the map is descriptive, and the record states the solver.
  • Study scope. The study's own head, forward and inverse settings, either linked to the session or pinned, with per-stage differences and Take session values. The Study header gets one DOT line and the group-image light opens DOT.
  • Head stage facts. The optode projection runs by itself; the head and position facts link to Anatomy and Coordinates.

Group image (group DOT)

  • Vertex and parcel random effects on the installed atlas head: each subject's β is projected through its own W, masked to vertices covered in k of n subjects, BH-FDR over the mask, and a max-statistic sign-flip family for FWE control. Exports Q (vertex) and R (parcel).
  • Runs as a background job with per-subject progress, and shows in the Study footer, DOT and Display.

Plan: prediction and power

  • Measurement prediction. Plant an activation over an ROI, an atlas parcel or a geodesic blob and see the channel ΔOD / ΔHb it would produce and the image the inverse would recover, with point-spread metrics and whether the gate would detect it. Use GLM β at this vertex takes the effect size from a fit. Export S.
  • Prospective power. A seeded Monte-Carlo at the β level over literature noise, your study's own variance, or values you type, tested by max-T sign-flip, BH-FDR, cluster mass or the vertex family. It reports power at the target, power anywhere, the null FWER check, the Monte-Carlo SE and the n for 80 %. Export T.

Forward and inverse

  • Per-optode layer thickness. The four-layer model measures scalp, skull and CSF under each optode from the installed head's shells instead of using one fixed convention.
  • Subject segmentation. A subject head can be segmented into five tissues (SAMSEG by default, or imported), which gives the forward model its skull shells.
  • Digitised optode positions. Read AtlasViewer / NIRSite digpts.txt, BIDS *_optodes.tsv or the SNIRF's own landmarks, fit them to the head and place the probe. Every probe install now records where its positions came from, and every DOT result states it.
  • Spatial basis functions (opt-in) for the inverse, held to Cedalion's.
  • Superficial signal in image space. Image paths read short-channel regression from the reconstructed block's own history; the materialised path can regress the mean short signal before W (auto | on | off, same rule as the GLM).
  • Motion censoring. A time-resolved GVTD detector (Sherafati 2020) in a new QC view marks motion; every image-domain path censors those samples, the channel GLM and block average do it when switched on, and each record states what was censored.

Parcels and atlas ROIs

  • Parcellations on the head. colin27 and fsaverage ship Desikan–Killiany, Destrieux and Schaefer-400 (17 networks); colin27 also ships Brodmann areas (MRIcron). Load your own lh/rh .annot pair from the ROI panel.
  • Parcel ROIs and parcel nodes. An ROI can be a set of parcels; image analyses can use parcels as nodes; the epoch image and the projected GLM carry a per-region table (*_regions.csv) beside Cedalion's sensitivity gate.
  • Auto-fill from atlas. One ROI per region, lobe, Schaefer network or functional (Brodmann) group under the probe. You review a preview before anything is committed, and existing ROIs are matched by membership, never deleted. It is refused unless the probe was placed on the head. Delete all clears the list.
  • Pair by atlas region in laterality pairs left and right ROIs by mirrored membership.

Multi-view viewport and the view figure

  • Up to six views in one viewport, each with its own camera. Four shipped layouts plus your own, saved with the project. Six views opens the head out: Left | Superior | Right over Anterior | Inferior | Posterior.
  • View figure export. The layout as one composite, each view on its own, and the colorbar, at screen scale or a print size in mm at a chosen dpi.
  • The canvas fills its pane by default, and dragging a divider no longer redraws every frame.

Signal panels and themes

  • A settings sheet for Time series, Spectrogram and Frequency. When closed, the settings sit in the header, and whatever does not fit moves into ⋯. Time series gets header toggles for events, motion and run seams; Frequency's traces are the legend and range problems are stated in words.
  • The Channel Selector header is one line (selection, marks, the reason under the caret), with the legend on the probe.
  • Graphite is the default theme, with the Ember accent. Plots and the 3D viewport follow the theme, and figure and capture exports default to a transparent background. The theme picker is now a menu in the menubar.

Protocol and study

  • The GLM shows which protocol it fits, and why, and records it. The Protocol panel shows how the session and study protocols differ and adopts either one in one click.
  • Export preprocessed recordings runs as a background job with progress and cancel, with a choice of layout (beside, mirrored, flat), a policy for files that already exist, and a dry-run plan.

Fixes

  • A cached head registration could come back onto the wrong montage. A .nirwcoord now stores the identity of the probe it was fitted to and is only restored onto that probe.
  • The inverse build on a haemoglobin block fell back silently to a median baseline and every later image refused. It now refuses up front and names the block.
  • The session GLM with a study loaded filtered the file's events by the study's condition names and refused with "No events found". It now fits through the study protocol.
  • Cohort refusals no longer repeat the same cause for every run of every subject.
  • The group image states the study GLM's solver and clears a stale error.

Downloads

  • Linux: .AppImage, .deb, .rpm (tester builds — no licence key needed).
  • Windows: .msi and -setup.exe are uploaded separately.

NIRWizard 0.2.1

Choose a tag to compare

@adamaske adamaske released this 20 Sep 14:26

NIRWizard 0.2.1 — tester builds for Windows and Linux (x64).

A cohort reproducibility release: the things a study already computed are now kept, stated and exportable. Quality control over a whole cohort keeps every metric it measured, the pipeline that actually ran per subject becomes an export of its own, preprocessed recordings are written per run, and cohort laterality stops refitting anything.

Cohort laterality reads what the study already computed

  • No refit. Cohort laterality is now a reduction over the study's cached group GLM or group block average. It no longer reloads every subject, re-runs the pipeline through the worker or refits the first level, so it updates as you edit the ROI pairs, the window or the chromophore. There is no Run button.
  • A stored snapshot, flagged when its source moves. The result records which group result it was reduced from. Re-running the group GLM or block average leaves the laterality in place with a "source recomputed" flag until you press Update from current source; switching between the GLM and the block-average source is held the same way.
  • Refusals that point somewhere. With no group GLM, no group block average, a response window outside the cached epoch, or a fit that predates stored contrast effects, the panel says so in place and offers Open GLM / Open Group BA, instead of a toast.
  • Contrasts are the fit's own. Laterality of a contrast now uses the effect the GLM panel shows, not the contrast definition as edited since. Re-run an older group GLM once if it predates stored contrast effects.
  • All three chromophores, every time. HbO, HbT and HbR are computed together and every export holds all three; a control above the chart picks which one to look at (the chart, table, HbR caveat and 3D overlay follow it), with a line saying how many cells of each are significant.
  • Region pairs are named after their ROIs ("Left | Right") instead of "Region 1", in the chart, the table and the exported CSVs. Type a name to override it.
  • The response window knows the epoch. For a block-average laterality the panel shows the epoch the cached block average covers, validates the window against it (with a Fit to epoch button), defaults the window from it instead of a fixed 5–15 s, and offers Use whole post-stim epoch, which follows the cached epoch if the block average is re-run.
  • A one-subject cohort states its pipeline and unit from the study and the fit's conversion record rather than leaving them blank.

Cohort QC keeps what it measured

  • One pass, every metric kept. Judging a cohort used to compute a full QC report per run and keep only the verdict. Each run's metrics and the provenance they were born with are now stored beside the record, so nothing is thrown away.
  • Re-judge without touching a file. Move the thresholds and the whole cohort is re-judged from the stored metrics — the cohort mirror of the session's threshold editor. The panel says when a threshold edit has moved the table off the verdicts the fits still read (channels under a hand override are skipped — those are meant to disagree).
  • It no longer looks hung. The pass runs as a proper background job on the study epoch with per-run progress, instead of parsing every recording serially with no feedback. A pass that refuses ("no enabled runs") no longer retires your cached estimates.
  • Export O — the cohort channel table. The session channel table with subject, run prepended, a per-run census that includes the runs that could not be judged, and one provenance record naming each of them.
  • One place to start it. QC gains a Session | Cohort toggle over the same table, and the Study button opens it.

The pipeline as executed is an export

  • Export P — preprocessing provenance. The as-executed pipeline block has been recorded with every result since 0.1.x and never had an export. It is now written long-format: one row per (scope, step) and one per (scope, step, parameter), so diffing two subjects is a sort. The sidecar carries the blocks verbatim — identity line, absence facts and annotations included.
  • Only what actually ran. A subject with no fresh estimate is named in Exclusions rather than reported from its configured pipeline, and the entry is offered from the Preprocessing panel, the Study footer and Export ▸ Data with the same refusal in the same words.

Preprocessed exports, run by run

  • A run is a recording. Exporting preprocessed data from a study writes one file per run, beside its original (sub1_run2_preprocessed.snirf), whatever the study's run policy. Pick the runs to write, or write every run of every enabled subject.
  • Refusals are named. Anything requested but not attempted comes back in the summary with the run's name and the reason, next to the per-run successes and failures.
  • One selection in the Outliner. Subject and run checkboxes are one selection over runs: a subject's box is checked, indeterminate or clear from its runs, shift-click selects a range, and the header states how many subjects and runs are selected.

Fixes

  • A useT export of a contrast returned β. glm_contrast_value ignored the flag, so a t-statistic export of a contrast row was byte-identical to the β export under a different header. The fit already carried the per-channel t; it is now what a useT export writes, for condition and contrast columns alike. HbT is the stated exception — t-statistics are not additive, so the HbT column stays the β (or c'β) sum, said so in the record, the CSV notes and the panel, which no longer labels it "t". Re-export any t-statistic comparison made with an earlier 0.2.x build.
  • Laterality values now say what they are. left_value / right_value (and mean_l / mean_r) are activation magnitudes with HbR negated, so "positive = left-dominant" holds for every chromophore — the convention was right and nothing in the output stated it. Each cell also carries its sign case, each cohort cell the three counts over exactly the subjects its t covers, and a difference contrast is marked as having no activation direction rather than counted as one.
  • A block-average window reaching before onset averages baseline into the response and biases the index toward zero. Still allowed, no longer silent: a warning on the result and includesPreOnsetBaseline in the record.
  • Provenance of a group round names the fit again. A reduction's model block describes the reduction, so no group record stated a solver, basis, drift cutoff or contrast weight; under the per-run policy the RFX's subjects[].model was the combine's model, not the run fits'. One projection now serves all four surfaces, carried once when every item was made alike and per item when not. Every record is also born with a ComputedAt, so an export set mixing builds is checkable.
  • ROIs show up again on a multi-block file. Roi.channel_ids are block-scoped, so an ROI captured under one block matched nothing in another — the 2-D selector tint, the probe colouring and the laterality overlay silently showed nothing. ROIs are now served and re-announced resolved to the active block, and membership edits match on (source, detector). Analyses were never affected.
  • A batch of cortex movies names the condition each one shows — in the baked-in caption band and in every _display.json, instead of repeating the first job's condition across the set.
  • Per-run export count leaves out selected runs of excluded subjects, matching what the backend writes, and a merge keeps the selection you had.

Added after the first upload of this release

The Linux installers were rebuilt to include these; the Windows installers will follow with the same changes.

  • Graphite is the new default theme — near-black with hairline borders and an Ember (Aske orange) accent. Plots and the 3D viewport now follow the active theme, and the theme picker is a menubar menu.
  • Group records state how each subject was made. A record on preprocessed files states an inherited pipeline read from the files' own NIRWizard_* tags, and a file with no tag says so rather than "no pipeline". Subjects are grouped by the pipeline that actually produced them, and a subject no longer wears run 1's record.
  • The cohort QC band and window are a study setting, saved with the study.

Downloads

  • Linux: .AppImage, .deb, .rpm (tester builds — no licence key needed).
  • Windows: .msi and -setup.exe are uploaded separately.

NIRWizard 0.2.0

Choose a tag to compare

@adamaske adamaske released this 19 Sep 14:27

NIRWizard 0.2.0 — tester builds for Windows and Linux (x64).

This release rebuilds connectivity as a workspace of its own, gives every plot a Save figure and a data export, makes a study honour an event protocol and exclude bad channels run by run, and puts GLM contrasts on a stated, balanced scale.

Connectivity — four estimators, four scopes, one workspace

  • Four undirected estimators: Pearson, shrinkage partial correlation (Schäfer–Strimmer, held to corpcor), wavelet transform coherence (f64 Morlet CWT, held to biwavelet) and the phase-locking value.
  • Four temporal scopes resolved to per-segment estimates plus one aggregate — never concatenation. Condition epochs are task-state FC, and the record says so.
  • Inference: Bartlett-corrected Fisher z combined across segments, or seeded surrogate nulls (phase randomisation / IAAFT) behind a cost confirm. A run can be cancelled at its next segment.
  • An optional graph layer over a density sweep — BCT-mirrored measures, Louvain communities, small-world σ, AUC — held to bctpy.
  • The workspace follows the DOT stage rail (Estimate / Scope / Inference / Graph) with six views: matrix, circular graph, edges on the head, time–frequency coherence, segment timeline and the density sweep.
  • Exports G, G-segments, G-graph and G-tf, each with its provenance sidecar. The nirconn import stays as a legacy path.

Figures and data

  • Save figure on every plot: PNG at 1×/2×/4× or SVG, with a provenance sidecar.
  • Export ▸ Data writes the time series, spectrum and spectrogram as full-resolution CSVs.

The Study — an event protocol and per-run QC

  • The study owns an event protocol. Import a .nwproto in the Study header: raw stim names are merged under the protocol's condition names, durations are overridden, and a stim name the protocol leaves out is not modelled — so rest markers can be dropped. Every study compute reads it: the per-run fits, the subject estimate under either run policy, the group GLM and the group block average (group laterality follows the group GLM). With no protocol, every stim name is a condition, as before.
  • QC all runs. One action judges every enabled run's raw block with the native engine at study-wide thresholds and stores a bad-channel record per run in the .nwstudy.
  • A bad channel leaves that run's fit only. Under the per-run policy the fixed-effects combine uses the runs where the channel is good. Under concatenate there is one fit, so a channel bad in any joined run leaves it — and the verdict says so.
  • Hand-made verdicts per run. The run Inspector lists the run's exclusions; keep a channel or exclude one by name. A user verdict outranks a later QC pass.
  • Any protocol, threshold or verdict change makes the study's results stale.

Not in this release: seeding the session's bad-channel state when a run is opened from the study (and writing a session verdict back), a thresholds editor in the Study workspace, and run-level rows in the group exclusion manifest.

GLM contrasts — balanced weights

  • Every contrast is applied balanced. The positive weights are rescaled to sum to +1 and the negative weights to −1, each sign on its own. A contrast over all k conditions (k × +1) is now the mean amplitude, not the sum. An unbalanced difference such as (Thumb + Index) > Ring, entered as +1, +1, −1, now tests (Thumb + Index)/2 − Ring. Before, it tested Thumb + Index − Ring, which is non-zero wherever all three fingers respond.
  • What changes in your results: the amplitude (effect, mean_beta, the cortex map, laterality input) of any contrast whose weights did not already balance. A one-sign contrast over k conditions shrinks by a factor of k, and its t, p and q are unchanged. An unbalanced difference changes its t, p and q too, because it now tests the hypothesis it was meant to. A plain A − B contrast is unchanged.
  • The stored weights are unchanged, so saved contrasts still load. A result saved in a .nirw or .nwstudy before this release keeps its old values and record until it is recomputed.
  • The contrast editor shows the applied weight beside each ±1 and labels each contrast a difference or vs baseline test. Every GLM sidecar records the entered and applied weights and the rule (Parameters.Model.contrastWeights, contrastWeightRule). Every CSV with a contrast row states the scale in its header.
  • Per-run combine: contrast SEs are exact. Each run's fit now carries the covariance of its condition βs, so a contrast over conditions that share a run keeps its between-condition term. Before, that term was dropped. A run result saved before this release still combines, and the record then names the variance an independence approximation.

Also

  • The Display panel now holds the coordinate display settings; group movies skip conditions that carry no data.
  • The Networking workspace is hidden for 0.2.0 (still compiled; the Conductor's LSL outlets are unaffected).
  • The Conductor gains a stimulus companion and a marker listener.

Downloads

  • Linux: .AppImage, .deb, .rpm (tester builds — no licence key needed).
  • Windows: .msi and -setup.exe are uploaded separately.

NIRWizard 0.1.9

Choose a tag to compare

@adamaske adamaske released this 12 Sep 12:15
41d12d3

NIRWizard 0.1.9 — tester builds for Windows and Linux (x64).

This release adds the two pieces that were missing at either end of a study. The Conductor runs the experiment: a paradigm you design in the app, markers pushed over LSL to the acquisition software, and a crash-safe session log. The Study workspace is the other end: a cohort of participants, each with its own list of runs, under one run policy, feeding every group analysis one estimate per participant.

It also fixes a serious 0.1.8 bug: the window close button did nothing. Anyone on 0.1.8 should upgrade.

The Conductor — run the experiment from NIRWizard

A new workspace in the Live group, beside Networking. NIRWizard now drives the paradigm instead of assuming another program did.

  • A paradigm is a file you design. A .nwparadigm holds the marker table (integer code, name, colour, with session start / session end / abort always present), a timeline of timed and self-paced blocks and repeat groups with seeded jitter, cue keys 1–9 bound to markers, one or more LSL outlets, and the run options. Undo and redo run over whole-document snapshots; the unsaved marker is derived from the history. Three worked examples ship — a block design, an event-related design and a self-paced task.
  • The schedule is expanded before you start, from a seed. Jitter is uniform, repeat groups are shuffled within each repetition, and the seed is written into the session log — so a session can be described exactly, and the schedule you previewed is the one that runs.
  • Markers go out with one explicit timestamp per outlet. A driver thread ticks at 20 ms, pushes each marker to every enabled outlet, and enforces a minimum marker gap: a scheduled send inside the gap is delayed and the delay recorded, a cue key inside it is sent and flagged. Three clocks are kept per marker — the monotonic session clock, the LSL clock and the wall clock.
  • The session log is crash-safe. JSON lines, flushed per line, holding the header (paradigm, seed, clocks at start), every marker with its per-outlet outcome, every pause and note, and a summary of planned versus actual durations. A cut file reads back as a completed-unknown session rather than an error. Markers export as TSV, and the run number for the next session is proposed from the log folder.
  • Dry run. No outlet is opened and a speed multiplier scales the schedule clock only — the wall and LSL clocks stay real — so a 20-minute paradigm can be walked in two minutes at the desk.
  • The keyboard is the interface. One keymap generates the ? sheet and every on-screen key hint; keys act only when the deck has focus and the run is armed or running, never while you are typing. Audible cues use Web Audio and stay alive while the workspace is parked.
  • Closing the window while a run is live aborts the run and finalises the log before the app exits, and the status bar carries a chip whenever a session is running.

docs/conductor.md says what is written and read, and where each clock lives. LSL exposes no acknowledgement, so an outlet outcome of ok means the push returned, not that a consumer received it.

The Study workspace — a cohort, with runs

A study is now the project, and a subject is an ordered, never-empty list of runs (ADR 0005).

  • One run policy governs the cohort. Per-run (the default) fits each run and combines by precision-weighted fixed effects; concatenate joins the runs into one session and fits once. The policy is a property of the study, not of a subject, because a group over mixed policies is a group over incomparable estimates.
  • Every group analysis consumes subject estimates. A four-run participant enters the group RFX once, with one β. Before this, a group analysis silently read each subject's first file — a four-run participant entered as run 1 alone. That is fixed.
  • Group block average pools trials per run under the per-run policy, with per-run trial counts, and rejects any epoch spanning a run boundary under concatenate, recorded as an exclusion.
  • Build a cohort through an import proposal. Pick a folder or a set of files and NIRWizard proposes the subject/run split by subfolder, prefix, pattern, or one subject per file. The proposal shows the rule, the order and the checks, runs can be dragged between subjects before you commit, and each subject's origin is recorded.
  • Open a subject or a run into the session. A study banner under the menu bar names the subject, its runs and the policy, steps between runs, offers Use this pipeline and Back to study. A reopened study lands on the same subject it was left on.
  • Batch first level. A group run keeps every subject's first-level result. Export all subjects… writes one folder per run fit and one per estimate, plus a subjects.csv index carrying each excluded subject's reason.
  • The file. .nwstudy v3 records runs with ids and hashes, the policy, the origins, the configs and every cached group result with its provenance record — restored on open only while every run hash still matches, and refusing by subject and run name when one has changed. v2 and earlier files still open.
  • Provenance. Every group record states the run policy at the top level and, per subject, the runs used with their hashes.

Fixes

  • The window buttons worked on nothing (0.1.8). The title bar's ×, minimize and maximize were rejected at the IPC boundary — Tauri's default window permissions are read-only and carry no allow-close, allow-destroy, allow-minimize or allow-toggle-maximize. Alt+F4 and the window manager still closed the app in 0.1.8 only because Tauri closes the window itself when nothing listens for a close request; once the Conductor registered its close guard, every close path would have been dead. Both halves are fixed and verified on a release build.

Known gaps

  • The Conductor has had no rehearsal against Aurora on real acquisition hardware yet. LSL exposes only have_consumers, so the consumer count reads 0 or 1, never the true number.
  • Repairing a recorded .snirf from a session log (the log already carries planned versus actual durations for it), a participant-facing display, transports other than LSL, and a paradigm stored inside a .nirw or .nwstudy are all out of scope for this release.
  • The per-run route and the batch export are exercised by tests and by the Study panel, not yet by a full acceptance pass at the keyboard.

NIRWizard 0.1.8

Choose a tag to compare

@adamaske adamaske released this 11 Sep 17:44
41d12d3

NIRWizard 0.1.8 — tester builds for Windows and Linux (x64).

This release is about one participant, several runs. Until now a subject recorded in four files meant four NIRWizard instances and a stopgap script to glue them; 0.1.8 gives that participant two first-class routes to one first-level result, and gives a study one button for the first-level results of every file. It also finishes the Montage Creator's second pass — your own S/D numbers, undo/redo, a rebuilt editor layout, mirror placement and auto-fill — replaces the theme list with six designed themes, makes the interface legible and scalable (a bundled typeface and a UI zoom), and puts NIRWizard under its own licence.

Multi-run sessions

Open runs as one session

  • File ▸ Open runs as one session… takes N same-probe recordings of one participant and builds one session: the runs laid end to end on one continuous clock, gain-matched per channel to run 1 on intensity (so the seam carries no DC step), events shifted and merged by name, aux channels merged where every run has them. The order you confirm in the dialog is the run order.
  • Runs are a fact, not a fake stim. The Info panel gets a Runs card (file, span, samples, per-run gain); the time-series plot marks each seam as a labelled run k line; the block's lineage reads "Concatenated from 4 runs · …". There is no run_boundary event.
  • The contract is strict and named. Runs must share the probe (positions, wavelengths), the measurement list and the sampling interval; anything else refuses by run and by field. No silent channel intersection.
  • Round trips. The SNIRF export carries the run list as NIRWizard_ConcatenatedRuns (with the full per-channel gain) and re-opens with its runs; a .nirw project (now v5) stores every run's hash and rebuilds the session on open, refusing by run name if a file changed.

One GLM across the runs

  • The single-subject GLM fits one design across every run with N−1 run-intercept nuisance columns, per-run DCT drift (SPM's multi-session convention), and one pooled AR(P) whose whitening restarts at every seam — a block-diagonal W, no leak across runs, no rows dropped. A single-recording session's design is byte-identical to 0.1.7's.
  • The session confound is stated, never hidden. When a contrast weighs conditions that were measured in disjoint sets of runs (quiet in runs 1–2, noise in runs 3–4), the contrast is flagged confounded with session with a one-line reason on the panel, in export A and in the sidecar's Statistics block: "per-run intercepts absorb offsets, not the session effect — this contrast estimates condition + session". Nothing is refused; the posture is unchanged.
  • The GLM panel's posture bar reads the design out loud: "4 runs · 3 run intercepts · drift per run · whitening pooled".
  • Preprocessing runs on the joined block as one. A new warn-only sanity rule (rule 7) names every filter and motion step that ran across the N−1 seams; the gain match makes the optical-density reference well-defined across runs (docs/scientific_validity.md §3.12).

The per-run route

  • A Study-panel subject can declare its runs. Run multi-run GLM loads them, applies the subject's preprocessing to each, fits each run's first-level GLM and combines by precision-weighted fixed effects (nilearn / SPM's sanctioned alternative to concatenation — no seams, no gain matching, no AR leak). The combined result lands in the session's GLM slot, so the channel table, Show on cortex, ROI aggregation and exports A/B/C take it unchanged; the header says "fixed effects over 4 runs".
  • The per-run condition presence table (which run carried which condition, how many onsets) drives the condition picker, the contrast editor and the combine — one fact, three consumers — and the same session-confound rule applies.
  • The group RFX sees one β per subject, never one per run.

Batch first-level GLM

  • The Study panel's group run now keeps every subject's first-level result. A First-level results section lists each subject with its posture and channel count, opens one subject's fit inline, and Export all subjects… writes one folder per subject (exports A, B under FIR, C with ROIs) plus a subjects.csv index with each excluded subject's reason.
  • A study of one subject runs its first level and no RFX — never a df = 0 group result.

Spec and provenance

  • docs/scientific_validity.md gains §6.9 Multi-run sessions (both routes, with the SPM/nilearn citations behind every policy), §9.2 documents that Sources lists the runs in order and that optional fields never bump the schema, and Statistics.run_policies says which run policy every multi-run result was fitted under. ADR 0004 records runs as an entry-level fact; CONTEXT.md gains a Runs vocabulary.

Montage Creator

  • Your numbers, not the editor's. S/D numbers are now optional and yours: placing a site no longer refuses a duplicate number — conflicts and unnumbered sites are marked and listed as warnings instead. A Number tool numbers a selection in sequence, with six renumber orders previewed before they apply. One export gate (NIRSite folder, probeInfo.json, probe-only SNIRF) refuses while a conflict stands; saving a .nirwmontage never does.
  • Undo and redo over labelled whole-montage snapshots; the unsaved marker is derived from the history, so undoing back to the save clears it.
  • A rebuilt editor layout: a tool rail on the left (icons only when narrow), the 2-D top view in the middle, and a resizable sheet on the right — the active tool's block pinned over Optodes / Channels / Device / Warnings tabs plus an Inspector — above one action footer with the shortcuts for the current tool.
  • Mirror placement copies a selection to the other hemisphere by 10-5 label (odd ↔ even) and reflects free sites through the head's own fitted mid-sagittal plane, so a moved or rotated head still mirrors correctly. Occupied, midline and missing targets are skipped by name, never overwritten.
  • Auto-fill (A): drag a region on the top view, pick a spacing, and the free reference points in it are thinned to that spacing and filled as a source/detector checkerboard, with ghost markers previewing the result, its channel count and its port cost before you commit.
  • Quality of life: find on / (labels, S9, bare numbers, unplaced points); warnings you can click to select what they name, with a one-step fix inline where the fix is obvious; a live ports strip; crash recovery (an unsaved montage is snapshotted every 30 s and offered back on the next start); a ? shortcut sheet generated from the keymap; sortable optode and channel tables with copy-as-TSV; Save as template and recent montages; numbers / labels / both as Display settings.
  • The bundled template set: eight montages on the bundled colin27 10-5 grid, opened as unsaved copies via New from template…, beside the user's own NIRWIZARD_MONTAGES_DIR.
  • Fixed: opening a montage (New, or from a template) could crash the Montage Creator pane.

Legibility and UI scale

  • One bundled typeface. The interface is set in Atkinson Hyperlegible Next, with Atkinson Hyperlegible Mono for figures and identifiers, italics included. Both ship inside the app, so text looks the same on every OS and offline, and easily confused characters (l, 1, I) are distinct. Names and prose use the UI face and numbers the data face, in panels and in all twelve charts alike.
  • UI scale. View ▸ Zoom in / Zoom out / Reset zoom and Ctrl + / Ctrl − / Ctrl 0 scale the whole interface, with a brief readout in the status bar. The scale is remembered and applied before the licence screen. On a display 2560 px or wider whose webview does not report its DPI (the case that made NIRWizard nearly unusable on a 4K screen), the first start defaults to 150 %; Reset zoom returns to that machine's default rather than to 100 %.
  • Hierarchy by size, not capitals. Panel and section titles move up the type ramp, and no text is set in all-caps any more; grouping labels keep their role through a hairline rule and a muted colour.

Themes

  • Fifteen editor-theme ports are replaced by six designed themes — NIR, Gruvbox, Bench, Console, Ward and High Contrast — that differ in ground, accent, border weight and density, not only colour, so they are tellable apart at a glance. A saved theme that was retired moves to the closest designed theme of the same light/dark scheme; the dark/light toggle now flips NIR ↔ Bench.
  • Gruvbox no longer shows a selected channel in the same colour as its accent, and its status dots are distinguishable.

Licence

  • NIRWizard now ships under its own licence (LICENSE, shown by the installers): free to use for research, teaching and private study — including internal use inside a company, on any number of machines — with no redistribution, resale or embedding in a product. Results are wholly yours; citation is requested (CITATION.cff). The earlier MIT declaration in the Rust manifest is withdrawn. NIRWizard is not a medical device.

Known gaps

  • Block average, connectivity and QC read a concatenated block as one recording (an epoch that spans a seam is not yet rejected); session as a tested factor, per-run preprocessing before the join, and channel-intersection joins for drifted probes are listed in §11.
  • The per-run route and the batch export were exercised by tests and the Study panel, not yet on a full acceptance pass at the keyboard.
  • The new typeface and UI scale are held by guard tests, but the visual walk at 150 % (clipped labels in dense tables) and the Windows Snap-layout flyout at a non-100 % scale have not yet been checked by hand.

NIRWizard 0.1.7

Choose a tag to compare

@adamaske adamaske released this 05 Sep 13:16
41d12d3

NIRWizard 0.1.7 — tester builds for Windows and Linux (x64).

This release is about the DOT pipeline. 0.1.6 shipped a sensitivity visualiser with a reconstruction attached; 0.1.7 turns it into a quantitative imaging chain, connects the reconstructed image to the statistical chain, and measures the result against an independent implementation (Cedalion). The rest of the release is a workspace slot for the dock, a round of correctness fixes from a full architecture review, and a handful of Linux packaging fixes.

DOT pipeline

The work followed a written critique of the 0.1.6 pipeline against six 2025–2026 papers (docs/dot_critique.md). Every finding F1–F9 is now landed or ruled out with a reason on its ticket; what ships is described in docs/dot_math.md.

Forward model

  • Physical units (F1). The analytic kernel keeps its 1/D prefactor, MCX returns fluence rather than flux, the extinction table is in mm⁻¹/M, and the sensitivity matrix scales by each element's support volume instead of a dropped h³. Reported concentrations no longer change when you change the voxel size: previously a 1 → 3 mm voxel change moved the reported ΔHbO by 27× while the image looked identical. Voxel-size invariance is a gated test.
  • One Jacobian per wavelength (F2). The forward model runs once per wavelength from a per-tissue, per-wavelength optics table (Bulger et al. 2026, Table 1), producing one A and one W per wavelength over a shared element mask. HbO/HbR crosstalk from the shared-Jacobian shortcut drops from ≈11 % to ≈0.7 %. Wavelengths between the two table anchors (760/850 nm) are interpolated; outside them, clamped and reported.
  • Layered head by default (F3). The default engine is now a four-layer analytic slab (scalp/skull/CSF/brain, Liemert–Kienle) instead of a homogeneous half-space. The semi-infinite kernel remains an explicit choice. MCX transports through a five-label segmented head on any head that ships skull shells — and the bundled head now does.
  • colin27 is the startup head. The uncited single-subject "default" head and its hand-tuned 6° levelling transform are retired. A fresh install loads the colin27 MNI template through the atlas path, at identity, and every provenance record cites it by id and version.
  • Engine and medium are separate labels. Every run reports how fluence was computed (analytic / mcx) and what it was computed in (4-layer slab, homogeneous half-space, homogeneous head mask, or 5-label segmented head), so the engine token can no longer overstate the head model.
  • Oracle tests (F8). The forward model is held to a published closed form (DPF(ρ)·ρ within 0.8 %) and to MCX (layered vs MCX 0.93–1.00× on a slab). The MCX rows need a GPU and are ignored in CI.

Inverse model

  • Bad channels never reach A (F5a). Rows are the channels the QC bad-channel record spares; absences are reported as facts, not warnings.
  • Measurement covariance (F5b). C is the per-channel baseline ΔOD variance, applied by whitening. On by default.
  • Regularisation convention documented and defaulted to the literature (F6). The operator is NeuroDOT's λ₁/λ₂ form with the published 0.01 / 0.1 defaults, three named presets with citations, and an L-curve selector. (The old α_spatial = 0.01 was λ₂ = 0.1 on the other scale; nothing silently changed shape.)
  • Spatial smoothing (F7). A 3 mm FWHM row-stochastic kernel is folded into W, so every consumer of the operator sees the same smoothed image.
  • Quality maps (F9). PSF resolution maps, CNR and CBR (Guan et al. 2026 Eq. 6), and montage-adequacy rules 5–6 are reported with each reconstruction. Power curves were not taken.

The image domain as an analysis domain (F4, ADR 0003)

The reconstructed image is no longer a picture at the end of the pipeline; it is a second analysis domain the existing statistical chain reads:

  • Projected GLM. A channel-domain GLM β is projected through W to a vertex β with propagated error (exact for OLS; the AR-IRLS solver is refused by name rather than approximated).
  • Materialised series. Connectivity and block average run on W·Y over an ROI-bounded, budgeted vertex set. Block Average and Connectivity panels gain a Source selector (channels | image ROI vertices), and an Image Domain Facts card states the node count, thinning, and node spacing against PSF resolution.
  • Honest posture. The image has rank at most the number of channel rows, so image-domain results are mechanically descriptive; the rank ceiling is reported beside every result.
  • Canonical exports K–N. The epoch-mean image, the projected GLM, and the materialised image-domain connectivity / block average, each with a *_image_nodes.csv row-identity part and a provenance sidecar.

Cedalion comparison — the oracle harness

tools/dot-oracle/ is a re-runnable harness that runs the same colin27 head, the same registered optodes and the same 760/850 nm pair through four NIRWizard arms (layered analytic, semi-infinite analytic, MCX five-label, MCX homogeneous) and three Cedalion arms, at 2 mm and 3 mm voxels, and compares sensitivity rows per channel. It was run twice: against 0.1.6 and against this release (tools/dot-oracle/results/2026-09-05-381dda2.md).

What the second run says:

question metric result
Is the banana the right shape? median log-space r vs Cedalion, 760 nm 0.95–0.96 analytic, 0.89–0.95 MCX
Is the peak at the right depth? median depth of peak, NW vs Cedalion 17.2 mm on both; Δ = 0.0 mm on every arm
Do analytic and MCX agree inside NIRWizard? median r, 2 mm / 3 mm 0.93 / 0.95
Is the wavelength dependence right? 850/760 amplitude ratio, NW vs Cedalion per-wavelength 0.86–0.94 vs 0.88
Did the dropped h³ go away? scale ratio movement 2 mm → 3 mm first run 0.30 (the (2/3)³ signature); now 1.13–1.17

Where the two still differ, and what stays open on the verdict ticket:

  • Absolute amplitude. NIRWizard's A is 1.5–2.5× smaller than Cedalion's on the same cells, uniformly across arms. The named candidate is the depth at which the Rytov normaliser is sampled (one transport mfp inside the surface versus Cedalion's surface voxel).
  • MCX voxel-size dependence. The fixed-λ invariance test moves 1.9–4.0× between 2 mm and 3 mm on the MCX arms, against 1.14–1.42× analytic and 1.16× for Cedalion's own MCX.
  • Curvature. The layered analytic engine is plane-parallel under each optode; what that costs on a real head is priced only by the MCX arms.

The harness settled one thing the critique predicted: an unmodified Cedalion run simulates once per optode and copies the slab across wavelengths (r = 1.000000), so a comparison against it alone would have reported no wavelength effect. The per-wavelength Cedalion arm exists because of that.

Workspace

  • Workspace slot. The center tab strip is no longer an index of every panel. One group is the workspace slot: Pipeline-panel and Panels-menu clicks route workspaces there, an unpinned workspace is a preview the next click replaces, and pinning (glyph or double-click) keeps a tab. The default layout boots with one preview workspace instead of seventeen tabs. Saved layouts upgrade without closing anything you had open.
  • Short/long channel threshold is editable in the Info panel's Signal card. Previously the value was registered but had no UI, and importing a second file under a custom threshold announced the default while every analysis ran at your value.
  • Brand. New wizard-hat mark across the app icons, menubar and favicon.

Correctness fixes

From the architecture review sweep (docs/wayfinder-arch/, 27 tickets) and after:

  • Coordinates. Landmark placement, reference-point generation and spring relaxation queried the scalp mesh in world space with mesh-local structure. On the old default head that was ~9 mm of error at head radius. One frame type now owns the world ⇄ mesh-local composition, and world/tkRAS are distinct types in the backend.
  • FreeSurfer Torig. The MGZ reader built the tkRAS matrix wrong two ways (direction cosines read by rows, and used at all); the result was a 180° flip about R–L that only agreed with FreeSurfer at the volume centre. Verified on all three bundled heads. Surfaces now read their useRealRAS flag rather than being classified by filename.
  • MRI backdrop follows the installed subject; it used to come from the bundled head regardless.
  • Cropped blocks keep the recording's clock. SNIRF stim onsets are per entry and shared by every block, so a re-zeroed crop sat tmin seconds off its own events. Both backends now write on the recording's clock, and the GLM design no longer assumes time starts at zero.
  • Project selection saved by probe identity (source, detector) rather than session-local ids, which could silently resolve to a different channel on reopen.
  • 2-D probe layout is built from the active block, so channel selection survives a block switch.
  • One runaway effect no longer takes four panels down. A Spectrogram selection effect never settled and Svelte's global loop guard threw in whichever pane was being flushed. The jobs layer now holds the same invariant structurally.
  • Scene mutations mint their own geometry epoch, so a cached model result cannot outlive a transform edit.
  • HDF5 access is serialised through one lock; libh...
Read more

NIRWizard 0.1.6

Choose a tag to compare

@adamaske adamaske released this 23 Aug 17:47
41d12d3

NIRWizard 0.1.6 — tester builds for Windows and Linux (x64). Linux builds ship for the first time in this release.

The largest release so far: a new dockable workspace, a reworked statistical chain with provenance on every result, and Cedalion as the default preprocessing engine.

Workspace

  • New dock shell. The fixed layout is gone. All 30 panels are dockable, floatable and tabbable; drag them where you want them. Four built-in layout presets, saveable user presets, and the working layout is remembered between sessions and stored in .nirw projects. Panels are opened from the new Panels menu.
  • Theming. Gruvbox Dark is the new default; extra themes load from JSON files (NIRWIZARD_THEMES_DIR).

Analysis

  • QC surface. Six per-channel metrics (SCI/PSP/SNR/amplitude/SD/GVTD), a windowed quality view, editable thresholds, and one-click exclusion — feeding a first-class bad-channel record that GLM, block average and connectivity all respect.
  • GLM. SPM canonical HRF with derivatives or an FIR basis, DCT drift, short-channel nuisance regressors, an AR-IRLS solver, per-channel SE/df/p, and BH-FDR per condition × chromophore. Precision-weighted ROI combination.
  • Group analysis. Random-effects group GLM with FDR-masked cortex maps, partial-cohort exclusion manifests, pipeline-homogeneity checks and a hard stop on unit mismatch.
  • Block average, connectivity, laterality. Amplitude-range trial rejection with per-channel n and CI bands; Bartlett-corrected connectivity inference with an explicit regime label and nirconn import; Seghier laterality with FDR across ROI pairs.
  • Provenance. Every result is born with a provenance record (sources, parameters, exclusions, statistics) and can be exported as canonical CSV/TSV parts plus a JSON sidecar.

Preprocessing

  • Cedalion is the default engine, with the full step catalog running: conversions, zero-phase filters, the motion suite (TDDR, wavelet, spline, PCA), channel picking, short-channel regression, resample and crop. MNE remains selectable as the compatibility backend. The Homer3/MATLAB backend has been removed.
  • Data blocks. Preprocessing output no longer overwrites your recording — it lands beside it as a derived block with visible lineage. A block manager lets you select, rename, duplicate, freeze and delete blocks, and blocks survive SNIRF export.
  • Projects. .nirw v4 stores the block manifest as a recipe and replays it on open, restoring every cached result whose inputs still hash-match.

Performance & fixes

  • 3D viewport renders on demand instead of continuously; large time-series and spectra plots stream decimated binary data, so many-channel files stay interactive.
  • Panel crashes are contained instead of taking down the app.
  • Protocol generation, a feedback dialog, .nirwcoord import/export, and a TESTER BUILD marker in the statusbar.

Downloads

This release ships tester builds only. The license gate is disabled — they boot straight past the lock screen and show a "TESTER BUILD — unlicensed" marker in the statusbar. No license key is needed.

Windows (x64)

  • NIRWizard_0.1.6_x64_en-US-tester.msi — MSI installer
  • NIRWizard_0.1.6_x64-setup-tester.exe — NSIS installer

Linux (x86_64)

  • NIRWizard_0.1.6_amd64-tester.AppImage — self-contained; chmod +x and run
  • NIRWizard_0.1.6_amd64-tester.deb — Debian/Ubuntu
  • NIRWizard-0.1.6-1.x86_64-tester.rpm — Fedora/RHEL

The .deb/.rpm need WebKitGTK 4.1 and HDF5 from your distribution; the AppImage bundles them. Cedalion/MNE preprocessing needs a Python interpreter with those packages installed on any platform — see the README.

NIRWizard 0.1.5

Choose a tag to compare

@adamaske adamaske released this 01 Jul 18:20
41d12d3

NIRWizard 0.1.5 for Windows (x64).

Licensed builds (require a valid license key):

  • NIRWizard_0.1.5_x64_en-US.msi — MSI installer
  • NIRWizard_0.1.5_x64-setup.exe — NSIS installer

Tester build (license gate disabled — boots straight past the lock screen; statusbar shows a "TESTER BUILD — unlicensed" marker):

  • NIRWizard_0.1.5_x64_en-US-tester.msi — MSI installer
  • NIRWizard_0.1.5_x64-setup-tester.exe — NSIS installer