3dRSA


Usage: 3dRSA [options]

Representational Similarity Analysis (RSA) over atlas ROIs or searchlights.

For each ROI, 3dRSA builds a square NEURAL similarity matrix from your
imaging data, builds one or more MODEL matrices from behavior (or from
another modality, or from a file), and asks how well the models explain the
neural one.  Only the strict upper triangles are compared, since the
matrices are symmetric and the diagonal carries no information.

Significance always comes from permutation.  This is not a stylistic
preference: the entries of a matrix triangle are NOT independent, because n
items give n(n-1)/2 pairs but only n independent units.  Parametric p-values
over the triangle are therefore badly anticonservative.  The permutation
relabels the ITEMS, applying the same shuffle to rows and columns together
-- shuffling triangle entries instead is the classic Mantel error.

Two families of analysis, chosen with '-mode':

-mode IS-RSA (inter-subject RSA, the default)

Rows of the matrix are SUBJECTS.  Each subject contributes one feature
vector per ROI (by default the ROI-mean time course), the neural matrix
holds subject-by-subject similarity, and the model comes from a
behavioral column.  Asks: do people who are behaviorally similar have
similar brain responses?

-mode RSA (classic within-subject RSA)

Rows of the matrix are SUB-BRICKS (conditions).  Each subject gets their
own condition-by-condition matrix per ROI, compared against a model
matrix from '-model_mat' or their own fixed '-seed_mask' RDM. The
per-subject correlations are Fisher-z
transformed and tested against zero across subjects.

Input options:

-mask AAA    = Atlas (or ROI mask) dataset.  REQUIRED, with one exception
               (below).  Every distinct non-zero integer value is a separate
               ROI.  If the dataset carries a label table (as AFNI atlases
               do), those labels appear in the output table.
                 ++ EXCEPTION: a surface '-searchlight' (with '-surf') may
                    omit '-mask' to search the WHOLE mesh.  Unlike a volume,
                    a surface has no voxels that are skull, ventricle or air
                    -- every node is cortex -- so 'search everywhere' has a
                    coherent meaning a volumetric searchlight does not have,
                    where '-mask' stays required.  Expect a large, slow,
                    genuinely exploratory run.

-roi_sel LLL = Restrict to this list of ROI values, in the usual AFNI
               int-list syntax, e.g. '1,3,7..12'.

-seed_mask SSS = Seed representational connectivity (S5). SSS is a mask or
               atlas on the input grid defining ONE fixed seed ROI. 3dRSA
               builds the seed geometry from the same subjects and then
               compares it with every target ROI/searchlight from -mask.
                 ++ If SSS contains multiple positive atlas values, add
                    '-seed_roi VALUE' to select exactly one. The selector
                    uses the same AFNI integer-list grammar as -roi_sel but
                    must resolve to one ROI.
                 ++ Every target containing ANY seed voxel/node is removed
                    before BH and max-FWE inference. This is intentional:
                    shared measured features create seed-to-self noise
                    correlation. The excluded and searched counts are
                    recorded in the output.
                 ++ IS-RSA correlates the seed and target subject geometries
                    with the ordinary synchronized subject-label/null path.
                    Classic RSA correlates subject s's seed condition RDM
                    with subject s's target RDM, reports tanh(mean Fisher z),
                    and uses subject sign flips or '-classic_null conditions'.
                 ++ The seed uses the target's -featuretype, neural/condition
                    metrics, centering, runwise crossnobis, and noise
                    normalization. A seed is not a separately tuned model.
                 ++ -seed_mask is the complete one-model analysis: do not
                    combine it with model/joint/contrast/commonality/fitted/
                    LOO options. Subject -bootstrap and target reliability/
                    noise-ceiling output remain available. Condition
                    bootstrap and corr_cov/cosine_cov are rejected until
                    their two-noisy-RDM covariance contracts are defined.

-seed_roi RRR = Select the one positive atlas value used from -seed_mask.
               It is an error without -seed_mask or if multiple ROIs remain.

-searchlight NNN = Instead of atlas parcels, center a moving neighborhood on
               every non-zero voxel of the -mask and run RSA in each,
               painting the result at the center voxel -- a whole-brain map.
               NNN is a radius in mm (a sphere), or an explicit neighborhood
               in the same grammar as 3dLocalstat's -nbhd:
                 -searchlight 6              (sphere, radius 6 mm)
                 -searchlight 'SPHERE(6)'    (the same)
                 -searchlight 'RECT(6,6,6)'  (a box)
                 -searchlight 'RHDD(6)' / 'TOHD(6)'
               Supports IS-RSA and both forms of classic RSA:
                 ++ With '-dataTable', each sphere builds an ORDINARY, SAME-
                    DATA condition RDM for every subject, just as atlas-mode
                    RSA does.  The same condition estimates define and are
                    evaluated through that RDM, so it is not cross-validated
                    and does not have crossnobis's unbiased zero point.
                 ++ With '-runwiseTable', each sphere instead builds each
                    subject's CROSS-VALIDATED crossnobis condition RDM, with
                    '-noise_norm none', 'diag', or 'shrinkage'.  Prefer this
                    when conditions have independent repeated estimates.
               Both reuse the usual subject test/FDR/max-FWE path.
               All input datasets are held in memory, so watch memory on
               full-res data -- and doubly so with IS-RSA '-model_dset', which
               keeps the second modality resident too.  '-model_dset' IS
               supported: the
               cross-modal model is rebuilt from that other modality in each
               moving sphere, so you get a whole-brain map of where the two
               modalities share a subject geometry.  '-save_rdm' is not (it
               would write one matrix per voxel).

-memory_limit G = Searchlight peak-memory limit in GiB.  Before loading all
               subject datasets, 3dRSA estimates resident inputs, neighborhood
               indices, shared result/null/output arrays, and per-OpenMP-thread
               scratch (including crossnobis whitening).  By default it warns
               above 50% of detected physical RAM and refuses above 80%.
               This option replaces the 80% limit with G GiB, which is useful
               under a scheduler/container whose job limit is below host RAM;
               with an explicit limit, the warning begins at 75% of G.

-memory_override = Continue when the searchlight estimate exceeds its limit.
               This explicitly acknowledges overcommit risk; it does not make
               the allocation smaller.  Reducing OMP_NUM_THREADS often does.

-surf SSS    = Run the searchlight on a SURFACE instead of in the volume.
               SSS is the mesh geometry (a .gii/.asc/... surface), and the
               inputs (and -mask, if given) are surface datasets
               (.niml.dset/.gii) on that mesh.  Each in-mask node (every node,
               if '-mask' is omitted -- see above) centers a neighborhood of
               the nodes within '-searchlight R' mm ALONG THE SURFACE
               (geodesic, via SUMA), and the result is painted at the center
               node.
                 ++ With -surf, -searchlight takes a plain geodesic radius
                    in mm (not a SPHERE()/RECT() shape).
                 ++ Needs a build with surface support (compile -DUSE_SUMA,
                    link libSUMA); otherwise 3dRSA still does volume and
                    surface mask/atlas RSA, just not the surface searchlight.

-mode MMM    = 'IS-RSA' (the default) or 'RSA', as above.

-featuretype TTT = For IS-RSA, what each subject's feature vector is:
                 mean    = the ROI-mean time course [default].  Use for
                           resting state, movie/story listening, or any
                           continuously sampled data.
                 pattern = the ROI's spatial pattern, across voxels and
                           sub-bricks.  Use when the inputs are condition
                           betas and you want inter-subject similarity of
                           the spatial response rather than of a timecourse.
                           ++ '-noise_ceiling' is rejected for this feature
                              type: the input has no matched-repetition axis
                              from which to form a reliability split.
                 rdm     = SECOND-ORDER task-fMRI IS-RSA.  Build every
                           subject's condition-by-condition RDM inside this
                           ROI/searchlight, reduce it to its strict triangle,
                           then compare those RDM vectors across subjects.
                           This does not require voxel-by-voxel anatomical
                           correspondence between subjects.  With -dataTable,
                           '-condition_metric' builds each condition RDM.
                           With -runwiseTable, each subject RDM is crossnobis
                           (and may use '-noise_norm').  '-neural_metric' then
                           compares subject RDM vectors to build the outer
                           subject-by-subject neural matrix.
               Not used with '-mode RSA', which is always pattern-based.

-polort m    = Detrend each feature vector with a polynomial of order m,
               m = -1..9.  Default -1, meaning NO detrending, assuming
               your data are preprocessed.  Only for IS-RSA mean features.

-zcensor     = For continuous IS-RSA mean features, omit a TR from each
               SUBJECT PAIR's neural correlation when either subject's
               whole ROI/searchlight pattern is zero at that TR.  This is
               pairwise local censoring: a zero-filled frame never enters
               either the numerator or denominator for that pair.
               ++ Uses the original voxel pattern, not an ROI mean, so
                  nonzero voxels that happen to average to zero are kept.
               ++ Only valid with '-mode IS-RSA -featuretype mean' and
                  '-neural_metric corr' or 'scorr'.  At least 3 jointly
                  retained TRs are required for every subject pair.
               ++ Sets '-polort -1'.  A later '-polort' is allowed but
                  warned about: detrending zero-filled frames is generally
                  not a useful censoring estimand.
               ++ Not yet combined with -run_column, -model_dset, temporal
                  nulls, or -noise_ceiling, whose distinct missing-data
                  contracts must be defined explicitly.

Specifying data:

