iints-sdk-python35 1.5.8__tar.gz → 1.5.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iints_sdk_python35-1.5.8/src/iints_sdk_python35.egg-info → iints_sdk_python35-1.5.9}/PKG-INFO +2 -2
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/pyproject.toml +7 -2
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/__init__.py +43 -1
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/__init__.py +3 -0
- iints_sdk_python35-1.5.9/src/iints/analysis/evidence_bundle.py +328 -0
- iints_sdk_python35-1.5.9/src/iints/analysis/reporting.py +716 -0
- iints_sdk_python35-1.5.9/src/iints/analysis/run_quality.py +91 -0
- iints_sdk_python35-1.5.9/src/iints/analysis/safety_visualizer.py +363 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/cli/cli.py +1365 -73
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/__init__.py +36 -0
- iints_sdk_python35-1.5.9/src/iints/data/datasets.json +428 -0
- iints_sdk_python35-1.5.9/src/iints/data/evidence.py +62 -0
- iints_sdk_python35-1.5.9/src/iints/data/medtronic_live.py +484 -0
- iints_sdk_python35-1.5.9/src/iints/data/realism_governance.py +208 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/realism_validator.py +1 -0
- iints_sdk_python35-1.5.9/src/iints/data/research_catalog.py +248 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/highlevel.py +39 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/__init__.py +18 -0
- iints_sdk_python35-1.5.9/src/iints/live_patient/medtronic_direct.py +365 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/pico_pump.py +65 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/mdmp/__init__.py +12 -0
- iints_sdk_python35-1.5.9/src/iints/mdmp/eu_ai_pact.py +168 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/presets/evidence_sources.yaml +8 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/__init__.py +12 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/control_eval.py +21 -2
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/local_ai.py +12 -0
- iints_sdk_python35-1.5.9/src/iints/research/local_ai_gate.py +247 -0
- iints_sdk_python35-1.5.9/src/iints/validation/run_doctor.py +304 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9/src/iints_sdk_python35.egg-info}/PKG-INFO +2 -2
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints_sdk_python35.egg-info/SOURCES.txt +12 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints_sdk_python35.egg-info/requires.txt +1 -1
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/certification.py +3 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/drift.py +4 -3
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_demo_live.py +12 -2
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_onboarding.py +37 -2
- iints_sdk_python35-1.5.9/tests/test_cli_research_workflows.py +246 -0
- iints_sdk_python35-1.5.8/src/iints/analysis/reporting.py +0 -365
- iints_sdk_python35-1.5.8/src/iints/data/datasets.json +0 -189
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/LICENSE +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/LICENSE-MIT-IINTS-LEGACY +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/NOTICE +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/README.md +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/setup.cfg +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/assistant.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/backends/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/backends/base.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/backends/mistral_api.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/backends/ollama.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/cli.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/mdmp_guard.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/model_catalog.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/prepare.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/ai/prompts.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/algorithm_xray.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/baseline.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/booth_demo.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/carelink_workbench.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/clinical_benchmark.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/clinical_metrics.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/clinical_tir_analyzer.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/diabetes_metrics.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/edge_efficiency.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/edge_performance_monitor.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/eucys_results.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/explainability.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/explainable_ai.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/hardware_benchmark.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/metrics.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/population_report.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/poster.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/safety_index.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/sensor_filtering.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/study_analysis.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/study_engine.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/study_experiment.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/study_poster.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/study_protocol.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/analysis/validator.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/api/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/api/base_algorithm.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/api/registry.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/api/template_algorithm.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/assets/iints_logo.png +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/cli/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/cli/patient_cli.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/battle_runner.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/clinical_baseline.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/correction_bolus.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/discovery.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/fixed_basal_bolus.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/hybrid_algorithm.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/imitation_controller.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/lstm_algorithm.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/mock_algorithms.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/neural_controller.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/pid_controller.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/algorithms/standard_pump_algo.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/device.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/device_manager.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/devices/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/devices/models.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/patient/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/patient/bergman_model.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/patient/models.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/patient/patient_factory.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/patient/profile.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/physiology_variation.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/safety/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/safety/config.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/safety/input_validator.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/safety/supervisor.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/simulation/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/simulation/scenario_parser.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/simulator.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/core/supervisor.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/adapter.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/certify.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/column_mapper.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/contracts.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/demo/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/demo/demo_cgm.csv +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/guardians.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/importer.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/ingestor.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/mdmp_visualizer.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/nightscout.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/physiology_residual_profiles.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/quality_checker.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/realism_dashboard.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/realism_reference.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/realism_references.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/registry.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/runner.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/study_corruption.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/synthetic_mirror.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/tidepool.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/universal_parser.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/clinic_safe_baseline.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/clinic_safe_hyper_challenge.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/clinic_safe_hypo_prone.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/clinic_safe_midnight.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/clinic_safe_pizza.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/clinic_safe_stress_meal.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/default_patient.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/patient_559_config.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/reference_azt1d_t1d.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/reference_free_living_t1d.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/data/virtual_patients/reference_hupa_ucm_t1d.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/demo_assets.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/emulation/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/emulation/legacy_base.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/emulation/medtronic_780g.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/emulation/omnipod_5.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/emulation/tandem_controliq.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/jetson/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/jetson/endurance.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/jetson/research_pipeline.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/learning/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/learning/autonomous_optimizer.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/learning/learning_system.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/api.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/daemon.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/edge_benchmark.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/edge_ops.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/long_study.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/runtime.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/service_export.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/live_patient/uno_q.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/mdmp/backend.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/metrics.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/population/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/population/generator.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/population/runner.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/presets/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/presets/forecast_calibration_profiles.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/presets/golden_benchmark.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/presets/presets.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/presets/safety_contract_default.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/presets/validation_profiles.yaml +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/audit.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/calibration_gate.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/config.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/control.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/data_blend.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/dataset.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/evaluation.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/losses.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/metrics.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/model_registry.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/neural_control.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/research/predictor.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/scenarios/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/scenarios/generator.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/scenarios/study_pack.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/default_algorithm.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/demos/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/demos/live_stage_demo.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/pico_pump/README.md +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/pico_pump/code.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/pico_pump/serial_protocol.txt +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/scenarios/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/scenarios/chaos_insulin_stacking.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/scenarios/chaos_runaway_ai.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/scenarios/example_scenario.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/scenarios/exercise_stress.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/uno_q/README.md +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/templates/uno_q/iints_supervisor_bridge.ino +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/utils/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/utils/csv_safety.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/utils/plotting.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/utils/run_io.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/utils/url_safety.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/validation/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/validation/golden.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/validation/replay.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/validation/run_validation.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/validation/safety_contract.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/validation/schemas.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/visualization/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/visualization/cockpit.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints/visualization/uncertainty_cloud.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints_sdk_python35.egg-info/dependency_links.txt +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints_sdk_python35.egg-info/entry_points.txt +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/iints_sdk_python35.egg-info/top_level.txt +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_ai/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_ai/lineage.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/audit.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/bias_hooks.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/bundle.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/cli.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/compare.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/conformance.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/contracts.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/crypto.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/data/conformance/vectors/delegation.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/data/conformance/vectors/fingerprint.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/data/conformance/vectors/grading.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/data/conformance/vectors/signing.json +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/delegate.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/diffing.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/exceptions.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/fingerprint.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/fingerprint_store.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/hf.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/keys/mdmp_pub_v1.pem +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/llm_provenance.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/migrate.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/policy.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/prov.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/registry.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/runner.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/schema_export.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/synthetic.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/trust.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_core/visualizer.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_flavors/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_integrations/__init__.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_integrations/dvc.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_integrations/mlflow.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/src/mdmp_integrations/wandb.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_bergman.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_ci_governance.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_algorithm_loading.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_booth_demo.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_carelink_workbench.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_cloud_import_security.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_demo_export.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_edge_runtime.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_expo_tools.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_patient_runtime.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_poster.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_cli_run_summary.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_install_doctor.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_jetson_endurance.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_physiology_variation.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_plugin_system.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_population.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_presets_realism.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_research_realism_tools.py +0 -0
- {iints_sdk_python35-1.5.8 → iints_sdk_python35-1.5.9}/tests/test_simulator_calibration.py +0 -0
{iints_sdk_python35-1.5.8/src/iints_sdk_python35.egg-info → iints_sdk_python35-1.5.9}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iints-sdk-python35
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.9
|
|
4
4
|
Summary: A pre-clinical Edge-AI SDK for diabetes management validation.
|
|
5
5
|
Author-email: Rune Bobbaers <rune.bobbaers@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -18,7 +18,7 @@ Description-Content-Type: text/markdown
|
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
License-File: NOTICE
|
|
20
20
|
License-File: LICENSE-MIT-IINTS-LEGACY
|
|
21
|
-
Requires-Dist: fastapi<
|
|
21
|
+
Requires-Dist: fastapi<0.136.4,>=0.115.0
|
|
22
22
|
Requires-Dist: numpy<3.0.0,>=1.24.0
|
|
23
23
|
Requires-Dist: pandas<3.0.0,>=2.0.0
|
|
24
24
|
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "iints-sdk-python35"
|
|
7
|
-
version = "1.5.
|
|
7
|
+
version = "1.5.9"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Rune Bobbaers", email="rune.bobbaers@gmail.com" },
|
|
10
10
|
]
|
|
@@ -24,7 +24,7 @@ classifiers = [
|
|
|
24
24
|
"Development Status :: 5 - Production/Stable",
|
|
25
25
|
]
|
|
26
26
|
dependencies = [
|
|
27
|
-
"fastapi>=0.115.0,<
|
|
27
|
+
"fastapi>=0.115.0,<0.136.4",
|
|
28
28
|
"numpy>=1.24.0,<3.0.0",
|
|
29
29
|
"pandas>=2.0.0,<3.0.0",
|
|
30
30
|
"pydantic>=2.0.0,<3.0.0",
|
|
@@ -119,3 +119,8 @@ mdmp_core = [
|
|
|
119
119
|
"keys/*.pem",
|
|
120
120
|
"data/conformance/vectors/*.json",
|
|
121
121
|
]
|
|
122
|
+
|
|
123
|
+
[tool.coverage.run]
|
|
124
|
+
omit = [
|
|
125
|
+
"src/iints/templates/default_algorithm.py",
|
|
126
|
+
]
|
|
@@ -11,7 +11,7 @@ except ImportError: # pragma: no cover - Python < 3.8 fallback
|
|
|
11
11
|
try:
|
|
12
12
|
__version__ = version("iints-sdk-python35")
|
|
13
13
|
except PackageNotFoundError: # pragma: no cover - source tree fallback
|
|
14
|
-
__version__ = "1.5.
|
|
14
|
+
__version__ = "1.5.9"
|
|
15
15
|
|
|
16
16
|
# Note to developers: this SDK is currently maintained by a single author.
|
|
17
17
|
# Please report bugs via GitHub issues and feel free to contribute fixes via PRs.
|
|
@@ -211,6 +211,46 @@ def generate_demo_report(
|
|
|
211
211
|
title="IINTS-AF Demo Report",
|
|
212
212
|
)
|
|
213
213
|
|
|
214
|
+
def generate_agp_report(
|
|
215
|
+
simulation_results: 'pd.DataFrame',
|
|
216
|
+
output_path: Optional[str] = None,
|
|
217
|
+
safety_report: Optional[dict] = None,
|
|
218
|
+
subject_name: str = "Research simulation",
|
|
219
|
+
summary_json_path: Optional[str] = None,
|
|
220
|
+
) -> Optional[str]:
|
|
221
|
+
"""
|
|
222
|
+
Generate an AGP-style research PDF report from dense CGM/simulation data.
|
|
223
|
+
"""
|
|
224
|
+
if output_path is None:
|
|
225
|
+
return None
|
|
226
|
+
generator = ClinicalReportGenerator()
|
|
227
|
+
return generator.generate_agp_pdf(
|
|
228
|
+
simulation_results,
|
|
229
|
+
output_path,
|
|
230
|
+
subject_name=subject_name,
|
|
231
|
+
safety_report=safety_report or {},
|
|
232
|
+
summary_json_path=summary_json_path,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
def generate_agp_assets(
|
|
236
|
+
simulation_results: 'pd.DataFrame',
|
|
237
|
+
output_dir: Optional[str] = None,
|
|
238
|
+
subject_name: str = "Research simulation",
|
|
239
|
+
summary_json_path: Optional[str] = None,
|
|
240
|
+
) -> Optional[dict]:
|
|
241
|
+
"""
|
|
242
|
+
Export AGP-style PNG assets and summary JSON from dense CGM/simulation data.
|
|
243
|
+
"""
|
|
244
|
+
if output_dir is None:
|
|
245
|
+
return None
|
|
246
|
+
generator = ClinicalReportGenerator()
|
|
247
|
+
return generator.export_agp_assets(
|
|
248
|
+
simulation_results,
|
|
249
|
+
output_dir,
|
|
250
|
+
subject_name=subject_name,
|
|
251
|
+
summary_json_path=summary_json_path,
|
|
252
|
+
)
|
|
253
|
+
|
|
214
254
|
# You can also define __all__ to explicitly control what gets imported with `from iints import *`
|
|
215
255
|
__all__ = [
|
|
216
256
|
# API
|
|
@@ -287,6 +327,8 @@ __all__ = [
|
|
|
287
327
|
"generate_report",
|
|
288
328
|
"generate_quickstart_report",
|
|
289
329
|
"generate_demo_report",
|
|
330
|
+
"generate_agp_report",
|
|
331
|
+
"generate_agp_assets",
|
|
290
332
|
"generate_results_poster",
|
|
291
333
|
# High-level API
|
|
292
334
|
"run_simulation",
|
|
@@ -40,6 +40,7 @@ from .eucys_results import (
|
|
|
40
40
|
generate_eucys_main_figure,
|
|
41
41
|
generate_eucys_results_bundle,
|
|
42
42
|
)
|
|
43
|
+
from .evidence_bundle import EVIDENCE_SCOPE, build_evidence_bundle
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
def _missing_reports_dependency(feature: str, exc: Exception) -> None:
|
|
@@ -100,9 +101,11 @@ __all__ = [
|
|
|
100
101
|
"analyze_study_directory",
|
|
101
102
|
"build_booth_demo",
|
|
102
103
|
"build_carelink_workbench",
|
|
104
|
+
"build_evidence_bundle",
|
|
103
105
|
"ClinicalMetricsCalculator",
|
|
104
106
|
"ClinicalMetricsResult",
|
|
105
107
|
"ClinicalReportGenerator",
|
|
108
|
+
"EVIDENCE_SCOPE",
|
|
106
109
|
"compute_metrics",
|
|
107
110
|
"compare_studies",
|
|
108
111
|
"build_eucys_abstract_draft_markdown",
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, Iterable, List, Optional
|
|
7
|
+
import json
|
|
8
|
+
import shutil
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
from iints.utils.run_io import compute_sha256
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
EVIDENCE_SCOPE = (
|
|
16
|
+
"Research and education only. This bundle is not clinical evidence, "
|
|
17
|
+
"not a medical-device submission, and not dosing advice."
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True)
|
|
22
|
+
class EvidenceRun:
|
|
23
|
+
label: str
|
|
24
|
+
source_dir: Path
|
|
25
|
+
bundle_dir: Path
|
|
26
|
+
artifacts: Dict[str, str] = field(default_factory=dict)
|
|
27
|
+
metrics: Dict[str, Any] = field(default_factory=dict)
|
|
28
|
+
warnings: List[str] = field(default_factory=list)
|
|
29
|
+
|
|
30
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
31
|
+
return {
|
|
32
|
+
"label": self.label,
|
|
33
|
+
"source_dir": str(self.source_dir),
|
|
34
|
+
"bundle_dir": str(self.bundle_dir),
|
|
35
|
+
"artifacts": self.artifacts,
|
|
36
|
+
"metrics": self.metrics,
|
|
37
|
+
"warnings": self.warnings,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _safe_slug(value: str) -> str:
|
|
42
|
+
slug = "".join(ch.lower() if ch.isalnum() else "_" for ch in value.strip())
|
|
43
|
+
slug = "_".join(part for part in slug.split("_") if part)
|
|
44
|
+
return slug or "run"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _read_json(path: Path) -> Dict[str, Any]:
|
|
48
|
+
try:
|
|
49
|
+
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
50
|
+
except Exception:
|
|
51
|
+
return {}
|
|
52
|
+
return payload if isinstance(payload, dict) else {}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _copy_if_exists(source: Path, target_dir: Path, name: Optional[str] = None) -> Optional[Path]:
|
|
56
|
+
if not source.is_file():
|
|
57
|
+
return None
|
|
58
|
+
target_dir.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
target = target_dir / (name or source.name)
|
|
60
|
+
shutil.copy2(source, target)
|
|
61
|
+
return target
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _find_first(root: Path, names: Iterable[str]) -> Optional[Path]:
|
|
65
|
+
for name in names:
|
|
66
|
+
candidate = root / name
|
|
67
|
+
if candidate.is_file():
|
|
68
|
+
return candidate
|
|
69
|
+
for name in names:
|
|
70
|
+
matches = sorted(root.glob(f"**/{name}"))
|
|
71
|
+
if matches:
|
|
72
|
+
return matches[0]
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _glucose_metrics(results_csv: Optional[Path]) -> Dict[str, Any]:
|
|
77
|
+
if results_csv is None or not results_csv.is_file():
|
|
78
|
+
return {}
|
|
79
|
+
try:
|
|
80
|
+
df = pd.read_csv(results_csv)
|
|
81
|
+
except Exception:
|
|
82
|
+
return {}
|
|
83
|
+
glucose_column = None
|
|
84
|
+
for candidate in ("glucose_actual_mgdl", "glucose", "glucose_mgdl", "current_glucose"):
|
|
85
|
+
if candidate in df.columns:
|
|
86
|
+
glucose_column = candidate
|
|
87
|
+
break
|
|
88
|
+
if glucose_column is None or df.empty:
|
|
89
|
+
return {"rows": int(len(df))}
|
|
90
|
+
glucose = pd.to_numeric(df[glucose_column], errors="coerce").dropna()
|
|
91
|
+
if glucose.empty:
|
|
92
|
+
return {"rows": int(len(df))}
|
|
93
|
+
time_column = "time_minutes" if "time_minutes" in df.columns else "timestamp" if "timestamp" in df.columns else None
|
|
94
|
+
duration_minutes = None
|
|
95
|
+
if time_column is not None:
|
|
96
|
+
time_values = pd.to_numeric(df[time_column], errors="coerce").dropna()
|
|
97
|
+
if not time_values.empty:
|
|
98
|
+
duration_minutes = float(time_values.max() - time_values.min())
|
|
99
|
+
return {
|
|
100
|
+
"rows": int(len(df)),
|
|
101
|
+
"duration_minutes": duration_minutes,
|
|
102
|
+
"mean_glucose_mgdl": round(float(glucose.mean()), 3),
|
|
103
|
+
"min_glucose_mgdl": round(float(glucose.min()), 3),
|
|
104
|
+
"max_glucose_mgdl": round(float(glucose.max()), 3),
|
|
105
|
+
"tir_70_180_pct": round(float(((glucose >= 70) & (glucose <= 180)).mean() * 100.0), 3),
|
|
106
|
+
"tir_below_70_pct": round(float((glucose < 70).mean() * 100.0), 3),
|
|
107
|
+
"tir_below_54_pct": round(float((glucose < 54).mean() * 100.0), 3),
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _bundle_one_run(label: str, run_dir: Path, output_runs_dir: Path) -> EvidenceRun:
|
|
112
|
+
source = run_dir.expanduser().resolve()
|
|
113
|
+
warnings: list[str] = []
|
|
114
|
+
run_target = output_runs_dir / _safe_slug(label)
|
|
115
|
+
artifacts_dir = run_target / "artifacts"
|
|
116
|
+
run_target.mkdir(parents=True, exist_ok=True)
|
|
117
|
+
|
|
118
|
+
results_csv = _find_first(source, ("results.csv", "sim_results.csv"))
|
|
119
|
+
summary_json = _find_first(source, ("summary.json", "demo_summary.json", "run_summary.json"))
|
|
120
|
+
manifest_json = _find_first(source, ("run_manifest.json", "manifest.json"))
|
|
121
|
+
safety_json = _find_first(source, ("safety_report.json", "safety.json"))
|
|
122
|
+
report_pdf = _find_first(source, ("report.pdf", "clinical_report.pdf", "research_report.pdf"))
|
|
123
|
+
|
|
124
|
+
artifacts: dict[str, str] = {}
|
|
125
|
+
for key, path in {
|
|
126
|
+
"results_csv": results_csv,
|
|
127
|
+
"summary_json": summary_json,
|
|
128
|
+
"run_manifest_json": manifest_json,
|
|
129
|
+
"safety_report_json": safety_json,
|
|
130
|
+
"report_pdf": report_pdf,
|
|
131
|
+
}.items():
|
|
132
|
+
if path is None:
|
|
133
|
+
continue
|
|
134
|
+
copied = _copy_if_exists(path, artifacts_dir)
|
|
135
|
+
if copied is not None:
|
|
136
|
+
artifacts[key] = str(copied)
|
|
137
|
+
artifacts[f"{key}_sha256"] = compute_sha256(copied)
|
|
138
|
+
|
|
139
|
+
if results_csv is None:
|
|
140
|
+
warnings.append("No results.csv-style file found; metrics are limited.")
|
|
141
|
+
if manifest_json is None:
|
|
142
|
+
warnings.append("No run manifest found; reproducibility evidence is incomplete.")
|
|
143
|
+
if safety_json is None:
|
|
144
|
+
warnings.append("No safety report found; safety evidence is incomplete.")
|
|
145
|
+
|
|
146
|
+
metrics = _glucose_metrics(results_csv)
|
|
147
|
+
if safety_json is not None:
|
|
148
|
+
safety_payload = _read_json(safety_json)
|
|
149
|
+
for key in ("terminated_early", "critical_events", "supervisor_interventions"):
|
|
150
|
+
if key in safety_payload:
|
|
151
|
+
metrics[key] = safety_payload[key]
|
|
152
|
+
if summary_json is not None:
|
|
153
|
+
summary_payload = _read_json(summary_json)
|
|
154
|
+
for key in ("status", "completion_ratio", "completed_duration_minutes", "requested_duration_minutes"):
|
|
155
|
+
if key in summary_payload:
|
|
156
|
+
metrics[key] = summary_payload[key]
|
|
157
|
+
|
|
158
|
+
run_card = {
|
|
159
|
+
"label": label,
|
|
160
|
+
"source_dir": str(source),
|
|
161
|
+
"artifacts": artifacts,
|
|
162
|
+
"metrics": metrics,
|
|
163
|
+
"warnings": warnings,
|
|
164
|
+
"scope": EVIDENCE_SCOPE,
|
|
165
|
+
}
|
|
166
|
+
(run_target / "RUN_CARD.json").write_text(json.dumps(run_card, indent=2), encoding="utf-8")
|
|
167
|
+
return EvidenceRun(label=label, source_dir=source, bundle_dir=run_target, artifacts=artifacts, metrics=metrics, warnings=warnings)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _load_optional_json(root: Optional[Path], names: Iterable[str]) -> Dict[str, Any]:
|
|
171
|
+
if root is None:
|
|
172
|
+
return {}
|
|
173
|
+
path = _find_first(root.expanduser().resolve(), names)
|
|
174
|
+
return _read_json(path) if path is not None else {}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _write_markdown(path: Path, title: str, payload: Dict[str, Any]) -> None:
|
|
178
|
+
lines = [
|
|
179
|
+
f"# {title}",
|
|
180
|
+
"",
|
|
181
|
+
EVIDENCE_SCOPE,
|
|
182
|
+
"",
|
|
183
|
+
"## Summary",
|
|
184
|
+
"",
|
|
185
|
+
f"- Created UTC: `{payload['created_utc']}`",
|
|
186
|
+
f"- Runs: `{len(payload['runs'])}`",
|
|
187
|
+
f"- Local AI evidence: `{'yes' if payload.get('local_ai') else 'no'}`",
|
|
188
|
+
f"- Pump bench evidence: `{'yes' if payload.get('pump_bench') else 'no'}`",
|
|
189
|
+
"",
|
|
190
|
+
"## Runs",
|
|
191
|
+
"",
|
|
192
|
+
]
|
|
193
|
+
if not payload["runs"]:
|
|
194
|
+
lines.append("No simulation runs were attached.")
|
|
195
|
+
lines.append("")
|
|
196
|
+
for run in payload["runs"]:
|
|
197
|
+
metrics = run.get("metrics", {})
|
|
198
|
+
lines.extend(
|
|
199
|
+
[
|
|
200
|
+
f"### {run['label']}",
|
|
201
|
+
"",
|
|
202
|
+
f"- Source: `{run['source_dir']}`",
|
|
203
|
+
f"- Bundle: `{run['bundle_dir']}`",
|
|
204
|
+
f"- Rows: `{metrics.get('rows', 'n/a')}`",
|
|
205
|
+
f"- Mean glucose: `{metrics.get('mean_glucose_mgdl', 'n/a')}` mg/dL",
|
|
206
|
+
f"- TIR 70-180: `{metrics.get('tir_70_180_pct', 'n/a')}`%",
|
|
207
|
+
f"- Time <70: `{metrics.get('tir_below_70_pct', 'n/a')}`%",
|
|
208
|
+
f"- Time <54: `{metrics.get('tir_below_54_pct', 'n/a')}`%",
|
|
209
|
+
"",
|
|
210
|
+
]
|
|
211
|
+
)
|
|
212
|
+
for warning in run.get("warnings", []):
|
|
213
|
+
lines.append(f"- Warning: {warning}")
|
|
214
|
+
if run.get("warnings"):
|
|
215
|
+
lines.append("")
|
|
216
|
+
lines.extend(
|
|
217
|
+
[
|
|
218
|
+
"## Required Interpretation",
|
|
219
|
+
"",
|
|
220
|
+
"- Use this as reproducibility and engineering evidence.",
|
|
221
|
+
"- Do not present this as clinical performance evidence.",
|
|
222
|
+
"- Keep local AI and pump exports behind deterministic safety gates.",
|
|
223
|
+
"",
|
|
224
|
+
]
|
|
225
|
+
)
|
|
226
|
+
path.write_text("\n".join(lines), encoding="utf-8")
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def _write_model_card(path: Path, payload: Dict[str, Any]) -> None:
|
|
230
|
+
local_ai = payload.get("local_ai") or {}
|
|
231
|
+
gate = local_ai.get("training_safety_gate") or local_ai.get("closed_loop_evaluation", {}).get("safety_gate") or {}
|
|
232
|
+
lines = [
|
|
233
|
+
"# IINTS Research Model Card",
|
|
234
|
+
"",
|
|
235
|
+
EVIDENCE_SCOPE,
|
|
236
|
+
"",
|
|
237
|
+
"## Intended Use",
|
|
238
|
+
"",
|
|
239
|
+
"Local AI models generated by IINTS are for simulator research, reproducibility studies, and bench-only demonstrations.",
|
|
240
|
+
"",
|
|
241
|
+
"## Not Intended For",
|
|
242
|
+
"",
|
|
243
|
+
"- real insulin delivery",
|
|
244
|
+
"- diagnosis or treatment",
|
|
245
|
+
"- autonomous therapy without certified medical-device controls",
|
|
246
|
+
"",
|
|
247
|
+
"## Evidence Inputs",
|
|
248
|
+
"",
|
|
249
|
+
f"- Attached runs: `{len(payload['runs'])}`",
|
|
250
|
+
f"- Local AI summary present: `{'yes' if local_ai else 'no'}`",
|
|
251
|
+
"",
|
|
252
|
+
"## Safety Gate",
|
|
253
|
+
"",
|
|
254
|
+
f"- Status: `{gate.get('status', 'not_available')}`",
|
|
255
|
+
f"- Passed: `{gate.get('passed', 'not_available')}`",
|
|
256
|
+
f"- Score: `{gate.get('score', 'not_available')}`",
|
|
257
|
+
"",
|
|
258
|
+
]
|
|
259
|
+
if gate.get("critical_failures"):
|
|
260
|
+
lines.extend(["### Critical Failures", ""])
|
|
261
|
+
lines.extend(f"- {item}" for item in gate["critical_failures"])
|
|
262
|
+
lines.append("")
|
|
263
|
+
lines.extend(
|
|
264
|
+
[
|
|
265
|
+
"## Promotion Rule",
|
|
266
|
+
"",
|
|
267
|
+
"A model can only move toward hardware bench testing after realism checks, closed-loop evaluation, MDMP/evidence review, and deterministic supervisor gates pass.",
|
|
268
|
+
"",
|
|
269
|
+
]
|
|
270
|
+
)
|
|
271
|
+
path.write_text("\n".join(lines), encoding="utf-8")
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def build_evidence_bundle(
|
|
275
|
+
run_dirs: Iterable[tuple[str, Path]],
|
|
276
|
+
*,
|
|
277
|
+
output_dir: Path,
|
|
278
|
+
title: str = "IINTS Research Evidence Bundle",
|
|
279
|
+
local_ai_dir: Optional[Path] = None,
|
|
280
|
+
pump_bundle_dir: Optional[Path] = None,
|
|
281
|
+
) -> Dict[str, Any]:
|
|
282
|
+
"""Create a compact evidence pack for demos, reviews, and EUCYS-style explanation."""
|
|
283
|
+
|
|
284
|
+
root = output_dir.expanduser().resolve()
|
|
285
|
+
runs_dir = root / "runs"
|
|
286
|
+
root.mkdir(parents=True, exist_ok=True)
|
|
287
|
+
|
|
288
|
+
runs = [_bundle_one_run(label, Path(run_dir), runs_dir).to_dict() for label, run_dir in run_dirs]
|
|
289
|
+
local_ai = _load_optional_json(local_ai_dir, ("LOCAL_AI_RESEARCH_SUMMARY.json", "summary.json"))
|
|
290
|
+
pump_bench = _load_optional_json(pump_bundle_dir, ("manifest.json", "iints_pump_manifest.json"))
|
|
291
|
+
|
|
292
|
+
payload: Dict[str, Any] = {
|
|
293
|
+
"title": title,
|
|
294
|
+
"created_utc": datetime.now(timezone.utc).isoformat(),
|
|
295
|
+
"scope": EVIDENCE_SCOPE,
|
|
296
|
+
"runs": runs,
|
|
297
|
+
"local_ai": local_ai,
|
|
298
|
+
"pump_bench": pump_bench,
|
|
299
|
+
"artifacts": {
|
|
300
|
+
"summary_json": str(root / "evidence_summary.json"),
|
|
301
|
+
"readme_md": str(root / "README.md"),
|
|
302
|
+
"model_card_md": str(root / "MODEL_CARD.md"),
|
|
303
|
+
"run_index_csv": str(root / "run_index.csv"),
|
|
304
|
+
},
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
(root / "evidence_summary.json").write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
|
308
|
+
_write_markdown(root / "README.md", title, payload)
|
|
309
|
+
_write_model_card(root / "MODEL_CARD.md", payload)
|
|
310
|
+
|
|
311
|
+
rows = []
|
|
312
|
+
for run in runs:
|
|
313
|
+
metrics = run.get("metrics", {})
|
|
314
|
+
rows.append(
|
|
315
|
+
{
|
|
316
|
+
"label": run["label"],
|
|
317
|
+
"source_dir": run["source_dir"],
|
|
318
|
+
"bundle_dir": run["bundle_dir"],
|
|
319
|
+
"rows": metrics.get("rows"),
|
|
320
|
+
"mean_glucose_mgdl": metrics.get("mean_glucose_mgdl"),
|
|
321
|
+
"tir_70_180_pct": metrics.get("tir_70_180_pct"),
|
|
322
|
+
"tir_below_70_pct": metrics.get("tir_below_70_pct"),
|
|
323
|
+
"tir_below_54_pct": metrics.get("tir_below_54_pct"),
|
|
324
|
+
"warnings": "; ".join(run.get("warnings", [])),
|
|
325
|
+
}
|
|
326
|
+
)
|
|
327
|
+
pd.DataFrame(rows).to_csv(root / "run_index.csv", index=False)
|
|
328
|
+
return payload
|