Class PairedDesignEdgeCasesTest

java.lang.Object
ubic.gemma.core.util.math.linearmodels.PairedDesignEdgeCasesTest

public class PairedDesignEdgeCasesTest extends Object
Edge cases of a blocking factor in the design. The golden agreement with limma is PairedDesignFitTest; these pin the shapes that limma would also handle but that break implementations that assume a balanced two-way grid.
  • Constructor Details

    • PairedDesignEdgeCasesTest

      public PairedDesignEdgeCasesTest()
  • Method Details

    • unbalancedPairsAreFittable

      @Test public void unbalancedPairsAreFittable()
      An incomplete pair (one arm missing) is still fittable by OLS -- the missing arm's subject level simply adjusts that subject's intercept. limma lmFit handles it; Gemma must too. This is an improvement over the old all-or-nothing block-completeness gate, which could not have run this design at all.

      Data: 5 samples; subjects s1, s2 both arms, s3 ctrl only. Model ~ subject + treatment, 4 coefficients (intercept, s2, s3, treat), residual dof = 1.

    • allSingletonSubjectsAreRankDeficient

      @Test public void allSingletonSubjectsAreRankDeficient()
      All-singleton subjects (every subject has exactly one arm) make the treatment effect unidentifiable: each single-arm subject indicator spans the rows of its arm, so subject columns are collinear with intercept + treatment. The fit must not throw -- rank-deficiency is handled downstream -- but the residual dof must make the degeneracy visible (n - rank <= 0 territory).
    • continuousFactorIsRejectedAsBlocking

      @Test public void continuousFactorIsRejectedAsBlocking()
      A CONTINUOUS factor cannot be a blocking factor: it has one column and no subject levels to block on. (A one-level categorical factor is caught upstream by the constant-factor logic; the config level only rejects what the config alone can see.)
    • blockingFactorsSurviveConfigCopy

      @Test public void blockingFactorsSurviveConfigCopy()
      Blocking factors must survive the config copy constructor, because subsetting copies the config per subset arm (fixConfigForSubset) -- a paired + subsetted analysis loses its pairing otherwise.
    • oneLevelCategoricalFactorIsAcceptedByConfig

      @Test public void oneLevelCategoricalFactorIsAcceptedByConfig()
      A blocking factor whose subject levels are USELESS (one level in the data) is just a constant column; the analyzer's constant-factor handling governs, and flagging it must not crash the config.
    • estimateBlockingCorrelationSurvivesConfigCopy

      @Test public void estimateBlockingCorrelationSurvivesConfigCopy()
      The copy constructor (used for the subset arm and for redo) carries the mixed-model flag too: a copy that dropped it would refit a mixed analysis as fixed-effect.
    • settingBlockingFactorsReplacesThePreviousSet

      @Test public void settingBlockingFactorsReplacesThePreviousSet()
      setBlockingFactors replaces; it does not accumulate, so a redo that recovers the old set cannot leave a stale factor from an earlier call behind.
    • interactionWithABlockingFactorIsRefusedOnEitherSide

      @Test public void interactionWithABlockingFactorIsRefusedOnEitherSide()
      An interaction is refused when either member is a blocking factor, whichever side it sits on.
    • interactionBetweenOtherFactorsStillAllowedWithABlockingFactorSet

      @Test public void interactionBetweenOtherFactorsStillAllowedWithABlockingFactorSet()
      An interaction between two non-blocking factors is unaffected by the blocking restriction.