cleverly.StudyProtocol#

class cleverly.StudyProtocol(target_population: str, eligibility: Sequence[str], time_zero: str, treatment_strategies: Sequence[str], treatment_versions: Sequence[str], outcome: str, horizon: str, intercurrent_event_handling: Sequence[str], interference_unit: str, assumption_rationale: Sequence[str])[source]#

Record the scientific protocol that gives a causal question its context.

Parameters:
target_populationstr

Population to which the causal question applies.

eligibilitysequence of str

Inclusion and exclusion criteria.

time_zerostr

Event that aligns eligibility, treatment assignment, and follow-up.

treatment_strategiessequence of str

Treatment strategies under comparison.

treatment_versionssequence of str

Version attached to each treatment strategy, in the same order.

outcomestr

Outcome definition and measurement.

horizonstr

Follow-up horizon for the outcome.

intercurrent_event_handlingsequence of str

Rules for events after time zero that affect outcome interpretation.

interference_unitstr

Unit within which interference may occur.

assumption_rationalesequence of str

Study-specific rationale for the identification assumptions.

schema_versionint

Version of this normalized record schema.

See also

cleverly.CausalStudy

Attach a protocol to observed study data.

cleverly.IdentifiedEffect

Persist the record with an identified question.

cleverly.Provenance

Store the protocol digest on a fitted result.

Notes

This hybrid record uses target-trial and ICH estimand vocabulary. It is not a complete target-trial protocol or a complete ICH estimand. The typed estimand stores the contrast, and the method stores the analysis configuration.

Examples

>>> from cleverly import StudyProtocol
>>> protocol = StudyProtocol(
...     target_population="Adults eligible for navigation",
...     eligibility=["Discharged alive"],
...     time_zero="Hospital discharge",
...     treatment_strategies=["Navigation", "Usual care"],
...     treatment_versions=["Two calls", "No call"],
...     outcome="Thirty-day transition score",
...     horizon="30 days",
...     intercurrent_event_handling=["Use outcome regardless of readmission"],
...     interference_unit="Patient",
...     assumption_rationale=["Adjustment covers measured common causes"],
... )
>>> len(protocol.fingerprint)
16

Methods#

classmethod StudyProtocol.from_dict(payload: dict[str, Any]) → StudyProtocol[source]#

Construct a protocol from its normalized form.

Parameters:
payloaddict

Mapping produced by to_dict().

Returns:
StudyProtocol

Validated immutable protocol record.

StudyProtocol.summary_lines() → tuple[str, ...][source]#

Return every protocol field as readable summary lines.

Returns:
tuple of str

Full protocol record and fingerprint, one fact per line.

StudyProtocol.to_dict() → dict[str, Any][source]#

Return the stable JSON-compatible normalized form.

Returns:
dict

A mapping with sequences represented as JSON arrays.

Attributes#

StudyProtocol.CURRENT_SCHEMA_VERSION: ClassVar[int] = 1#
StudyProtocol.canonical_json#

Return canonical UTF-8 JSON text used by fingerprint.

StudyProtocol.fingerprint#

Return the BLAKE2b digest of the canonical UTF-8 JSON record.

StudyProtocol.schema_version: int = 1#
StudyProtocol.target_population: str#
StudyProtocol.eligibility: Sequence[str]#
StudyProtocol.time_zero: str#
StudyProtocol.treatment_strategies: Sequence[str]#
StudyProtocol.treatment_versions: Sequence[str]#
StudyProtocol.outcome: str#
StudyProtocol.horizon: str#
StudyProtocol.intercurrent_event_handling: Sequence[str]#
StudyProtocol.interference_unit: str#
StudyProtocol.assumption_rationale: Sequence[str]#