-dataTable   = The table of subjects, measures and datasets, in the format
               used by 3dMVM and 3dLME: a header row of column names, then
               one row per input.  'InputFile' holds the dataset; 'Subj'
               labels the subject.  Every other column is available to
               '-model' (if numeric) or '-model_dset' (if file names).

               Three ways to give it:
                 -dataTable Subj MADRS InputFile s01 22 s01+tlrc ...
                 -dataTable @table.txt
                 -dataTableFile table.txt

               In a FILE the header fixes the column count, so 'InputFile'
               may be in any column and a mis-counted row is reported with
               its line number.  Blank lines and '#' comments are ignored,
               and a line ending in backslash continues onto the next.
               Given DIRECTLY on the command line there is no line
               structure, so 'InputFile' must be the LAST column.

               Leave a subject with a missing dataset out of the table.
               3dRSA does no guessing about who is present.

-condition_column CCC = Alternative long-table input for traditional RSA.
               CCC names the condition-label column; each InputFile row must
               resolve to exactly ONE beta brick (an AFNI selector is fine):

                 Subj cond   InputFile
                 s01  house  s01_betas+tlrc[house]
                 s01  face   s01_betas+tlrc[face]
                 s01  tree   s01_betas+tlrc[tree]

               Rows may appear in ANY order. They are matched by Subj and
               condition values, not row position. Every subject must have
               exactly one row for every declared condition; duplicate,
               missing, and unexpected subject/condition cells are errors.
               Requires '-mode RSA' and '-condition_order'.

-condition_order L1,L2,... = Row/column order of every fixed -model_mat when
               -condition_column is used. This is MODEL-MATRIX order, not
               data-table row order. For example:

                 -condition_column cond \
                 -condition_order house,face,tree

               The labels are exact and case-sensitive. A numeric model
               matrix is unlabeled, so this explicit binding prevents a
               shuffled table from silently changing its interpretation.

-run_column CCC = Native multiple-run continuous IS-RSA. CCC names a column
               in -dataTable identifying repeated run rows for each Subj:

                 Subj Run behavior InputFile
                 s01  1   22       s01_run1+tlrc
                 s01  2   22       s01_run2+tlrc

               Each run is ROI-averaged and -polort detrended separately,
               normalized within run, then concatenated in the first
               subject's labeled run order. Run labels are matched by value,
               not row order. Every subject must have exactly the same runs
               and the same number of TRs in each corresponding run. Columns
               are subject-level and constant within subject unless explicitly
               named by -run_model or -run_factor. Nuisance/block stay constant.
               The resulting neural RDM still has SUBJECTS as its items; runs
               are repeated measurements, not independent observations.
               Currently supported with '-mode IS-RSA -featuretype mean' and
               '-null labels'. -model_dset, -seed_mask, and -noise_ceiling are
               rejected until their run-aware estimands are defined.

-run_normalize N = Within-run normalization for -run_column: zscore [default],
               demean, or none. zscore uses each ROI/run's population SD; a
               constant time course becomes zero. Concatenation weights runs
               by their number of TRs. -polort, when used, precedes this step.

-run_analysis A = How native continuous runs enter IS-RSA:
                 concatenate [default] = concatenate preprocessed runs, then
                   build one subject neural RDM (TR-weighted with zscore).
                 separate = build one neural RDM and model effect per labeled
                   run, plus an equal-run MEAN summary. FDR/max-FWE cover the
                   joint run x space family for the separate effects.
                 mean = report only the equal-run mean of the run-specific
                   model-association statistics. It is not correlation of
                   averaged RDMs and is not the concatenated estimator.
               All runs use the same synchronized subject-label relabelings.
               Fixed -model/-model_mat and -run_model effects are supported;
               planned run contrasts use -run_contrast. With -model_joint,
               every run is a standardized dyadic regression containing all
               fixed and run-varying models. MEAN and planned contrasts then
               combine conditional coefficients, not marginal correlations.
               -ortvec, between-model contrasts, fitted/LOO, bootstrap,
               model_series, and -save_rdm remain later run-model stages.

-run_model C:R = Build the behavioral model separately in every labeled run
               from numeric long-table column C. R is NN or AnnaK and has the
               same interpretation as -model. Use once per requested rule:

                 -run_model Happiness:NN
                 -run_model Happiness:AnnaK

               Requires -run_column and -run_analysis separate or mean. The
               observed effect uses Happiness for the matching run/movie. A
               permutation moves each subject's WHOLE Happiness trajectory
               together: one subject relabeling is shared over every run and
               spatial location. It never shuffles scores independently by
               run, and repeated rows are not treated as independent people.

-run_center C subject = Decompose a matching -run_model column into two named
               estimands. C_state_RULE uses C_ir - mean_r(C_ir) within each
               run; C_trait_RULE uses each subject's across-run mean and is
               constant over runs. Both are reported, so within-person movie
               response and stable between-person level are not conflated.
               Complete balanced scores are required in this first contract.

-run_factor F = Declare a run-level design column such as Condition or Movie.
               Its value must be identical across subjects for each labeled
               run, though it may change between runs. May be repeated.

-run_contrast NAME=F:POS-NEG = A fixed-run planned contrast. For every model,
               compute the equal-run mean association for factor level POS
               minus the equal-run mean for NEG. For four movies, for example:

                 -run_factor Condition                                      \
                 -run_contrast HappyMinusSad=Condition:happy-sad

               Runs/movies are fixed design cells in Stage 4, not a random
               sample of movies. The same whole-subject trajectory relabeling
               forms every run and contrast null. With 'separate', run effects
               and contrasts share one run/contrast x space BH/max-FWE family
               per model; with 'mean', each model's reported contrasts share
               contrast x space. Different behavioral models remain separate
               planned families, matching the ordinary 3dRSA convention.
               A subject model '-model group Group:match' gives same-group similarity;
               its HappyMinusSad result is the representational Group x
               Condition interaction. Add '-model_joint' with a Happiness
               -run_model to adjust that Group coefficient for Happiness in
               each movie; the contrast is then the adjusted interaction.
               This is fixed-movie conditional RDM regression, not a random-
               movie mixed-effects model or Group x Happiness moderation.

-runwiseTable FILE = A separate input for CROSS-VALIDATED condition RDMs
               (crossnobis), one row per subject x RUN:

                 Subj  Run  InputFile          ResidFile
                 s01   1    s01_r1_betas+tlrc  s01_r1_errts+tlrc
                 s01   2    s01_r2_betas+tlrc  s01_r2_errts+tlrc

               Ordinary classic RSA estimates each condition's pattern once
               per subject, so a distance measured and judged from the SAME
               noisy patterns is positively biased -- conditions look
               different even when they are not.  Cross-validation removes
               that bias by taking each condition contrast from INDEPENDENT
               runs, so the noise averages out.  That needs the data laid out
               by run, which -dataTable cannot express -- hence this table.
                 ++ By default, 'InputFile' has one sub-brick per condition,
                    in a common order across all rows. 'ResidFile' is OPTIONAL:
                    the run's
                    residual time series, needed only for the whitened
                    (Mahalanobis) crossnobis distance.
                 ++ F21 unbalanced input: add a 'ConditionFile' column. Each
                    row names a text file containing one whitespace-free
                    condition label per InputFile sub-brick. Conditions may
                    be absent from a run or repeated within it; repeats are
                    averaged into that run's estimate. The model/RDM order is
                    the lexical order of all labels and is printed in output.
                    Each condition PAIR must occur together in at least two
                    independent runs per subject. Its crossnobis estimate uses
                    only those valid ordered run pairs and their own
                    denominator. Blank/comment lines are ignored.
                 ++ S6 already-estimated trial betas: instead of
                    ConditionFile, add a mutually exclusive 'TrialFile'
                    column. Each TrialFile is a two-column table in local
                    InputFile sub-brick order, for example:

                      Trial       Condition
                      trial_001   face
                      trial_002   house

                    Subj and Run come from the containing runwiseTable row.
                    Trial IDs must be unique within subject. Trial betas for
                    the same condition are averaged WITHIN RUN, then the
                    existing independent-run crossnobis estimator operates
                    on those run-level condition patterns. This reads betas
                    already estimated by 3dDeconvolve/3dREMLfit/3dLSS; it
                    does not fit a first-level GLM or construct a trial-by-
                    trial RDM. Extra TrialFile columns are rejected in this
                    first contract so unused descriptors cannot be silent.
                 ++ Use with '-mode RSA' and a '-model_mat' over conditions,
                    or with '-mode IS-RSA -featuretype rdm' and one or more
                    subject-by-subject '-model_mat' matrices.  The latter
                    compares subjects by their crossnobis RDM geometry.
                    A runwise table has no subject-level behavioral columns,
                    so runwise second-order IS-RSA currently uses -model_mat
                    rather than '-model LABEL COLUMN:RULE'.
                    Requires >= 2 runs per subject; all InputFiles must share
                    the grid. Without ConditionFile/TrialFile they must share the
                    condition count/order. Run labels must be unique within a
                    subject. Everything
                    downstream is the ordinary classic-RSA path: the
                    cross-validated RDM is correlated with your model(s),
                    tested across subjects by sign flip, FDR- and FWE-
                    corrected, and '-model_contrast' works as usual.
                 ++ The distances are UNBIASED, so a condition pair that does
                    not truly differ scatters around zero: NEGATIVE distances
                    are expected and are kept as-is (clipping them at zero
                    would put the bias back).
                 ++ For whitened (Mahalanobis) crossnobis, add '-noise_norm'
                    (below) and a 'ResidFile' column; without it the distance
                    is cross-validated squared Euclidean (W = I).
                 ++ Add '-searchlight NNN' to compute the same runwise
                    crossnobis analysis in every moving neighborhood.

