{
 "about": {
  "method": "growth-window-rate",
  "recordedOn": "2026-10-10",
  "script": "pipeline/assay-analyser/oracles/growth_window.py",
  "scriptSha256": "a9a1412b2f65fb46c3f8d3ffe3482dd5560ad64af02190646edc7835accf3468",
  "origin": "Self-constructed readings: exact doublings and a fixed noise vector",
  "tolerances": {
   "mu": "within 1e-9 relative",
   "doublingTime": "within 1e-9 relative; absent exactly when mu <= 0",
   "status, reason, rows, n": "exact",
   "residuals": "within 1e-9 absolute"
  }
 },
 "oracle": {
  "engine": "Python fractions (exact cases); scipy.stats.linregress (noisy cases)",
  "python": "3.11.15",
  "scipy": "1.13.1",
  "numpy": "2.0.2"
 },
 "cases": [
  {
   "name": "exact-doubling-hours",
   "about": "Exact doubling every 1.5 h above a 0.042 matched blank: mu = ln 2 / 1.5 per hour, doubling time 1.5 h",
   "timeUnit": "h",
   "window": [
    "0",
    "9"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.052",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1.5",
     "response": "0.062",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.082",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "4.5",
     "response": "0.122",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "6",
     "response": "0.202",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "7.5",
     "response": "0.362",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "9",
     "response": "0.682",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "estimated",
    "n": 7,
    "blank": 0.042,
    "mu": 0.46209812037329684,
    "log2SlopeExact": "2/3",
    "doublingTime": 1.5,
    "rows": [
     3,
     4,
     5,
     6,
     7,
     8,
     9
    ]
   }
  },
  {
   "name": "exact-doubling-minutes",
   "about": "The same readings with time in minutes: mu / 60 per minute, doubling time 90 min",
   "timeUnit": "min",
   "window": [
    "0",
    "540"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.052",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "90",
     "response": "0.062",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "180",
     "response": "0.082",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "270",
     "response": "0.122",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "360",
     "response": "0.202",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "450",
     "response": "0.362",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "540",
     "response": "0.682",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "estimated",
    "n": 7,
    "blank": 0.042,
    "mu": 0.007701635339554948,
    "log2SlopeExact": "1/90",
    "doublingTime": 90.0,
    "rows": [
     3,
     4,
     5,
     6,
     7,
     8,
     9
    ]
   }
  },
  {
   "name": "exact-sub-window",
   "about": "A window of four of the seven exact points gives the same slope",
   "timeUnit": "h",
   "window": [
    "3",
    "7.5"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.052",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1.5",
     "response": "0.062",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.082",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "4.5",
     "response": "0.122",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "6",
     "response": "0.202",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "7.5",
     "response": "0.362",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "9",
     "response": "0.682",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "estimated",
    "n": 4,
    "blank": 0.042,
    "mu": 0.46209812037329684,
    "log2SlopeExact": "2/3",
    "doublingTime": 1.5,
    "rows": [
     5,
     6,
     7,
     8
    ]
   }
  },
  {
   "name": "excluded-reading",
   "about": "An excluded reading inside the window is left out; the slope is unchanged on exact data",
   "timeUnit": "h",
   "window": [
    "0",
    "9"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.052",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1.5",
     "response": "0.062",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.082",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "4.5",
     "response": "0.122",
     "role": "sample",
     "excluded": true
    },
    {
     "time": "6",
     "response": "0.202",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "7.5",
     "response": "0.362",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "9",
     "response": "0.682",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "estimated",
    "n": 6,
    "blank": 0.042,
    "mu": 0.46209812037329684,
    "log2SlopeExact": "2/3",
    "doublingTime": 1.5,
    "rows": [
     3,
     4,
     5,
     7,
     8,
     9
    ]
   }
  },
  {
   "name": "noisy-exponential-window",
   "about": "Noisy lag, exponential and plateau phases; the window 3 to 9 h covers the exponential phase only",
   "timeUnit": "h",
   "window": [
    "3",
    "9"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.0641",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1",
     "response": "0.0607",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "2",
     "response": "0.0637",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.0679",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "4",
     "response": "0.0829",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "5",
     "response": "0.1001",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "6",
     "response": "0.1209",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "7",
     "response": "0.1557",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "8",
     "response": "0.2001",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "9",
     "response": "0.2695",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "10",
     "response": "0.3613",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "11",
     "response": "0.3634",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "12",
     "response": "0.3604",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "estimated",
    "n": 7,
    "blank": 0.042,
    "mu": 0.3533683895817323,
    "intercept": -4.653728286925836,
    "residuals": [
     -0.059889192096005406,
     0.04362951266552573,
     0.0412967238929034,
     -0.006056101694865923,
     0.005957681628063316,
     -0.01774636449473288,
     -0.007192259900886455
    ],
    "doublingTime": 1.961542687449761,
    "rows": [
     6,
     7,
     8,
     9,
     10,
     11,
     12
    ],
    "logBeforeBlankSlope": 0.2264186720988878,
    "differsFromLogBeforeBlank": true
   }
  },
  {
   "name": "noisy-window-into-plateau",
   "about": "A window running into the plateau gives a lower slope: the window is the user's choice and is reported with the value",
   "timeUnit": "h",
   "window": [
    "6",
    "12"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.0641",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1",
     "response": "0.0607",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "2",
     "response": "0.0637",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.0679",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "4",
     "response": "0.0829",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "5",
     "response": "0.1001",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "6",
     "response": "0.1209",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "7",
     "response": "0.1557",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "8",
     "response": "0.2001",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "9",
     "response": "0.2695",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "10",
     "response": "0.3613",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "11",
     "response": "0.3634",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "12",
     "response": "0.3604",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "estimated",
    "n": 7,
    "blank": 0.042,
    "mu": 0.24880468353408403,
    "intercept": -3.8763904853304467,
    "residuals": [
     -0.15601166700436586,
     -0.03943417763378809,
     0.0414254822910638,
     0.1565432929325583,
     0.24671947072820566,
     0.004470140776797971,
     -0.25371254209047067
    ],
    "doublingTime": 2.785908893330741,
    "rows": [
     9,
     10,
     11,
     12,
     13,
     14,
     15
    ],
    "logBeforeBlankSlope": 0.1986710662553018,
    "differsFromLogBeforeBlank": true
   }
  },
  {
   "name": "withheld-nonpositive",
   "about": "A corrected response of zero or below inside the window cannot be logged: withheld, the rows named",
   "timeUnit": "h",
   "window": [
    "0",
    "3"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.041",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1",
     "response": "0.042",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "2",
     "response": "0.060",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.080",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "withheld",
    "reason": "nonpositive",
    "rows": [
     3,
     4
    ]
   }
  },
  {
   "name": "withheld-two-points",
   "about": "Two readings in the window: too few for a slope with residuals",
   "timeUnit": "h",
   "window": [
    "0",
    "1.5"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.052",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1.5",
     "response": "0.062",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.082",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "4.5",
     "response": "0.122",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "6",
     "response": "0.202",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "7.5",
     "response": "0.362",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "9",
     "response": "0.682",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "withheld",
    "reason": "too-few-points",
    "rows": [
     3,
     4
    ]
   }
  },
  {
   "name": "declining",
   "about": "A declining window: mu is negative and no doubling time is reported",
   "timeUnit": "h",
   "window": [
    "0",
    "5"
   ],
   "readings": [
    {
     "time": 0,
     "response": "0.040",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.044",
     "role": "blank",
     "excluded": false
    },
    {
     "time": 0,
     "response": "0.042",
     "role": "blank",
     "excluded": false
    },
    {
     "time": "0",
     "response": "0.4420",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "1",
     "response": "0.3620",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "2",
     "response": "0.2980",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "3",
     "response": "0.2468",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "4",
     "response": "0.2058",
     "role": "sample",
     "excluded": false
    },
    {
     "time": "5",
     "response": "0.1731",
     "role": "sample",
     "excluded": false
    }
   ],
   "expected": {
    "status": "estimated",
    "n": 6,
    "blank": 0.042,
    "mu": -0.22313396588943596,
    "intercept": -0.9163197904693317,
    "residuals": [
     2.9058595176656432e-05,
     1.947317040285057e-05,
     9.887745628933686e-06,
     3.023208552388468e-07,
     -0.0002534535360925183,
     0.0001947317040285057
    ],
    "doublingTime": null,
    "rows": [
     3,
     4,
     5,
     6,
     7,
     8
    ],
    "logBeforeBlankSlope": -0.187712441692266,
    "differsFromLogBeforeBlank": true
   }
  }
 ]
}