-noise_norm NNN = Noise-normalize the crossnobis distance using the residuals
               (needs '-runwiseTable' with a 'ResidFile' column).  Weighting
               each voxel by how noisy it is -- and, for the full version,
               decorrelating the voxels -- makes the distance a Mahalanobis
               distance and is what most improves crossnobis reliability
               (Walther et al. 2016).  NNN is one of:
                 none      No whitening (the default): plain cross-validated
                           squared Euclidean.
                 diag      Univariate: divide each voxel by its residual noise
                           SD (variances floored to the median, so a silent
                           voxel is not amplified).
                 shrinkage Multivariate: whiten by the FULL residual covariance
                           (Sigma^-1/2), regularized by Ledoit-Wolf shrinkage
                           toward a scaled identity with small eigenvalues
                           floored, so it stays invertible even when an ROI has
                           as many voxels as residual time points.  Recommended.
                           This still forms and eigendecomposes a dense p x p
                           covariance per subject and location.  For large
                           neighborhoods (roughly >128 voxels), benchmark first
                           and consider 'diag' or a smaller neighborhood.
               The covariance is estimated per subject per ROI from that
               subject's residual time series (each run demeaned first), never
               from the condition betas being compared.

MODELS – what you are testing, and how to say it

A model is a square matrix, the same size as the neural one, saying how
similar each PAIR of items ought to be if your hypothesis is true.  3dRSA
can build one three ways: from a column of numbers, from a file, or from a
second set of datasets.

-model LABEL CCC:RRR – build a matrix from a behavioral column

Takes dataTable column 'CCC' and turns it into a subject-by-subject matrix
using rule 'RRR'.  May be given more than once.  Only for '-mode IS-RSA'.

  A model column may also be a COMMA-SEPARATED list of columns, which builds
  a multivariate profile model: '-model mood PANAS_PA_Var,PANAS_NA_Var:euclid'.
  Each column is standardized and the subject-by-subject Euclidean distance
  over the whole profile is used -- a richer dyadic predictor than any single
  scalar (Chen et al. 2020).  The rank rules below are for single columns.

  For a profile the rule is 'euclid' or 'mahal':
    euclid  standardized Euclidean distance -- each measure weighted equally.
            Correlated measures (say three overlapping mood scales) then count
            more than once, tilting the distance toward whatever they share.
    mahal   MAHALANOBIS distance -- whitens by the measures' covariance, so
            correlated measures are down-weighted and each contributes its
            independent part.  Reduces to 'euclid' when the measures are
            uncorrelated.  The covariance is regularized (Ledoit-Wolf shrinkage
            toward the identity, small eigenvalues floored) so it stays
            invertible even when there are as many measures as subjects; 3dRSA
            prints the shrinkage used and the effective rank.  Scale- and
            column-order-invariant.  A constant column is rejected (it has no
            variance to whiten).

  annak    Similarity = ( rank(i) + rank(j) ) / 2n.
           The 'Anna Karenina' model, after the opening line: all happy
           families are alike, every unhappy family is unhappy in its own
           way.  Similarity depends on how HIGH the pair scores, not on
           whether they agree.  High scorers are predicted to look alike;
           low scorers are predicted to look idiosyncratic, each different
           from everyone including each other.
           ++ Use when one end of your scale is a well-defined state and the
              other is 'anything else' -- e.g. sustained attention, task
              engagement, or a symptom-free reference state.  Depression and
              anxiety scales often behave this way: healthy responses are
              stereotyped, disordered ones are heterogeneous.

  nn       Similarity = 1 - |rank(i) - rank(j)| / max, the 'nearest
           neighbor' model.  Subjects with SIMILAR scores are predicted to
           have similar brains, no matter where on the scale they sit.
           ++ Use when the scale is a graded dimension along which responses
              vary continuously, and both extremes are equally 'real'.

  match    Categorical similarity: 1 when the two subjects have the same
           data-table label, 0 otherwise. Labels may be text or numeric. Use
           '-model group Group:match' for a categorical group-geometry hypothesis.
           A positive effect means within-group brains are more similar than
           between-group brains; it does not encode which group is higher.

  euclid   Same shape as 'nn' but on the RAW values instead of their ranks.
           ++ Use when the units are meaningful and the spacing matters --
              when the gap between 10 and 20 really is twice the gap between
              10 and 15.  Ranking would throw that away.  It is also more
              sensitive to outliers than 'nn', for the same reason.

  absdiff  |x(i) - x(j)| on raw values, left as a DISSIMILARITY.
           ++ Identical information to 'euclid', but with the sign flipped,
              so a positive result means 'similar scores, DISsimilar
              brains'.  Use it when that is the natural way to state your
              hypothesis; otherwise prefer 'euclid'.

  ** annak and nn are EXACTLY orthogonal, for any number of subjects, and
     independently of your data.  'nn' depends on the rank DIFFERENCE and
     'annak' on the rank SUM, and over the complete set of pairs those two
     are uncorrelated.  So running both on one column is two genuinely
     independent tests, and there is nothing to disentangle between them --
     they need '-model_joint' no more than two unrelated variables would.
     What DOES need disentangling is two correlated behavioral scales
     (MADRS and HAM-D, say), or a behavior and a confound.

-model_mat LABEL FFF – read a matrix from a file

Reads a square matrix from the 1D file FFF, which must match the number of
rows of the neural matrix.  May be given more than once.

Required for '-mode RSA', where the rows are conditions and so cannot
come from a dataTable column.  This is how the classic designs are
expressed: 1 for pairs of conditions in the same category and 0 otherwise,
a matrix of stimulus low-level similarity, a semantic distance matrix from
word embeddings, and so on.

Also the way to bring in a model 3dRSA cannot build itself -- a matrix you
computed in R or Python, or one saved earlier by '-save_rdm'.

-model_series LLL – time-resolved model-RDM series (F20)

Reads an ORDERED list of per-timepoint model matrices and evaluates every
time point at every ROI/searchlight location in one run.  Each non-comment
row of LLL is:

    Time     ModelFile
    -100ms   eeg_m100.1D
       0ms   eeg_000.1D
     100ms   eeg_p100.1D

The header is optional.  Time labels must be unique single tokens; relative
ModelFile paths are resolved relative to LLL.  Every file is checked with
the same finite/symmetric/dimension contract as '-model_mat'.  At least two
time points are required, and input order is preserved.

The text output is LONG form (one row per time x ROI) and preserves the
verbatim time label.  Dataset bricks use safe t0000, t0001, ... labels, with
that mapping recorded in the table.  Crucially, one synchronized relabeling
drives the complete grid: BH FDR and max-statistic FWE are corrected over the
JOINT TIME x SPACE family, not separately at each latency.

May be used with classic RSA (condition RDMs), IS-RSA (subject matrices),
ordinary or runwise/crossnobis input, atlas ROIs, and searchlights.  It defines
the complete model set, so do not combine it with '-model', '-model_mat',
'-model_dset'.  Fitted/joint/nuisance models, contrasts, commonality,
and LOO need distinct time-series statistics and are rejected for now.

-model_series_subjects paired|loo LLL – dependent fusion

Reads a complete subject-indexed temporal model grid. Each non-comment row
of LLL is:

    Subj   Time     ModelFile
    s01    -100ms   eeg_s01_m100.1D
    s01       0ms   eeg_s01_000.1D

Rows may be reordered, but every subject x time cell must occur exactly once.
Subjects must match the imaging table exactly by label; matrix paths resolve
relative to LLL. The paired assertion means each matrix is that subject's own
EEG/MEG RDM. The loo assertion means each matrix is a group RDM constructed
without the named subject. 1dTrdm -model_series_out paired|loo writes these
manifests and their matrices. ModelFile entries are dissimilarity matrices;
3dRSA automatically reverses their sense when the neural estimator produces
similarities, so matching representational geometry always has positive sign.

This is classic '-mode RSA' only. Each subject's fMRI condition RDM is compared
with that subject's selected temporal model. Paired mode defaults to the
population-subject sign-flip test. LOO templates overlap across subjects, so
LOO defaults to '-classic_null conditions' and tests representational alignment
in the fixed observed participant sample; subject sign flips and subject
bootstrap would incorrectly treat the overlapping effects as independent and
are rejected. One condition relabeling is shared over subjects, time, and space.
BH FDR and max-FWE cover the complete time x ROI/searchlight family.
Ordinary/runwise neural RDMs and one-axis condition bootstrap are supported;
paired mode also supports subject bootstrap. Joint, nuisance, contrast,
commonality, fitted/predictive LOO, dual-bootstrap, and corr_cov/cosine_cov
extensions remain separate estimands and are rejected.

-model_dset LABEL CCC – use another modality as the model

Takes dataTable column 'CCC', which must hold DATASET names (one per
subject, like InputFile), and builds a neural matrix from them for EACH ROI
-- then uses that as the model for the main data in that same ROI.

This is the cross-modal case, and it is the reason RSA is a natural tool for
multimodal work.  MEG features (time by sensor) and fMRI features (voxels)
are not comparable in any direct way.  But once each is reduced to a
subject-by-subject geometry, the two live in the SAME space and can be
compared entry for entry.  So you can ask whether MEG and fMRI carry the
same representational structure in a region, and -- with '-model_joint' --
whether behavior explains the MEG geometry BEYOND what fMRI already does.

  ** Unlike -model_mat, which is one fixed matrix for every ROI, a
     -model_dset model is rebuilt per ROI.  That is the point: fMRI in
     region k is the model for MEG in region k.
     It therefore requires source-localized data on the SAME voxel grid as
     InputFile.  Sensor-space M/EEG belongs in fixed '-model_mat' matrices or
     a time-resolved '-model_series', not in '-model_dset'.
  ** Only for '-mode IS-RSA'.  Rows must be the same subjects, in the same
     order as the dataTable.
  ** The model datasets are reduced with the same '-featuretype' and
     '-neural_metric' as the main data.  Under '-featuretype rdm', each
     modality first gets its own per-subject condition RDM using
     '-condition_metric'; the resulting subject RDM geometries are compared.

-model_fit NAME=A,B,… – fitted weighted component model (F7)

Fits a nonnegative weighted mixture of two or more already named model RDMs.
Name components directly in the model options, select '-metric pearson', then
request, for example, '-model_fit combined=visual,semantic'.  Components may be fixed
matrices or per-location '-model_dset' matrices, but must all be similarities
or all be distances.  The fit is deliberately constrained and nested:
  * Each subject is held out in turn.  Classic RSA learns weights from every
    other subject's condition dyads; IS-RSA learns from dyads containing only
    the other subjects.  The held subject's dyads are used only for scoring.
  * Components and training neural values are standardized inside each fold.
    Nonnegative ridge regression learns weights.  Accuracy is the mean
    held-subject Fisher-z correlation, returned as '_cvR'.
  * Every label permutation repeats the COMPLETE nested fit.  IS-RSA jointly
    relabels subjects in all components; classic RSA jointly relabels their
    condition labels.  Raw/FDR/max-FWE inference therefore includes fitting.
  * Weight columns/maps are mean fold weights normalized to sum to one.  They
    describe component allocation but are not inferential statistics.

  -fit_ridge R       = Nonnegative ridge penalty [default 0.01], scaled by the
                       number of training dyads.  Zero gives nonnegative least
                       squares.  Applies to every -model_fit request.

  -fit_condfold FILE = F22 strict subject x condition generalization for
                       classic RSA. FILE has one whitespace-free fold label per
                       condition, in model-matrix order; blank/comment lines
                       are ignored. Each fold must hold >=3 conditions and leave
                       >=3 for training. Within every held-subject fold, weights
                       train only on other-subject dyads whose two conditions are
                       outside the held fold, and score only held-subject dyads
                       whose two conditions are inside it. Cross-boundary dyads
                       are excluded. '_cvR' is tanh(mean Fisher z) over all valid
                       subject x condition folds; weights average those folds.
                       Every condition-label null draw repeats the complete
                       two-axis fit. With mapped -runwiseTable input, FILE follows
                       the lexical condition order printed by 3dRSA.

Fitted-model contrasts support either F7 subject-only or F22 subject x condition
folds. Nuisance-adjusted fitting and bootstrap weight intervals remain separate
extensions. A model
series and temporal nulls are rejected rather than silently approximated.

-model_joint – test the models together instead of separately

By default each model is tested on its own, and you get one correlation per
model per ROI.  That is the right thing when the models are unrelated, but
it cannot tell you whether two significant models are two findings or one
finding counted twice.

With '-model_joint' the neural triangle is regressed on ALL the model
triangles at once:

    neural = b1*model1 + b2*model2 + ... + error

so each coefficient is that model's contribution with the others held fixed.
All triangles are z-scored first, so the b's are standardized and comparable
(with a single model, b is exactly the ordinary correlation).

Two things you get that you cannot get from separate tests:

  1. SEPARATING CORRELATED MODELS.  MADRS, HAM-A and HAM-D intercorrelate
     heavily; PANAS positive- and negative-affect variance both load on
     general affective instability.  Tested separately all three may come
     back significant in the same ROI without any of them being independent.
     Regress them together and read which one carries the effect.

  2. INTERACTIONS (in due course) and other derived structure, once your
     models are columns of one design rather than separate runs.

To remove a CONFOUND rather than test it -- head motion, tSNR, age -- use
'-ortvec' (below), not '-model'.  A confound belongs in the design as a
regressor of no interest, not as a model you report a coefficient for.

Significance uses the Freedman-Lane scheme: to test model j, the neural
triangle is first fit by the OTHER columns (other models and every nuisance),
and only the residual of that reduced fit is permuted before refitting.  That
tests model j specifically, rather than the joint null that every model is
zero.  The output reports the standardized b, the partial correlation, and
the permutation p for each model.

3dRSA prints the correlations AMONG your models before it starts.  Read
them.  Two models correlated at 0.9 will split their shared effect
unpredictably between them, and neither may reach significance even when the
effect is strong -- the familiar collinearity problem, not a bug.

-ortvec CCC – remove a nuisance without testing it

Takes the numeric dataTable column 'CCC' -- head motion, say -- and projects
it out of the neural matrix before the models are fit.  It gets NO reported
coefficient and is never tested: a regressor of no interest, exactly like
motion in an fMRI GLM.  May be given more than once.  IS-RSA only.

The subtlety, and why this is not just '-model motion Motion:something': IS-RSA
lives in PAIR space.  The neural outcome is one value per pair of subjects,
so a per-subject nuisance has to be given a per-pair form before it can be
removed -- there is no 'raw' version, because similarity is a property of a
pair, not of a subject.  (This is the one place the fMRI analogy breaks: in
a GLM everything already lives in time, so motion drops in as-is; here
nothing lives in pair space until you map it.)

A confound can inflate neural similarity two ways, and you should not have
to guess which: subjects with SIMILAR motion share artifacts (a difference
effect), and subjects who BOTH move a lot share artifacts (a level effect).
So each -ortvec column is removed as TWO pairwise nuisances, |m_i - m_j| and
m_i + m_j, which together span any pairwise structure linear in the
covariate.  No annaK/NN shape is assumed -- that is the whole point.

'-ortvec' works with or without '-model_joint'.  Without it, each model is
still tested on its own, but with the nuisances removed from both sides, so
the reported effect is a partial correlation.

-model_contrast A-B – does model A fit better than model B?

The most common follow-up question in RSA is not 'is this model significant'
but 'is THIS model better than THAT one' -- visual vs semantic structure, a
categorical vs a continuous account, and so on.  Two separate p-values cannot
answer it: both models can be significant, or the stronger one just miss, and
neither tells you whether the DIFFERENCE is reliable.  '-model_contrast A-B'
tests that difference directly.

Name the models in their model options so the contrast reads cleanly:

    -model_mat visual   visual.1D
    -model_mat semantic semantic.1D
    -model_contrast visual-semantic

(A and B are model names.  May be given more than once for several contrasts.
Under IS-RSA either side may also be a per-location '-model_dset';
both modality RDMs are rebuilt in the same ROI/searchlight before comparison.)

For a spatially varying multimodal contrast:

    -model_dset EEG  EEGfile \
    -model_dset fMRI fMRIfile \
    -model_contrast EEG-fMRI

The comparison is always paired, but PAIRING DOES NOT DETERMINE THE NULL.
Choose the scientific hypothesis explicitly:

  -contrast_hypothesis superiority
    H0 is equal paired model performance, including when both models have
    nonzero performance. IS-RSA uses a centered paired subject bootstrap:
    every draw resamples the neural RDM and both model RDMs together, omits
    duplicate-copy diagonal dyads, and tests d*-d_obs. Classic RSA with
    '-classic_null subjects' sign-flips per-subject Fisher-z differences (or
    uses '-group_test signedrank'). For two fitted models, each outer subject
    contributes its mean A-B Fisher-z difference over folds valid for BOTH
    models; a centered paired outer-subject bootstrap tests that held-out
    performance difference and uses synchronized draws for spatial max-FWE.

  -contrast_hypothesis alignment
    H0 is the sharp absence of alignment between the neural and model geometry.
    One shared item relabeling is applied to both models.  This is available for
    IS-RSA label/temporal nulls and classic '-classic_null conditions'.  It does
    NOT test equality of two possibly nonzero model performances.

  -contrast_hypothesis legacy [compatibility default]
    Retains the historical mode-dependent null, labels it in output provenance,
    and warns so old scripts continue to run without silently claiming one null.

-classic_null NNN = Which population classic-RSA inference samples:

    subjects   [default] = Population-level random-effects inference. Each
                 subject's Fisher-z model fit is sign-flipped; paired
                 contrasts may instead use '-group_test signedrank'. This
                 supports inference beyond the observed subject sample and
                 needs multiple independent subjects.
    conditions = Fixed-effects inference for the OBSERVED subject sample.
                 One condition relabeling is applied jointly to RDM rows and
                 columns and shared across every subject, fixed model in a
                 paired contrast, ROI/searchlight, and OpenMP worker. The
                 tested statistic is mean subject Fisher z (or the paired
                 mean Fisher-z difference), so a single-subject analysis is
                 valid -- but does NOT generalize to a population of subjects.
                 The first contract covers separately tested fixed model
                 matrices and their paired contrasts, ordinary or runwise/
                 crossnobis, including corr_cov/cosine_cov. Joint regression
                 needs a predictor-specific reduced-model condition null and
                 is rejected for now. Existing commonality/fitted-model nulls
                 keep their own documented condition-relabeling estimands.

Classic output reports TWO effects: '_zDiff' is mean_s[atanh(rA_s)-atanh(rB_s)]
on the inferential scale, while '_rDiff' is the descriptive mean_s[rA_s-rB_s].
They are not transforms of one another. Bootstrap bounds are explicitly named
'_zDiff_bootLo/Hi' (or dualLo/Hi). IS-RSA retains '_diff'=rA-rB. Dataset maps
use rDiff/zDiff/Zstat for classic contrasts and diff/Zdiff for IS-RSA. Each
contrast has its own max-statistic FWE family.

F14 extends the same syntax to TWO fitted models:

    -model_fit GOOD=visual,semantic
    -model_fit BAD=visual,nuisance
    -model_contrast GOOD-BAD

This is a paired held-out comparison, not a comparison of in-sample fits.
For every outer held-subject fold, both mixtures are learned without that
subject and scored on that same held subject.  The reported '_cvDiff' is
mean[ Fisher-z(r_GOOD,fold) - Fisher-z(r_BAD,fold) ] over paired folds.
With '-fit_condfold', each subject fold expands into the same strict held-
condition folds for both models, so the paired difference generalizes over
both axes and never uses cross-boundary condition dyads.
For alignment/legacy inference, every null draw applies the SAME subject
(IS-RSA) or condition (classic RSA) relabeling to both models and completely
refits both. For superiority, the original common held-fold fits supply paired
outer-subject effects to the centered bootstrap described above. In both cases
p/q and max-FWE are two-sided. Output columns are '_cvDiff/_cvP/_cvQ'
and optional '_cvPfwe'; maps are '_cvDiff', '_cvZdiff' (or uncalibrated
'_cvFZdiff' at -nperm 0), and '_cvZdiffFWE'.  Mixing one fixed and one fitted
model in a contrast is rejected because their estimands differ.

-model_commonality A,B[,C] – how does variance SPLIT?

Where the contrast asks 'which model wins', commonality analysis asks 'how do
they divide the work' -- the natural question when two accounts might each add
something, as when an EEG-derived and an fMRI-derived RDM both describe the
same conditions.  It reports the raw three-piece partition of the variance the
two models JOINTLY explain, plus two unique-effect partial R2 values:

    uniq_A  = R2(A,B) - R2(B)      what A explains that B does not
    uniq_B  = R2(A,B) - R2(A)      what B explains that A does not
    common  = R2(A) + R2(B) - R2(A,B)     what the two share
    partialR2_A = uniq_A / (1-R2(B))       A's share of variance left by B
    partialR2_B = uniq_B / (1-R2(A))       B's share of variance left by A

where R2(A), R2(B) are the single-model fits and R2(A,B) the joint two-model
fit (all under '-metric', ranks first for Spearman -- the same regression
'-model_joint' uses).  The three RAW terms sum to the joint R2(A,B); the two
partial terms are added effect sizes and are not part of that identity.  If a
reduced fit leaves no residual variance, its corresponding partial R2 is 0.

  'common' CAN BE NEGATIVE.  That is not an error: it means SUPPRESSION -- the
  pair together explains MORE than the sum of their separate fits (each model
  soaks up noise the other is confused by).  3dRSA reports it unclipped.

Name the two models directly in their model options, then list them comma-separated:

    -model_dset EEG  EEGfile
    -model_dset fMRI fMRIfile
    -model_commonality EEG,fMRI

F8 accepts THREE named models in the same option.  A,B,C returns the seven
exhaustive raw regions: unique A/B/C; common AB excluding C, AC excluding B,
and BC excluding A; and common ABC.  These seven (shared terms still
unclipped) sum to R2(A,B,C).  It also returns partialR2_A_given_B_C and its
B/C counterparts, so conditional effect sizes remain available just as in
the pairwise analysis.  For example:

    -model_commonality EEG,fMRI,behavior

Unique-effect inference is CONDITIONAL.  To test A, 3dRSA fits the reduced
neural~B model (or neural~B+C for a triple), relabels only that residual RDM,
adds it back to the fixed reduced fit, and refits the full model
(Freedman-Lane); the other unique effects are tested analogously.  Thus each
uniq/partialR2 pair tests what its model adds beyond all competitors.  Shared
regions are not added-variable effects and retain the complete neural-item
relabeling null.  The models stay fixed throughout, so
their mutual correlation is preserved.  Each quantity gets its own two-sided
permutation p and max-stat FWE family.

For IS-RSA, items are subjects and those residual/complete RDMs are relabeled
by subject.  For classic RSA, the decomposition is first computed separately
for every subject and the group statistic is the mean component.  One shared
CONDITION permutation relabels every subject's reduced residual RDM (or full
neural RDM for 'common') in a draw, and that same draw is shared over all
ROIs/searchlights.  This avoids the invalid subject sign flip that would find
non-negative squared semipartials trivially, while preserving synchronized
spatial max-FWE.  It supports ordinary and runwise/crossnobis classic RSA;
optional subject bootstrap intervals resample the observed subject components.

Output per request: 'uniq_A / uniq_B / common_A_B / partialR2_A /
partialR2_B', each with '_p / _q' (and '_pfwe'), plus a value + signed-z
sub-brick for each (and a '_ZFWE' map).  Repeatable, and it composes with
'-model_contrast': give both to
get 'which model wins' AND 'how the variance splits' from one run.
A triple uses explicit labels such as 'uniq_A_given_B_C',
'common_A_B_not_C', 'common_A_B_C', and 'partialR2_A_given_B_C'.

INTERPRETATION: the raw uniq_* values remain on the joint R2 decomposition
scale, so their magnitudes shrink as the competing model approaches the
reliability ceiling.  Prefer partialR2_* when reporting the size of a unique
effect across fits with differently strong competitors.  Both forms now use
the matching reduced-model null; keep common_* on its raw decomposition scale.

Similarity and testing:

-neural_metric NNN = How two feature vectors become one matrix entry:
                       corr   = Pearson correlation [default].  Equivalent
                                to 1 minus the 'correlation distance' used
                                by most Python RSA packages.
                       scorr  = Spearman correlation.  Robust to outliers
                                and to monotone nonlinearity.
                       cosine = cosine similarity.  Like Pearson but
                                without removing the mean, so overall
                                signal level still counts.
                       euclid = Euclidean distance, a DISSIMILARITY, so it
                                flips the sign of the result.
                     Under '-featuretype rdm', these are subject RDM-triangle
                     vectors.  The within-subject condition RDM itself is
                     controlled separately by '-condition_metric'.

-condition_metric NNN = With '-featuretype rdm' + '-dataTable', how condition
                     patterns become each subject's inner RDM: corr [default],
                     scorr, cosine, or euclid.  With '-runwiseTable' the inner
                     estimator is crossnobis instead, so this option is not
                     used.

-center_conditions CCC = Preprocess ORDINARY condition patterns before their
                     within-subject RDM is built:
                       none    = keep the raw patterns [compatibility default].
                       subject = at every ROI/searchlight, subtract that
                                 subject's voxelwise mean pattern across all
                                 conditions. This is also called cocktail-
                                 blank removal or re-meaning. It prevents a
                                 shared baseline pattern from dominating corr,
                                 scorr, or cosine condition geometry.
                     Applies to '-mode RSA -dataTable' and ordinary second-
                     order '-mode IS-RSA -featuretype rdm'. It is applied to
                     both modalities when '-model_dset' builds a second-order
                     model RDM. Euclidean distances are algebraically invariant
                     to the common subtraction and retain exact legacy values.
                     With '-runwiseTable', crossnobis condition contrasts already
                     cancel common within-run patterns; CCC=subject is rejected
                     rather than pretending to define a partition-wise policy.

-metric MMM        = How the two triangles are compared:
                       spearman = rank correlation [default].  The usual
                                  choice, because a model built from ranks
                                  is not linearly related to neural
                                  similarity -- only monotonically.
                       rhoa     = expected Spearman correlation under
                                  independent random ordering within ties.
                                  It equals Spearman when neither triangle
                                  has ties, but does not reward categorical
                                  models merely for predicting tied entries.
                                  Fast alternative to ktaua for tied RDMs.
                       pearson  = product-moment correlation.
                       ktaub    = Kendall's tau-b.  Much slower.
                       ktaua    = Kendall's tau-a (no tie correction).
                                  Nili et al. (2014) recommend tau-a over
                                  tau-b for MODEL RDMs with many tied
                                  entries -- e.g. a category same/different
                                  matrix, which has only two distinct
                                  values -- where tau-b's tie correction can
                                  distort model rankings.  Slowest option.
                       corr_cov = covariance-whitened Pearson RDM
                                  correlation.  Removes each triangle mean.
                       cosine_cov = covariance-whitened RDM cosine (WUC).
                                  Retains the meaningful crossnobis zero.
                     corr_cov/cosine_cov use the Diedrichsen et al.
                     zero-distance covariance V=(C C') o (C C'), exactly
                     equivalent to comparing centered second-moment matrices.
                     Their first contract requires classic RSA, balanced
                     -runwiseTable crossnobis, and fixed dissimilarity
                     -model_mat/-model_series inputs.  Subject bootstrap,
                     fixed-model contrasts, noise ceilings, atlas ROIs, and
                     searchlights are supported.  Condition-mapped/unbalanced
                     runs and condition bootstrap need an unequal-support
                     covariance and are rejected rather than misweighted.
                     rhoa is a scalar RDM comparator; it supports primary
                     effects, model contrasts, bootstrap intervals, noise
                     ceilings, LOO, atlas/searchlight inference, and temporal
                     nulls.  It is not a regression/commonality/fitted-model
                     objective; use spearman for rank-based regression.
                     '-model_joint' and '-ortvec' use least squares.  Under
                     -metric spearman the triangles are ranked first, so
                     the fit is a Spearman partial correlation and a single
                     model reproduces its ordinary Mantel result; -metric
                     pearson leaves the raw similarity values.  ktaub is
                     not available for the regression paths.

-nperm N           = Number of permutations [default 5000].  The identity
                     relabeling is slot 0 of the set and is counted, so the
                     smallest reachable p is 1/N; N=5000 bottoms out at
                     0.0002 -- fine for FDR over a few hundred ROIs, but for a
                     searchlight FWE column push N to 5000-10000+ (the
                     corrected p floors at 1/N as well).
                       ++ Exception: IS-RSA '-contrast_hypothesis superiority'
                          uses N random paired subject-bootstrap draws, not
                          permutations.  It uses the Monte-Carlo plus-one
                          correction, so its smallest p is 1/(N+1).
                       ++ N=0 SKIPS inference.  In '-mode RSA' it then falls
                          back to a parametric one-sample t across the (
                          independent) subjects, a legitimate z.  In '-mode
                          RSA -classic_null conditions', N=0 is rejected:
                          the fixed-effects null has no parametric replacement.
                          In '-mode
                          IS-RSA' there is no valid parametric test -- the
                          dyads are not independent -- so no p/q/FWE is
                          produced and the second sub-brick is an UNCALIBRATED
                          Fisher-z effect map ('_FZ', not FIZT-typed).  Use
                          N=0 only for a quick effect-size look.

-null NNN          = Null hypothesis for IS-RSA [default labels]:
                       labels    = relabel subjects in every model matrix;
                                   tests behavior-to-brain association.
                       timeshift = independently circular-shift every
                                   subject's ROI-mean time series before
                                   rebuilding the neural matrix; tests
                                   whether shared temporal alignment matters.
                       phase     = independently randomize every subject's
                                   positive-frequency Fourier phases before
                                   rebuilding the neural matrix; preserves
                                   the complete series' mean and power spectrum
                                   while destroying phase-locked alignment.
                     'timeshift' requires continuous '-featuretype mean',
                     equal-length gap-free series, and -nperm > 0.  One
                     immutable offset set is reused at every ROI/searchlight,
                     preserving thread reproducibility and max-stat FWE.
                     Per location, all subject-pair similarities are computed
                     once for every RELATIVE circular lag; each null draw is
                     then a table lookup rather than a full matrix rebuild.
                     With '-model_dset', only InputFile is shifted; the model
                     modality remains unshifted, explicitly testing whether
                     their shared temporal alignment matters.
                     Primary effects, paired fixed/per-location model
                     contrasts, joint regression, and separately fitted
                     nuisance-adjusted regression are supported.  A
                     regression coefficient remains conditional on its
                     other model/nuisance columns, but its complete-series
                     shift null destroys all cross-subject temporal alignment;
                     this is not the residual-label (Freedman-Lane) null used
                     by '-null labels'.  Commonality, LOO, and -block remain
                     rejected pending distinct time-shift contracts.
                     'phase' has the same continuous-series statistic and
                     supported effect families.  DC and the real-signal
                     Nyquist bin are retained; every other conjugate Fourier
                     pair receives an independent uniform phase by subject
                     and draw.  One stateless seeded phase family, including
                     identity slot 0, is shared across ROIs/searchlights for
                     reproducible max-FWE.  Each worker Fourier-transforms a
                     searchlight's local subject means once, reuses that local
                     spectrum for every draw, then replaces it at the next
                     center.  Model matrices remain
                     unrandomized; commonality, LOO, -block, and segmented
                     inputs remain rejected.

-min_shift K       = With '-null timeshift', require every random offset to
                     have circular distance at least K TRs from zero [1].
                     Choose K from the temporal autocorrelation scale.  The
                     identity remains slot 0 solely for the finite-sample
                     empirical-p correction; all other slots obey K.

-bootstrap N       = Draw N ordinary subject-bootstrap samples (N >= 20) and
                     report a
                     percentile confidence interval for every primary model
                     effect, model contrast, and commonality component.
                     Subjects are sampled
                     with replacement; one
                     shared resample set is used for every ROI/searchlight,
                     independently of the permutation null.
                       ++ IS-RSA: when a subject is sampled twice, the dyad
                          between those two copies is the repeated-subject
                          diagonal artifact and is omitted.  It is NOT entered
                          as a zero-distance or unit-similarity observation.
                       ++ RSA: resamples the independent subject effects; an
                          ordinary correlation is averaged in Fisher-z space.
                          A contrast resamples the paired within-subject
                          Fisher-z differences and reports tanh(mean diff).
                       ++ IS-RSA contrasts resample both model fits together
                          and bound their paired correlation difference, with
                          repeated-subject diagonal artifacts still omitted.
                       ++ IS-RSA commonality recomputes all pairwise or
                          three-predictor raw regions and conditional
                          partial-R2 effects on every compact paired draw.
                       ++ Adds '<model>_bootLo/_bootHi' and
                          '<A-B>_bootLo/_bootHi' table columns and
                          '<component>_bootLo/_bootHi' commonality columns,
                          matching plain-float dataset sub-bricks.  These are
                          uncertainty bounds, not p-values or multiplicity
                          correction.
                       ++ With '-loo', also adds '<model>_looBootLo/
                          _looBootHi'.  These resample completed held-out
                          prediction/target rows, synchronously across a
                          multivariate profile.  They quantify uncertainty
                          over the evaluated subjects with predictions held
                          fixed; they do NOT include fold-refitting or
                          training-set instability.
                       ++ IS-RSA joint/nuisance fits are refit on each compact
                          missing-dyad draw; their intervals bound the reported
                          standardized coefficient ('_b'), not partial-r.
                       ++ With '-block', subjects are resampled WITHIN each
                          block and every block keeps its observed sample size.
                          This is a stratified subject bootstrap.  It assumes
                          independence within strata; it is NOT a whole-cluster
                          bootstrap for families or sites.

-boot_ci P         = Percent confidence level for -bootstrap [default 95].
                     Also sets the confidence level for -cond_bootstrap.
                     With both axes it sets the corrected dual-bootstrap
                     t interval.
                     P must be greater than 0 and less than 100.

-cond_bootstrap N  = Draw N condition/stimulus bootstrap samples (N >= 20)
                     for classic '-mode RSA'.  The SAME sampled condition
                     indices subset every subject's neural RDM and every
                     model RDM, so their axes never lose alignment.
                       ++ Duplicate copies of one original condition create
                          a trivial off-diagonal diagonal entry; that dyad is
                          omitted rather than entered as zero/unit similarity.
                       ++ Supports ordinary and runwise/crossnobis ROI or
                          searchlight RSA, tested separately or jointly.
                       ++ Alone, adds '<model>_cbootLo/_cbootHi' table columns
                          and matching plain-float dataset sub-bricks.
                       ++ With '-bootstrap N' using the SAME N, performs the
                          F6 dual subject x condition bootstrap.  It combines
                          subject-only, condition-only, and simultaneous-draw
                          variances with the finite-sample correction, then
                          reports '<model>_dualLo/_dualHi'.  These are one
                          joint-generalization interval, not two one-axis CIs.
                       ++ Dual intervals support fixed primary models,
                          '-model_joint', fixed '-model_contrast', grouped
                          conditions, and atlas/searchlight outputs.  They do
                          not yet cover commonality, fitted models, model
                          series, or noise ceilings.

-cond_group FILE   = Optional grouping descriptor for -cond_bootstrap. FILE
                     has one whitespace-free label per condition, one label
                     per nonblank/noncomment line, in sub-brick/model order.
                     Conditions with the same label are sampled in or out as
                     one unit; groups may have different sizes.

-block CCC         = Exchangeability/bootstrap strata: dataTable column 'CCC'
                     groups subjects (by site, scanner, cohort, ...) and the
                     permutation only swaps subjects WITHIN a block, never
                     across.  Use it when subjects are not freely
                     exchangeable -- e.g. multi-site data where site is a
                     nuisance you have not otherwise modeled.  The column may
                     be text or numbers; distinct values become blocks.
                     ++ IS-RSA only.  Classic '-mode RSA' either sign-flips
                        subject effects or relabels conditions; subject blocks
                        restrict neither operation, so -block there is an
                        error, not a silent no-op.
                     ++ With '-bootstrap', subjects are sampled with replacement
                        within each block, preserving its original N.  Blocks
                        therefore mean strata, not dependent clusters.  Do not
                        use this as a whole-family or whole-site bootstrap.

-seed S            = Seed the random number generator, to reproduce a run.
                     Default is to seed from the clock and print the seed.
                     ++ One relabeling set is built up front and shared by
                        every ROI/voxel, so a given seed reproduces the same
                        numbers no matter how many threads the run uses.

Output options:

-prefix PPP  = Write 'PPP.rsa.1D' (a text table, one row per ROI) and the
               dataset 'PPP', in which each ROI is painted with its own
               result: two sub-bricks per model, the effect and a z-score
               marked as such so it thresholds in the AFNI GUI.
               Default prefix is 'RSA'.
               ++ Per-ROI/voxel inference gives three multiplicity handles per
                  model, from least to most stringent: the raw permutation p
                  ('_p'), a Benjamini-Hochberg FDR q over the ROIs ('_q'), and
                  a max-statistic family-wise p ('_pfwe', with signed z map
                  '_ZFWE').  See 'Family-wise error correction' below for what
                  the FWE column is and when to prefer it.

-noise_ceiling = Add a reliability estimate per ROI, so a weak model fit can
               be read as 'wrong model' vs 'noisy region'.
                 IS-RSA mean features: splits the ROI-mean time course,
                   builds the subject matrix from each half, and correlates
                   them -- does this region's subject geometry replicate?
                   Reported as one 'reliability' column.
                   '-featuretype pattern' is rejected: its flattened
                   [sub-brick][voxel] vector contains no matched repetitions,
                   so splitting it would confound condition and/or voxel
                   identity with reliability.
                 RSA: the Nili et al. (2014) noise ceiling -- each subject's
                   condition RDM vs the group-mean RDM (upper bound,
                   'nc_high') and vs the leave-one-subject-out mean of the
                   others (lower bound, 'nc_low').  A model reaching nc_low
                   is doing as well as the data reliability allows.
                   This applies to ordinary condition-pattern RDMs and to
                   '-runwiseTable' crossnobis RDMs.  In the runwise case,
                   independent runs define every subject RDM before the
                   subject-level ceiling is calculated; residual whitening,
                   if requested, is applied before crossnobis.  The fixed
                   model has no fitted condition parameters, so no condition
                   data enter a fit.  'nc_low' excludes the evaluated subject;
                   'nc_high' includes it by the conventional upper-bound
                   definition and is intentionally optimistic.
                 ++ These also go into the output dataset as sub-bricks
                    ('reliability', or 'nc_low'/'nc_high'), so under
                    -searchlight you get a whole-brain reliability map to read
                    alongside the effect: a null effect where reliability is
                    high is a real miss, where it is low is just noise.

-nc_split SSS = How to split continuous IS-RSA mean features for reliability
               [default 'half']:
                 half       = first half of the time course vs the second.
                              Temporally independent, so not inflated by
                              autocorrelation, but the halves differ in
                              stimulus content -- a conservative estimate.
                 interleave = even samples vs odd samples.  Content matched,
                              but adjacent-sample correlation inflates it
                              (more so for fast-sampled data like MEG).
               The two carry opposite biases; report which you used.

-loo         = Leave-one-subject-out prediction (IS-RSA only).  Holds out
               each subject, predicts behavior without using that subject's
               target, then reports cross-validated accuracy with a subject-
               label permutation p.  The predictor follows the model shape:
                 nn/euclid/absdiff scalar = neural-neighbor rank-weighted
                       mean of the training subjects' behavior (nearer gets
                       more weight; neural distances are negated first).
                 annak scalar = training-only neural typicality regression.
                       In each fold, the remaining subjects' behavior is fit
                       from their mean neural closeness to one another; the
                       held behavior is predicted from its mean closeness to
                       that training set.  This tests the AnnaK joint-level /
                       idiosyncrasy hypothesis, not nearest-neighbor proximity.
                 multivariate COLUMN1,COLUMN2,...:euclid|mahal = the same
                       outcome-blind neural weights predict every held measure.
                       looR is the equal-weight mean of the measure-wise
                       predicted-vs-true correlations.  Null permutations move
                       complete subject profiles, preserving their covariance.
               Because a subject's own behavior never enters their own
               prediction, a positive result means the neural geometry
               genuinely carries behavior, not that a model was fit to it.
                 ++ Uses data-table '-model' targets; model_mat and model_dset
                    are skipped because they contain no held subject outcome.
                    Exact duplicate targets and estimands keep their own labels
                    but share one computation/max-FWE family.  AnnaK and NN
                    models of the same column are distinct estimands/families.
                 ++ Adds '..._looR/_looP/_looQ' to the table and '_looR/_looZ'
                    sub-bricks to the dataset, so it maps under -searchlight.
                 ++ Under -nperm the prediction also gets its OWN max-statistic
                    FWE ('_looPfwe' column, '_looZFWE' sub-brick).  It is a
                    separate family from the Mantel/regression statistic --
                    cross-validated accuracy is a different quantity, on a
                    different scale -- so it earns its own max-null rather than
                    borrowing the effect's.  See below.
                 ++ This is not the leave-one-subject-out lower noise ceiling
                    for classic/runwise RSA.  Classic RSA has no subject-level
                    target to predict; use '-noise_ceiling' and read
                    'nc_low' for that runwise LOO reliability bound.

-no_dset     = Write only the text table.

-save_rdm QQQ= Also write the matrices themselves, as 'QQQ_model_<name>.1D'
               and 'QQQ_roi<value>.1D'.  Worth doing once on any new
               analysis, to see that your models look the way you think.
               These files can be fed straight back in via '-model_mat'.
               Fixed models get one model file; a '-model_dset' varies by
               ROI, so it has no single model file (neural ROI files are
               still written).

-quiet       = Suppress the progress and diagnostic messages.
-progress M  = Progress display: auto, bar, line, or off [auto].
               'auto' uses a one-line updating bar on a terminal and 10%
               milestone lines when stderr is redirected.  Progress counts
               completed ROIs/searchlights and reports throughput, elapsed
               time, and an approximate ETA. '-quiet' overrides this option.

Notes:

* On the SIGN of a result.  The 'corr', 'scorr' and 'cosine' neural metrics
   and the 'annak', 'nn' and 'euclid' model rules all produce SIMILARITIES,
   so a positive result means 'more similar behavior goes with more similar
   brain response'.  The 'euclid' neural metric and the 'absdiff' rule
   produce DISSIMILARITIES; mixing one of those with a similarity flips the
   sign.  3dRSA prints the sense of each model and will not stop you.

* q-values are Benjamini-Hochberg FDR across the ROIs, computed separately
   for each model.  FDR controls the expected FRACTION of false positives
   among the ROIs you call significant -- a good default for an atlas, where
   you want a trustworthy list of regions and can tolerate a known small
   share of them being wrong.

* Family-wise error correction (the ‘_pfwe’ column, ‘_ZFWE’ sub-brick).

   For a searchlight -- thousands of overlapping, spatially correlated spheres
   -- FDR is often not what you want; there you usually want to control the
   probability of ANY false positive anywhere in the map.  That is family-wise
   error (FWE), and 3dRSA gets it by the max-statistic permutation method of
   Nichols & Holmes (2002), essentially for free from the machinery the p
   already needs:
     - One relabeling set is drawn up front and SHARED by every ROI/voxel
       (that is also why a given -seed reproduces a run regardless of thread
       count).  Call relabeling k applied everywhere the k-th null realization
       of the WHOLE map.
     - For each k, 3dRSA records the single largest |statistic| attained by any
       element under that relabeling.  Those maxima, over all k, are the null
       distribution of the map maximum.
     - An element's FWE p is where its observed statistic falls in that
       max-null: p_fwe = (# relabelings whose map-max >= |observed|) / nperm.
       Thresholding every element at p_fwe <= 0.05 holds the chance of even one
       false positive ACROSS THE WHOLE MAP at 0.05.
       For an IS-RSA fixed-RDM or fitted-model superiority contrast, replace
       'relabeling statistic' with
       the centered paired-bootstrap value |d*_k-d_obs|.  Its raw and max-FWE
       tails use (1 + exceedances)/(1 + N), because no identity draw exists.
   Because the max-null already carries the spatial correlation of the data
   (neighboring searchlights move together under a relabeling), this is exact
   and adaptive -- no Gaussian-field assumption, no smoothness estimate, and
   never anticonservative the way a Bonferroni count of non-independent
   searchlights would be.  It is by construction at least as strict as the raw
   p, so '_pfwe' >= '_p' always.
     ++ Reported per MODEL, not pooled across models: the max is taken over
        space for one model at a time (as in FSL randomise / PALM for a single
        contrast).  If you additionally want to correct across models, treat
        the several '_pfwe' as their own small family.
     ++ The max-null resolution floors p_fwe at 1/nperm, so for a searchlight
        use enough permutations (5000+); the smallest reportable corrected p is
        1/nperm.
     ++ Two independent statistics, two independent max-nulls: the Mantel/
        regression effect ('_pfwe') and, with -loo, the cross-validated
        prediction ('_looPfwe').  Each is corrected within its own family.
     ++ The centered superiority bootstrap is a Monte-Carlo approximation,
        not an exact permutation test; its family-wise construction is still
        synchronized over space and thread-count reproducible.
     ++ Computed whenever -nperm > 0.  For a handful of atlas ROIs it is valid
        but blunt (a max over a few regions is a weak correction); FDR '_q' is
        usually the better read there.  FWE earns its keep on the searchlight.

* With few items the permutation test has little resolution: 8 subjects
   allow only 8! = 40320 distinct relabelings.  Below 6 items 3dRSA refuses
   to run.

* Numerical input and migration contract.  Every numeric option token is
   consumed in full and must be finite and in range; strings such as '20x',
   'nan', and 'inf' are errors. Used numeric data-table columns, positive atlas
   labels, and every data brick/voxel that belongs to a requested ROI, seed, or
   searchlight domain must be finite. Positive atlas labels must be integers.
   Values outside the union analysis domain are intentionally ignored because
   they cannot enter an RDM. This is stricter than early development versions,
   which could accept trailing option text or propagate a NaN into inference;
   repair those inputs rather than relying on the old accidental behavior.

* Parallelized with OpenMP over ROIs.  On 16 cores a 200-ROI atlas with 2
   models and 5000 permutations takes under a second, against about 8
   seconds on one core.  Since the parallelism is over ROIs, an atlas with
   only a few will not speed up much.  Set OMP_NUM_THREADS to control it.

Examples:

1. IS-RSA on story listening, asking whether subjects with similar mood
   variance respond similarly, under both model shapes:

     3dRSA -mask Schaefer_200+tlrc  -mode IS-RSA          \
           -dataTableFile mood.txt                         \
           -model PANAS_ak PANAS_Var:annak                 \
           -model PANAS_nn PANAS_Var:nn                    \
           -nperm 5000  -prefix rsa_theta

2. The same, but removing head motion as a nuisance and testing two
   correlated clinical scales against each other:

     3dRSA -mask Schaefer_200+tlrc  -mode IS-RSA          \
           -dataTableFile mood.txt  -model_joint           \
           -model PANAS PANAS_Var:nn  -model MADRS MADRS:nn \
           -ortvec MeanFD                                  \
           -nperm 5000  -prefix rsa_ctl

   where mood.txt reads

     Subj  PANAS_Var  MADRS  MeanFD  InputFile
     s01   3.4        22     0.11    s01.theta+tlrc
     s02   1.1        14     0.28    s02.theta+tlrc

3. Cross-modal: does mood explain the MEG geometry beyond what fMRI does?

     3dRSA -mask Schaefer_200+tlrc  -mode IS-RSA          \
           -dataTableFile both.txt  -model_joint           \
           -model PANAS PANAS_Var:nn  -model_dset fMRI fMRIFile \
           -nperm 5000  -prefix rsa_cross

   where both.txt has an fMRIFile column of datasets beside InputFile.

4. Classic (traditional within-subject) RSA. Suppose every subject saw the
   same three conditions -- houses, faces, and trees -- and each subject's
   first-level dataset contains one beta sub-brick per condition. The data
   table has ONE ROW PER SUBJECT, not one row per condition:

     Subj  InputFile
     s01   s01_condition_betas+tlrc
     s02   s02_condition_betas+tlrc
     s03   s03_condition_betas+tlrc

   In the compact form, every InputFile must contain the same conditions in
   exactly the same sub-brick order:

     brick 0 = houses
     brick 1 = faces
     brick 2 = trees

   In classic RSA the RDM rows are CONDITIONS. Therefore a condition-level
   behavior hypothesis is supplied as a condition-by-condition -model_mat;
   it is not a subject column in subs.txt. For example, suppose independent
   ratings predict happiness 2 for houses, 5 for faces, and 4 for trees. A
   similarity model (larger = closer predicted happiness), in the SAME order
   as the beta sub-bricks, could be the numeric file happiness.1D:

     # row/column order: houses faces trees
     1.000000  0.000000  0.333333
     0.000000  1.000000  0.666667
     0.333333  0.666667  1.000000

   (The diagonal is ignored.) 3dRSA builds one neural condition RDM per
   subject and ROI, correlates each with this fixed happiness model, then
   performs population inference across subjects:

     3dRSA -mask atlas+tlrc  -mode RSA                         \
           -dataTableFile subs.txt                              \
           -model_mat happiness happiness.1D                    \
           -neural_metric corr -metric spearman                 \
           -nperm 5000 -prefix rsa_happiness

   Alternatively, put one selected brick per condition in an arbitrarily
   ordered long table, subs_by_condition.txt:

     Subj  cond    InputFile
     s01   tree   s01_condition_betas+tlrc[tree]
     s01   house  s01_condition_betas+tlrc[house]
     s01   face   s01_condition_betas+tlrc[face]

   Then bind labels to the row/column order of happiness.1D explicitly:

     3dRSA -mask atlas+tlrc -mode RSA                         \
           -dataTableFile subs_by_condition.txt                \
           -condition_column cond                              \
           -condition_order house,face,tree                    \
           -model_mat happiness happiness.1D                   \
           -nperm 5000 -prefix rsa_happiness_long

   The two input forms are numerically equivalent. The long-table rows need
   not follow subject or condition order; -condition_order describes only
   the fixed model matrix.

   Three conditions make the axes easy to see but are too few for a useful
   real RSA; use many independently defined conditions/stimuli in practice.

5. Second-order task-fMRI IS-RSA: compare subjects by their condition RDMs,
   avoiding voxelwise correspondence across subjects:

     3dRSA -mask brain+tlrc -mode IS-RSA -featuretype rdm       \
           -dataTableFile task.txt -condition_metric corr        \
           -model symptoms symptoms:nn -searchlight 'SPHERE(6)'  \
           -nperm 10000 -prefix rsa_second_order

   For crossnobis inner RDMs, replace -dataTableFile with -runwiseTable,
   and supply a subject-by-subject -model_mat.

6. Time-resolved M/EEG-fMRI fusion with one correction over time x space:

     3dRSA -mask brain+tlrc -mode RSA -dataTableFile fmri_conditions.txt \
           -model_series eeg_rdm_series.txt -searchlight 'SPHERE(6)'      \
           -metric spearman -nperm 10000 -prefix eeg_fmri_fusion

7. Searchlight with family-wise correction.  Threshold the '_ZFWE' sub-brick
   in the GUI (or the '_pfwe' column) at p <= 0.05 to control one false
   positive over the whole map:

     3dRSA -mask brain+tlrc  -mode IS-RSA  -searchlight 'SPHERE(6)' \
           -dataTableFile mood.txt  -model PANAS PANAS_Var:nn      \
           -loo  -nperm 10000  -prefix rsa_sl

8. Does a visual model fit the patterns better than a semantic one?  A paired
   contrast (classic within-subject RSA):

     3dRSA -mask atlas+tlrc  -mode RSA  -dataTableFile subs.txt   \
           -model_mat visual   visual.1D                          \
           -model_mat semantic semantic.1D                        \
           -model_contrast visual-semantic                        \
           -nperm 5000  -prefix rsa_vs

9. EEG/fMRI fusion: how much of the subject geometry do the two modalities
   share, and how much does each carry alone?  (Both modalities enter as
   per-ROI models; the neural side is the behavioral target.)

     3dRSA -mask brain+tlrc  -mode IS-RSA  -dataTableFile fuse.txt \
           -model_dset EEG  EEGrdmFile                            \
           -model_dset fMRI fMRIrdmFile                           \
           -model_commonality EEG,fMRI  -model_contrast EEG-fMRI   \
           -nperm 5000  -prefix rsa_fuse

10. Does a continuous naturalistic response depend on subjects sharing the
   same timeline?  Shift every complete ROI-mean series by at least 10 TRs:

     3dRSA -mask atlas+tlrc  -mode IS-RSA  -featuretype mean       \
           -dataTableFile story.txt  -model engagement engagement:nn \
           -null timeshift  -min_shift 10  -nperm 5000             \
           -seed 314159  -prefix rsa_story_shift

* https://en.wikipedia.org/wiki/Representational_similarity_analysis
* https://en.wikipedia.org/wiki/Mantel_test
* Kriegeskorte, Mur & Bandettini (2008), Front Syst Neurosci 2:4.
* Finn et al. (2020), NeuroImage 215:116828  [IS-RSA and the AnnaK model]
* Freedman & Lane (1983), J Bus Econ Stat 1:292  [the permutation scheme]
* Nichols & Holmes (2002), Hum Brain Mapp 15:1  [max-statistic FWE]
* Nimon & Oswald (2013), Organ Res Methods 16:650  [commonality analysis]
* Kauppi et al. (2010), Front Neuroinform 4:5  [circular time shifts]
* Schuett et al. (2023), eLife 12:e82566  [expected Spearman rho-a]

-- P Molfese, Jul 2026

* This binary version of 3dRSA is compiled using OpenMP, a semi-
   automatic parallelizer software toolkit, which splits the work across
   multiple CPUs/cores on the same shared memory computer.
* OpenMP is NOT like MPI -- it does not work with CPUs connected only
   by a network (e.g., OpenMP doesn't work across cluster nodes).
* For some implementation and compilation details, please see
   https://afni.nimh.nih.gov/pub/dist/doc/misc/OpenMP.html
* The number of CPU threads used will default to the maximum number on
   your system. You can control this value by setting environment variable
   OMP_NUM_THREADS to some smaller value (including 1).
* Un-setting OMP_NUM_THREADS resets OpenMP back to its default state of
   using all CPUs available.
   ++ However, on some systems, it seems to be necessary to set variable
      OMP_NUM_THREADS explicitly, or you only get one CPU.
   ++ On other systems with many CPUS, you probably want to limit the CPU
      count, since using more than (say) 16 threads is probably useless.
* You must set OMP_NUM_THREADS in the shell BEFORE running the program,
   since OpenMP queries this variable BEFORE the program actually starts.
   ++ You can't usefully set this variable in your ~/.afnirc file or on the
      command line with the '-D' option.
* How many threads are useful? That varies with the program, and how well
   it was coded. You'll have to experiment on your own systems!
* The number of CPUs on this particular computer system is ...... 1.
* The maximum number of CPUs that will be used is now set to .... 1.

++ Compile date = Sep 19 2026 {AFNI_26.2.09:linux_ubuntu_24_64}