calm-data-generator 2.0.1__tar.gz → 2.2.0__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.
- {calm_data_generator-2.0.1/calm_data_generator.egg-info → calm_data_generator-2.2.0}/PKG-INFO +42 -1
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/README.md +39 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/__init__.py +1 -1
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/cli.py +14 -5
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/PRESETS_REFERENCE.md +21 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/PRESETS_REFERENCE_ES.md +21 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/REAL_GENERATOR_REFERENCE.md +62 -6
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/REAL_GENERATOR_REFERENCE_ES.md +62 -1
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/REPORTS_REFERENCE.md +45 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/REPORTS_REFERENCE_ES.md +45 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/clinical/Clinic.py +21 -9
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/configs.py +2 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/drift/DriftInjector.py +14 -15
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/dynamics/ScenarioInjector.py +23 -3
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/persistence_models.py +23 -14
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/tabular/RealGenerator.py +399 -289
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/reports/LocalIndexGenerator.py +28 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/reports/QualityReporter.py +145 -8
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/reports/Visualizer.py +4 -2
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/advanced_drifts.py +2 -1
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/clinical_block_generator.py +0 -17
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0/calm_data_generator.egg-info}/PKG-INFO +42 -1
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator.egg-info/SOURCES.txt +1 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator.egg-info/requires.txt +2 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/pyproject.toml +17 -4
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/requirements.txt +4 -0
- calm_data_generator-2.2.0/tests/test_scgft_reporter.py +127 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/LICENSE +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/MANIFEST.in +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/API.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/API_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/CAUSAL_ENGINE_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/CAUSAL_ENGINE_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/CLINICAL_BLOCK_GENERATOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/CLINICAL_BLOCK_GENERATOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/CLINICAL_GENERATOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/CLINICAL_GENERATOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/COMPLEX_GENERATOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/COMPLEX_GENERATOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/DOCUMENTATION.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/DOCUMENTATION_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/DRIFT_INJECTOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/DRIFT_INJECTOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/REAL_BLOCK_GENERATOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/REAL_BLOCK_GENERATOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/SCENARIO_INJECTOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/SCENARIO_INJECTOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/STREAM_BLOCK_GENERATOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/STREAM_BLOCK_GENERATOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/STREAM_GENERATOR_REFERENCE.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/docs/STREAM_GENERATOR_REFERENCE_ES.md +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/base.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/clinical/ClinicGeneratorBlock.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/clinical/ClinicReporter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/clinical/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/complex/ComplexGenerator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/complex/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/drift/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/dynamics/CausalEngine.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/dynamics/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/stream/GeneratorFactory.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/stream/StreamBlockGenerator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/stream/StreamGenerator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/stream/StreamReporter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/stream/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/tabular/CustomPluginAdapter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/tabular/QualityReporter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/tabular/RealBlockGenerator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/tabular/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/utils/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/generators/utils/propagation.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/logger.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/BalancePreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/ConceptDriftPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/CopulaPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/DataQualityAuditPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/DiffusionPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/DriftScenarioPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/FastPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/FastPrototypePreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/GradualDriftPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/HighFidelityPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/ImbalancePreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/LongitudinalHealthPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/OmicsIntegrationPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/RareDiseasePreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/ScenarioInjectorPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/SeasonalTimeSeriesPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/SingleCellQualityPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/TimeSeriesPreset.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/presets/base.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/reports/DiscriminatorReporter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/reports/ExternalReporter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/reports/__init__.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/reports/base.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/clinic_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/clinical_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/correlation_drift.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/drift_injector.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/real_block_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/real_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/reports_deep_dive.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/scenario_injector.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/stream_block_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/stream_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator/tutorials/tutorial_advanced_methods.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator.egg-info/dependency_links.txt +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator.egg-info/entry_points.txt +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/calm_data_generator.egg-info/top_level.txt +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/setup.cfg +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_accessors.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_anndata_support.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_block_generators_extended.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_causal_engine.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_clinic_block_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_clinical_advanced.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_clinical_regression.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_complex_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_comprehensive.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_comprehensive_reporting.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_correlation_propagation.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_custom_plugin_adapter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_differentiation_factor.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_discriminator_reporter.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_disease_effects_fix.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_drift_correlations.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_drift_injector_advanced.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_drift_injector_math.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_functional_drift.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_imbalance.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_migration.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_presets.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_quality_metrics.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_real_block_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_real_generator_persistence.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_reporters_extended.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_reporting_fix.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_river_integration.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_scenario_extended.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_scvi_quality_regression.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_single_call.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_stream_block_generator.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_tabular_extended.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_timeseries_extended.py +0 -0
- {calm_data_generator-2.0.1 → calm_data_generator-2.2.0}/tests/test_timeseries_real.py +0 -0
{calm_data_generator-2.0.1/calm_data_generator.egg-info → calm_data_generator-2.2.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: calm-data-generator
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: CALM-Data-Generator: A Python library for synthetic data generation with support for drift injection and clinical data.
|
|
5
5
|
Author-email: Alejandro Belda Fernandez <alejandrobeldafernandez@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -40,6 +40,7 @@ Requires-Dist: imbalanced-learn<0.15.0,>=0.14.0
|
|
|
40
40
|
Requires-Dist: copulae<0.8.0,>=0.7.9
|
|
41
41
|
Requires-Dist: anndata<0.12.0,>=0.11.0
|
|
42
42
|
Requires-Dist: scvi-tools<1.4.0,>=1.3.0
|
|
43
|
+
Requires-Dist: scanpy<1.11.0,>=1.10.0
|
|
43
44
|
Requires-Dist: lightning<2.4.0,>=2.3.0
|
|
44
45
|
Requires-Dist: torchmetrics<1.9.0,>=1.8.0
|
|
45
46
|
Requires-Dist: plotly<6.6.0,>=6.5.0
|
|
@@ -52,6 +53,7 @@ Requires-Dist: hmmlearn<0.4.0,>=0.3.0
|
|
|
52
53
|
Requires-Dist: pyarrow<15.0.0,>=14.0.0
|
|
53
54
|
Requires-Dist: setuptools<70.0.0,>=59.0.0
|
|
54
55
|
Requires-Dist: fsspec<2026.0.0,>=2025.12.0
|
|
56
|
+
Requires-Dist: scgft-evaluator<0.2.0,>=0.1.0
|
|
55
57
|
Provides-Extra: stream
|
|
56
58
|
Requires-Dist: river>=0.21.0; extra == "stream"
|
|
57
59
|
Provides-Extra: full
|
|
@@ -587,6 +589,26 @@ synthetic = gen.generate(
|
|
|
587
589
|
|--------|----------|
|
|
588
590
|
| `scvi` | Generate new cells from learned distribution |
|
|
589
591
|
|
|
592
|
+
Once you have synthetic single-cell data, validate its quality using [scGFT Evaluator](https://github.com/nasim23ea/scgft-evaluator) via `QualityReporter`:
|
|
593
|
+
|
|
594
|
+
```python
|
|
595
|
+
from calm_data_generator.reports.QualityReporter import QualityReporter
|
|
596
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
597
|
+
|
|
598
|
+
reporter = QualityReporter(verbose=True)
|
|
599
|
+
reporter.generate_comprehensive_report(
|
|
600
|
+
real_df=real_df,
|
|
601
|
+
synthetic_df=synthetic_df,
|
|
602
|
+
generator_name="SingleCell_Example",
|
|
603
|
+
report_config=ReportConfig(
|
|
604
|
+
output_dir="./sc_report",
|
|
605
|
+
use_scgft=True,
|
|
606
|
+
target_column="cell_type",
|
|
607
|
+
),
|
|
608
|
+
)
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
> See [REPORTS_REFERENCE.md](calm_data_generator/docs/REPORTS_REFERENCE.md#single-cell-evaluation-scgft) for full details.
|
|
590
612
|
|
|
591
613
|
### Stream Data Generation
|
|
592
614
|
|
|
@@ -624,6 +646,24 @@ reporter.generate_report(
|
|
|
624
646
|
# Results JSON (including compared_data_files) saved to ./quality_report/report_results.json
|
|
625
647
|
```
|
|
626
648
|
|
|
649
|
+
For **single-cell data**, enable [scGFT](https://github.com/nasim23ea/scgft-evaluator) evaluation (Graph Fourier Transform-based manifold preservation metrics):
|
|
650
|
+
|
|
651
|
+
```python
|
|
652
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
653
|
+
|
|
654
|
+
reporter.generate_comprehensive_report(
|
|
655
|
+
real_df=real_df,
|
|
656
|
+
synthetic_df=synthetic_df,
|
|
657
|
+
generator_name="MyGen",
|
|
658
|
+
report_config=ReportConfig(
|
|
659
|
+
output_dir="./sc_report",
|
|
660
|
+
use_scgft=True,
|
|
661
|
+
target_column="cell_type",
|
|
662
|
+
),
|
|
663
|
+
)
|
|
664
|
+
# Generates scgft_report.html with ARI, MMD, Jaccard, Kendall Tau metrics
|
|
665
|
+
```
|
|
666
|
+
|
|
627
667
|
---
|
|
628
668
|
|
|
629
669
|
## Modules
|
|
@@ -759,3 +799,4 @@ We stand on the shoulders of giants. This library is possible thanks to these am
|
|
|
759
799
|
- **[Hugging Face Hub](https://github.com/huggingface/huggingface_hub)** (Apache-2.0) - Facilitating model sharing and versioning.
|
|
760
800
|
- **[Plotly](https://github.com/plotly/plotly.py)** (MIT) - Enabling interactive data visualizations.
|
|
761
801
|
- **[hmmlearn](https://github.com/hmmlearn/hmmlearn)** (BSD-3-Clause) - Powering the `hmm` method for drift-aware generation via Hidden Markov Models.
|
|
802
|
+
- **[scgft-evaluator](https://github.com/nasim23ea/scgft-evaluator)** - Providing Graph Fourier Transform-based evaluation for single-cell synthetic data quality assessment.
|
|
@@ -527,6 +527,26 @@ synthetic = gen.generate(
|
|
|
527
527
|
|--------|----------|
|
|
528
528
|
| `scvi` | Generate new cells from learned distribution |
|
|
529
529
|
|
|
530
|
+
Once you have synthetic single-cell data, validate its quality using [scGFT Evaluator](https://github.com/nasim23ea/scgft-evaluator) via `QualityReporter`:
|
|
531
|
+
|
|
532
|
+
```python
|
|
533
|
+
from calm_data_generator.reports.QualityReporter import QualityReporter
|
|
534
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
535
|
+
|
|
536
|
+
reporter = QualityReporter(verbose=True)
|
|
537
|
+
reporter.generate_comprehensive_report(
|
|
538
|
+
real_df=real_df,
|
|
539
|
+
synthetic_df=synthetic_df,
|
|
540
|
+
generator_name="SingleCell_Example",
|
|
541
|
+
report_config=ReportConfig(
|
|
542
|
+
output_dir="./sc_report",
|
|
543
|
+
use_scgft=True,
|
|
544
|
+
target_column="cell_type",
|
|
545
|
+
),
|
|
546
|
+
)
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
> See [REPORTS_REFERENCE.md](calm_data_generator/docs/REPORTS_REFERENCE.md#single-cell-evaluation-scgft) for full details.
|
|
530
550
|
|
|
531
551
|
### Stream Data Generation
|
|
532
552
|
|
|
@@ -564,6 +584,24 @@ reporter.generate_report(
|
|
|
564
584
|
# Results JSON (including compared_data_files) saved to ./quality_report/report_results.json
|
|
565
585
|
```
|
|
566
586
|
|
|
587
|
+
For **single-cell data**, enable [scGFT](https://github.com/nasim23ea/scgft-evaluator) evaluation (Graph Fourier Transform-based manifold preservation metrics):
|
|
588
|
+
|
|
589
|
+
```python
|
|
590
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
591
|
+
|
|
592
|
+
reporter.generate_comprehensive_report(
|
|
593
|
+
real_df=real_df,
|
|
594
|
+
synthetic_df=synthetic_df,
|
|
595
|
+
generator_name="MyGen",
|
|
596
|
+
report_config=ReportConfig(
|
|
597
|
+
output_dir="./sc_report",
|
|
598
|
+
use_scgft=True,
|
|
599
|
+
target_column="cell_type",
|
|
600
|
+
),
|
|
601
|
+
)
|
|
602
|
+
# Generates scgft_report.html with ARI, MMD, Jaccard, Kendall Tau metrics
|
|
603
|
+
```
|
|
604
|
+
|
|
567
605
|
---
|
|
568
606
|
|
|
569
607
|
## Modules
|
|
@@ -699,3 +737,4 @@ We stand on the shoulders of giants. This library is possible thanks to these am
|
|
|
699
737
|
- **[Hugging Face Hub](https://github.com/huggingface/huggingface_hub)** (Apache-2.0) - Facilitating model sharing and versioning.
|
|
700
738
|
- **[Plotly](https://github.com/plotly/plotly.py)** (MIT) - Enabling interactive data visualizations.
|
|
701
739
|
- **[hmmlearn](https://github.com/hmmlearn/hmmlearn)** (BSD-3-Clause) - Powering the `hmm` method for drift-aware generation via Hidden Markov Models.
|
|
740
|
+
- **[scgft-evaluator](https://github.com/nasim23ea/scgft-evaluator)** - Providing Graph Fourier Transform-based evaluation for single-cell synthetic data quality assessment.
|
|
@@ -103,6 +103,9 @@ def show_tutorial(number):
|
|
|
103
103
|
|
|
104
104
|
def run_tutorial(number):
|
|
105
105
|
"""Run a specific tutorial."""
|
|
106
|
+
import subprocess
|
|
107
|
+
import sys
|
|
108
|
+
|
|
106
109
|
tutorials_dir = get_tutorials_dir()
|
|
107
110
|
tutorials = sorted(tutorials_dir.glob("*.py"))
|
|
108
111
|
|
|
@@ -114,15 +117,21 @@ def run_tutorial(number):
|
|
|
114
117
|
idx = int(number) - 1
|
|
115
118
|
if 0 <= idx < len(tutorials):
|
|
116
119
|
tutorial = tutorials[idx]
|
|
117
|
-
print(f"\n
|
|
120
|
+
print(f"\n Running: {tutorial.name}")
|
|
118
121
|
print("=" * 60)
|
|
119
|
-
|
|
122
|
+
# Run in a subprocess to keep the tutorial isolated from this process
|
|
123
|
+
result = subprocess.run(
|
|
124
|
+
[sys.executable, str(tutorial)],
|
|
125
|
+
check=False,
|
|
126
|
+
)
|
|
127
|
+
if result.returncode != 0:
|
|
128
|
+
print(f"Tutorial exited with code {result.returncode}")
|
|
120
129
|
else:
|
|
121
|
-
print(f"
|
|
130
|
+
print(f"Invalid tutorial number. Choose 1-{len(tutorials)}")
|
|
122
131
|
except ValueError:
|
|
123
|
-
print("
|
|
132
|
+
print("Please provide a tutorial number (e.g., 1, 2, 3)")
|
|
124
133
|
except Exception as e:
|
|
125
|
-
print(f"
|
|
134
|
+
print(f"Error running tutorial: {e}")
|
|
126
135
|
|
|
127
136
|
|
|
128
137
|
def show_path():
|
|
@@ -521,6 +521,27 @@ preset = SingleCellQualityPreset(random_state=42)
|
|
|
521
521
|
synthetic_cells = preset.generate(data=adata_df, n_samples=500)
|
|
522
522
|
```
|
|
523
523
|
|
|
524
|
+
To validate the generated data quality, use `QualityReporter` with scGFT enabled:
|
|
525
|
+
|
|
526
|
+
```python
|
|
527
|
+
from calm_data_generator.reports.QualityReporter import QualityReporter
|
|
528
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
529
|
+
|
|
530
|
+
reporter = QualityReporter(verbose=True)
|
|
531
|
+
reporter.generate_comprehensive_report(
|
|
532
|
+
real_df=adata_df,
|
|
533
|
+
synthetic_df=synthetic_cells,
|
|
534
|
+
generator_name="SingleCellQualityPreset",
|
|
535
|
+
report_config=ReportConfig(
|
|
536
|
+
output_dir="./sc_report",
|
|
537
|
+
use_scgft=True,
|
|
538
|
+
target_column="cell_type",
|
|
539
|
+
),
|
|
540
|
+
)
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
> See [REPORTS_REFERENCE.md](REPORTS_REFERENCE.md#single-cell-evaluation-scgft) for full scGFT documentation.
|
|
544
|
+
|
|
524
545
|
---
|
|
525
546
|
|
|
526
547
|
## Import Summary
|
|
@@ -521,6 +521,27 @@ preset = SingleCellQualityPreset(random_state=42)
|
|
|
521
521
|
synthetic_cells = preset.generate(data=adata_df, n_samples=500)
|
|
522
522
|
```
|
|
523
523
|
|
|
524
|
+
Para validar la calidad de los datos generados, usa `QualityReporter` con scGFT activado:
|
|
525
|
+
|
|
526
|
+
```python
|
|
527
|
+
from calm_data_generator.reports.QualityReporter import QualityReporter
|
|
528
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
529
|
+
|
|
530
|
+
reporter = QualityReporter(verbose=True)
|
|
531
|
+
reporter.generate_comprehensive_report(
|
|
532
|
+
real_df=adata_df,
|
|
533
|
+
synthetic_df=synthetic_cells,
|
|
534
|
+
generator_name="SingleCellQualityPreset",
|
|
535
|
+
report_config=ReportConfig(
|
|
536
|
+
output_dir="./sc_report",
|
|
537
|
+
use_scgft=True,
|
|
538
|
+
target_column="cell_type",
|
|
539
|
+
),
|
|
540
|
+
)
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
> Ver [REPORTS_REFERENCE_ES.md](REPORTS_REFERENCE_ES.md#evaluación-single-cell-scgft) para documentación completa de scGFT.
|
|
544
|
+
|
|
524
545
|
---
|
|
525
546
|
|
|
526
547
|
## Resumen de Imports
|
|
@@ -560,14 +560,70 @@ synthetic = gen.generate(
|
|
|
560
560
|
)
|
|
561
561
|
```
|
|
562
562
|
|
|
563
|
-
| Parameter | Default | Description |
|
|
564
|
-
|-----------|---------|-------------|
|
|
565
|
-
| `target_col` | **required** | Column name with cell type labels |
|
|
566
|
-
| `epochs` | 200 | Training epochs for the base scVI model |
|
|
567
|
-
| `n_latent` | 30 | Latent space dimensionality |
|
|
568
|
-
| `n_layers` | 1 | Number of encoder/decoder layers |
|
|
569
563
|
| `custom_distributions` | `None` | Per-class proportions for generation |
|
|
570
564
|
|
|
565
|
+
#### Single-Cell Workflow Utilities
|
|
566
|
+
|
|
567
|
+
For users working with single-cell transcriptomics, `RealGenerator` provides a utility to convert the generated synthetic DataFrames back into `AnnData` objects, which are the standard format for analysis libraries like `scanpy` or `squidpy`.
|
|
568
|
+
|
|
569
|
+
**`to_anndata(df, target_col=None, obs_cols=None)`** (Static Method)
|
|
570
|
+
|
|
571
|
+
Converts a synthetic DataFrame (the output of `generate()`) into an `AnnData` object.
|
|
572
|
+
|
|
573
|
+
| Parameter | Type | Default | Description |
|
|
574
|
+
|-----------|------|---------|-------------|
|
|
575
|
+
| `df` | `pd.DataFrame` | **required** | The synthetic DataFrame generated by `calm_data_generator`. |
|
|
576
|
+
| `target_col` | `str` | `None` | The column to be used as `cell_type` in `adata.obs`. |
|
|
577
|
+
| `obs_cols` | `List[str]` | `None` | List of additional columns to move from the feature matrix (`X`) to the metadata (`obs`). |
|
|
578
|
+
|
|
579
|
+
**Example:**
|
|
580
|
+
```python
|
|
581
|
+
from calm_data_generator.generators.tabular import RealGenerator
|
|
582
|
+
|
|
583
|
+
# 1. Generate synthetic data (e.g., using scVI)
|
|
584
|
+
synthetic_df = gen.generate(
|
|
585
|
+
data=real_adata,
|
|
586
|
+
n_samples=2000,
|
|
587
|
+
method="scvi",
|
|
588
|
+
target_col="cell_type"
|
|
589
|
+
)
|
|
590
|
+
|
|
591
|
+
# 2. Convert back to AnnData for scanpy analysis
|
|
592
|
+
synthetic_adata = RealGenerator.to_anndata(
|
|
593
|
+
synthetic_df,
|
|
594
|
+
target_col="cell_type"
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
# 3. Standard scanpy analysis
|
|
598
|
+
import scanpy as sc
|
|
599
|
+
sc.pp.pca(synthetic_adata)
|
|
600
|
+
sc.pl.pca(synthetic_adata, color="cell_type")
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
**Validating single-cell quality with scGFT:**
|
|
604
|
+
|
|
605
|
+
After generating synthetic single-cell data, validate its fidelity using [scgft-evaluator](https://github.com/nasim23ea/scgft-evaluator):
|
|
606
|
+
|
|
607
|
+
```python
|
|
608
|
+
from calm_data_generator.reports.QualityReporter import QualityReporter
|
|
609
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
610
|
+
|
|
611
|
+
reporter = QualityReporter(verbose=True)
|
|
612
|
+
reporter.generate_comprehensive_report(
|
|
613
|
+
real_df=real_df,
|
|
614
|
+
synthetic_df=synthetic_df,
|
|
615
|
+
generator_name="scVI_SingleCell",
|
|
616
|
+
report_config=ReportConfig(
|
|
617
|
+
output_dir="./sc_report",
|
|
618
|
+
use_scgft=True,
|
|
619
|
+
target_column="cell_type",
|
|
620
|
+
),
|
|
621
|
+
)
|
|
622
|
+
# Generates scgft_report.html with ARI, MMD, Jaccard, Kendall Tau metrics
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
> See [REPORTS_REFERENCE.md](REPORTS_REFERENCE.md#single-cell-evaluation-scgft) for full details.
|
|
626
|
+
|
|
571
627
|
---
|
|
572
628
|
|
|
573
629
|
---
|
|
@@ -195,8 +195,69 @@ synthetic = gen.generate(
|
|
|
195
195
|
|
|
196
196
|
|
|
197
197
|
|
|
198
|
-
|
|
198
|
+
| `custom_distributions` | `None` | Proporciones por clase para la generación |
|
|
199
|
+
|
|
200
|
+
#### Utilidades de Flujo de Trabajo para Single-Cell
|
|
201
|
+
|
|
202
|
+
Para los usuarios que trabajan con transcriptómica de célula única (single-cell), `RealGenerator` proporciona una utilidad para convertir los DataFrames sintéticos generados de vuelta a objetos `AnnData`, que es el formato estándar para librerías de análisis como `scanpy` o `squidpy`.
|
|
203
|
+
|
|
204
|
+
**`to_anndata(df, target_col=None, obs_cols=None)`** (Método Estático)
|
|
205
|
+
|
|
206
|
+
Convierte un DataFrame sintético (la salida de `generate()`) en un objeto `AnnData`.
|
|
207
|
+
|
|
208
|
+
| Parámetro | Tipo | Defecto | Descripción |
|
|
209
|
+
|-----------|------|---------|-------------|
|
|
210
|
+
| `df` | `pd.DataFrame` | **requerido** | El DataFrame sintético generado por `calm_data_generator`. |
|
|
211
|
+
| `target_col` | `str` | `None` | La columna que se usará como `cell_type` en `adata.obs`. |
|
|
212
|
+
| `obs_cols` | `List[str]` | `None` | Lista de columnas adicionales que se moverán de la matriz de características (`X`) a los metadatos (`obs`). |
|
|
213
|
+
|
|
214
|
+
**Ejemplo:**
|
|
215
|
+
```python
|
|
216
|
+
from calm_data_generator.generators.tabular import RealGenerator
|
|
217
|
+
|
|
218
|
+
# 1. Generar datos sintéticos (ej. usando scANVI)
|
|
219
|
+
synthetic_df = gen.generate(
|
|
220
|
+
data=real_adata,
|
|
221
|
+
n_samples=2000,
|
|
222
|
+
method="scanvi",
|
|
223
|
+
target_col="cell_type"
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# 2. Convertir de vuelta a AnnData para análisis con scanpy
|
|
227
|
+
synthetic_adata = RealGenerator.to_anndata(
|
|
228
|
+
synthetic_df,
|
|
229
|
+
target_col="cell_type"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# 3. Análisis estándar con scanpy
|
|
233
|
+
import scanpy as sc
|
|
234
|
+
sc.pp.pca(synthetic_adata)
|
|
235
|
+
sc.pl.pca(synthetic_adata, color="cell_type")
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Validación de calidad single-cell con scGFT:**
|
|
239
|
+
|
|
240
|
+
Tras generar datos sintéticos de célula única, valida su fidelidad usando [scgft-evaluator](https://github.com/nasim23ea/scgft-evaluator):
|
|
241
|
+
|
|
242
|
+
```python
|
|
243
|
+
from calm_data_generator.reports.QualityReporter import QualityReporter
|
|
244
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
245
|
+
|
|
246
|
+
reporter = QualityReporter(verbose=True)
|
|
247
|
+
reporter.generate_comprehensive_report(
|
|
248
|
+
real_df=real_df,
|
|
249
|
+
synthetic_df=synthetic_df,
|
|
250
|
+
generator_name="scVI_SingleCell",
|
|
251
|
+
report_config=ReportConfig(
|
|
252
|
+
output_dir="./sc_report",
|
|
253
|
+
use_scgft=True,
|
|
254
|
+
target_column="cell_type",
|
|
255
|
+
),
|
|
256
|
+
)
|
|
257
|
+
# Genera scgft_report.html con métricas ARI, MMD, Jaccard, Kendall Tau
|
|
258
|
+
```
|
|
199
259
|
|
|
260
|
+
> Ver [REPORTS_REFERENCE_ES.md](REPORTS_REFERENCE_ES.md#evaluación-single-cell-scgft) para documentación completa.
|
|
200
261
|
|
|
201
262
|
---
|
|
202
263
|
|
|
@@ -27,6 +27,7 @@ The `calm_data_generator` library includes a suite of reporting tools designed t
|
|
|
27
27
|
| `constraints_stats` | Dict[str, int] | `None` | Constraint violation statistics |
|
|
28
28
|
| `sequence_config` | Dict | `None` | Configuration for sequence-based analysis |
|
|
29
29
|
| `per_block_external_reports` | bool | `False` | Generate separate reports per block |
|
|
30
|
+
| `use_scgft` | bool | `False` | Enable specialized scGFT single-cell evaluation |
|
|
30
31
|
|
|
31
32
|
### Usage Examples
|
|
32
33
|
|
|
@@ -173,6 +174,50 @@ reporter.generate_report(
|
|
|
173
174
|
```
|
|
174
175
|
|
|
175
176
|
|
|
177
|
+
## Single-Cell Evaluation (scGFT)
|
|
178
|
+
**Module:** `calm_data_generator.reports.QualityReporter`
|
|
179
|
+
|
|
180
|
+
The library integrates [`scgft-evaluator`](https://github.com/nasim23ea/scgft-evaluator) to provide specialized validation for single-cell RNA sequencing (scRNA-seq) data. This method uses Graph Fourier Transforms (GFT) to assess if the synthetic data preserves the underlying manifold and biological structure of the original cells.
|
|
181
|
+
|
|
182
|
+
### Installation
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pip install scgft-evaluator @ git+https://github.com/nasim23ea/scgft-evaluator.git
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Or via `requirements.txt` (already included in calm-data-generator):
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
scgft-evaluator @ git+https://github.com/nasim23ea/scgft-evaluator.git
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Key Features
|
|
195
|
+
- **Manifold Preservation**: Evaluates if the cell-to-cell relationships are maintained.
|
|
196
|
+
- **Cluster/Population Integrity**: Metrics on how well synthetic cells represent real populations (ARI, MMD, Jaccard, Kendall Tau).
|
|
197
|
+
- **Limma-based DE comparison**: Differential expression concordance between real and synthetic via `limma`.
|
|
198
|
+
- **Dashboard Integration**: Generates a dedicated `scgft_report.html` tab in the HTML dashboard with a results table.
|
|
199
|
+
|
|
200
|
+
### Usage
|
|
201
|
+
Set `use_scgft=True` in your `ReportConfig` and specify the cell-type column:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
205
|
+
|
|
206
|
+
reporter.generate_comprehensive_report(
|
|
207
|
+
...,
|
|
208
|
+
report_config=ReportConfig(
|
|
209
|
+
output_dir="./sc_report",
|
|
210
|
+
use_scgft=True,
|
|
211
|
+
target_column="cell_type" # column with cell type labels
|
|
212
|
+
)
|
|
213
|
+
)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The evaluator runs `ScGFT_Evaluator.run_all()` comparing the two most prevalent cell populations and prints a metrics table when `verbose=True`.
|
|
217
|
+
|
|
218
|
+
> [!IMPORTANT]
|
|
219
|
+
> **Data Format**: This method is specifically designed for single-cell data where columns represent genes and rows represent cells. It is **not recommended** for standard bulk or tabular data.
|
|
220
|
+
|
|
176
221
|
## Clinic Reporter (`Clinical`)
|
|
177
222
|
**Module:** `calm_data_generator.generators.clinical.ClinicReporter`
|
|
178
223
|
|
|
@@ -27,6 +27,7 @@ La biblioteca `calm_data_generator` incluye un conjunto de herramientas de repor
|
|
|
27
27
|
| `constraints_stats` | Dict[str, int] | `None` | Estadísticas de violación de restricciones |
|
|
28
28
|
| `sequence_config` | Dict | `None` | Configuración para análisis basado en secuencias |
|
|
29
29
|
| `per_block_external_reports` | bool | `False` | Generar reportes separados por bloque |
|
|
30
|
+
| `use_scgft` | bool | `False` | Habilitar evaluación especializada scGFT para single-cell |
|
|
30
31
|
|
|
31
32
|
### Ejemplos de Uso
|
|
32
33
|
|
|
@@ -173,6 +174,50 @@ reporter.generate_report(
|
|
|
173
174
|
```
|
|
174
175
|
|
|
175
176
|
|
|
177
|
+
## Evaluación Single-Cell (scGFT)
|
|
178
|
+
**Módulo:** `calm_data_generator.reports.QualityReporter`
|
|
179
|
+
|
|
180
|
+
La biblioteca integra [`scgft-evaluator`](https://github.com/nasim23ea/scgft-evaluator) para proporcionar validación especializada para datos de secuenciación de ARN de célula única (scRNA-seq). Este método utiliza Transformadas de Fourier en Grafos (GFT) para evaluar si los datos sintéticos preservan el manifold subyacente y la estructura biológica de las células originales.
|
|
181
|
+
|
|
182
|
+
### Instalación
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pip install scgft-evaluator @ git+https://github.com/nasim23ea/scgft-evaluator.git
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
O mediante `requirements.txt` (ya incluido en calm-data-generator):
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
scgft-evaluator @ git+https://github.com/nasim23ea/scgft-evaluator.git
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Características Clave
|
|
195
|
+
- **Preservación del Manifold**: Evalúa si se mantienen las relaciones célula a célula.
|
|
196
|
+
- **Integridad de Clusters/Poblaciones**: Métricas sobre qué tan bien las células sintéticas representan las poblaciones reales (ARI, MMD, Jaccard, Tau de Kendall).
|
|
197
|
+
- **Comparación DE basada en limma**: Concordancia de expresión diferencial entre real y sintético vía `limma`.
|
|
198
|
+
- **Integración en el Dashboard**: Genera una pestaña dedicada `scgft_report.html` en el panel HTML con tabla de resultados.
|
|
199
|
+
|
|
200
|
+
### Uso
|
|
201
|
+
Establezca `use_scgft=True` en su `ReportConfig` e indique la columna de tipo celular:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from calm_data_generator.generators.configs import ReportConfig
|
|
205
|
+
|
|
206
|
+
reporter.generate_comprehensive_report(
|
|
207
|
+
...,
|
|
208
|
+
report_config=ReportConfig(
|
|
209
|
+
output_dir="./sc_report",
|
|
210
|
+
use_scgft=True,
|
|
211
|
+
target_column="cell_type" # columna con las etiquetas de tipo celular
|
|
212
|
+
)
|
|
213
|
+
)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
El evaluador ejecuta `ScGFT_Evaluator.run_all()` comparando las dos poblaciones celulares más frecuentes e imprime una tabla de métricas cuando `verbose=True`.
|
|
217
|
+
|
|
218
|
+
> [!IMPORTANT]
|
|
219
|
+
> **Formato de Datos**: Este método está diseñado específicamente para datos de célula única donde las columnas representan genes y las filas representan células. **No se recomienda** para datos estándar de bulk o tabulares.
|
|
220
|
+
|
|
176
221
|
## Reporter Clínico (`Clinical`)
|
|
177
222
|
**Módulo:** `calm_data_generator.generators.clinical.ClinicReporter`
|
|
178
223
|
|
|
@@ -451,6 +451,18 @@ class ClinicalDataGenerator(ComplexGenerator):
|
|
|
451
451
|
|
|
452
452
|
return df_temp, raw_demographic_data
|
|
453
453
|
|
|
454
|
+
def _apply_constraints(self, df: pd.DataFrame, constraints: List[Dict]) -> pd.DataFrame:
|
|
455
|
+
mask = pd.Series(True, index=df.index)
|
|
456
|
+
for c in constraints:
|
|
457
|
+
col, op, val = c.get("col"), c.get("op"), c.get("val")
|
|
458
|
+
if col not in df.columns: continue
|
|
459
|
+
if op == ">=": mask &= df[col] >= val
|
|
460
|
+
elif op == "<=": mask &= df[col] <= val
|
|
461
|
+
elif op == "==": mask &= df[col] == val
|
|
462
|
+
elif op == ">": mask &= df[col] > val
|
|
463
|
+
elif op == "<": mask &= df[col] < val
|
|
464
|
+
return df[mask].copy()
|
|
465
|
+
|
|
454
466
|
def _prepare_demographic_context(
|
|
455
467
|
self,
|
|
456
468
|
demographic_df,
|
|
@@ -1293,15 +1305,15 @@ class ClinicalDataGenerator(ComplexGenerator):
|
|
|
1293
1305
|
if not patient_ids_to_modify:
|
|
1294
1306
|
return updated_demographic_df, updated_omics_data_df
|
|
1295
1307
|
|
|
1296
|
-
# Update demographic data
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1308
|
+
# Update demographic data (vectorized)
|
|
1309
|
+
modify_idx = pd.Index(patient_ids_to_modify)
|
|
1310
|
+
mask_control = updated_demographic_df.loc[modify_idx, "Group"] == "Control"
|
|
1311
|
+
mask_disease = ~mask_control
|
|
1312
|
+
updated_demographic_df.loc[modify_idx[mask_control], "Group"] = "Disease"
|
|
1313
|
+
updated_demographic_df.loc[modify_idx[mask_disease], "Group"] = "Control"
|
|
1314
|
+
if "Binary_Group" in updated_demographic_df.columns:
|
|
1315
|
+
updated_demographic_df.loc[modify_idx[mask_control], "Binary_Group"] = 1
|
|
1316
|
+
updated_demographic_df.loc[modify_idx[mask_disease], "Binary_Group"] = 0
|
|
1305
1317
|
|
|
1306
1318
|
# Regenerate omics data for all transitioned patients
|
|
1307
1319
|
if patient_ids_to_modify:
|
|
@@ -552,16 +552,17 @@ class DriftInjector:
|
|
|
552
552
|
if len(idxs) == 0:
|
|
553
553
|
return s
|
|
554
554
|
|
|
555
|
-
# for each row to change, choose a different category
|
|
556
|
-
current = s.loc[idxs]
|
|
557
|
-
|
|
558
|
-
for
|
|
559
|
-
|
|
555
|
+
# for each row to change, choose a different category (vectorized by value group)
|
|
556
|
+
current = s.loc[idxs]
|
|
557
|
+
result_vals = current.copy()
|
|
558
|
+
for uval in uniques:
|
|
559
|
+
sub_idx = current.index[current == uval]
|
|
560
|
+
if len(sub_idx) == 0:
|
|
561
|
+
continue
|
|
562
|
+
choices = [u for u in uniques if u != uval]
|
|
560
563
|
if choices:
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
new_vals.append(cur)
|
|
564
|
-
s.loc[idxs] = new_vals
|
|
564
|
+
result_vals.loc[sub_idx] = rng.choice(choices, size=len(sub_idx))
|
|
565
|
+
s.loc[idxs] = result_vals
|
|
565
566
|
return s
|
|
566
567
|
|
|
567
568
|
def _validate_feature_op(self, drift_type: str, drift_magnitude: float):
|
|
@@ -1755,7 +1756,7 @@ class DriftInjector:
|
|
|
1755
1756
|
try:
|
|
1756
1757
|
df_drift = method(**params)
|
|
1757
1758
|
except Exception as e:
|
|
1758
|
-
|
|
1759
|
+
warnings.warn(f"Failed to apply {method_name}: {e}")
|
|
1759
1760
|
else:
|
|
1760
1761
|
print(f"Method {method_name} not found")
|
|
1761
1762
|
|
|
@@ -2024,7 +2025,7 @@ class DriftInjector:
|
|
|
2024
2025
|
Returns:
|
|
2025
2026
|
pd.DataFrame: The drifted dataframe.
|
|
2026
2027
|
"""
|
|
2027
|
-
current_df = df
|
|
2028
|
+
current_df = df
|
|
2028
2029
|
|
|
2029
2030
|
for i, config in enumerate(schedule):
|
|
2030
2031
|
method_name = "inject_feature_drift"
|
|
@@ -2208,8 +2209,7 @@ class DriftInjector:
|
|
|
2208
2209
|
time_col=time_col,
|
|
2209
2210
|
)
|
|
2210
2211
|
except Exception as e:
|
|
2211
|
-
|
|
2212
|
-
_w.warn(f"inject_functional_drift: report failed: {e}")
|
|
2212
|
+
warnings.warn(f"inject_functional_drift: report failed: {e}")
|
|
2213
2213
|
|
|
2214
2214
|
return df_result
|
|
2215
2215
|
|
|
@@ -2320,8 +2320,7 @@ class DriftInjector:
|
|
|
2320
2320
|
time_col=time_col,
|
|
2321
2321
|
)
|
|
2322
2322
|
except Exception as e:
|
|
2323
|
-
|
|
2324
|
-
_w.warn(f"inject_causal_cascade: report failed: {e}")
|
|
2323
|
+
warnings.warn(f"inject_causal_cascade: report failed: {e}")
|
|
2325
2324
|
|
|
2326
2325
|
return df_result
|
|
2327
2326
|
|
|
@@ -283,10 +283,30 @@ class ScenarioInjector:
|
|
|
283
283
|
|
|
284
284
|
# 1. Calculate Raw Score
|
|
285
285
|
if isinstance(formula, str):
|
|
286
|
+
# Validate the formula before calling eval().
|
|
287
|
+
# Only allow identifiers that are actual column names plus arithmetic
|
|
288
|
+
# operators and numeric literals — this prevents arbitrary code execution.
|
|
289
|
+
import re as _re
|
|
290
|
+
_allowed_pattern = _re.compile(
|
|
291
|
+
r"^[\w\s\.\+\-\*\/\(\)\,\d\.\>\<\=\!]+$"
|
|
292
|
+
)
|
|
293
|
+
if not _allowed_pattern.match(formula):
|
|
294
|
+
raise ValueError(
|
|
295
|
+
f"Formula '{formula}' contains disallowed characters. "
|
|
296
|
+
"Only column names, numeric literals, and arithmetic operators "
|
|
297
|
+
"(+, -, *, /, parentheses, inequalities) are permitted."
|
|
298
|
+
)
|
|
299
|
+
# Additionally verify that every identifier in the formula is an
|
|
300
|
+
# existing column name or a numeric token, not an arbitrary name.
|
|
301
|
+
_tokens = _re.findall(r"[A-Za-z_]\w*", formula)
|
|
302
|
+
_unknown = [t for t in _tokens if t not in df_target.columns]
|
|
303
|
+
if _unknown:
|
|
304
|
+
raise ValueError(
|
|
305
|
+
f"Formula references unknown identifiers: {_unknown}. "
|
|
306
|
+
f"Available columns: {list(df_target.columns)}"
|
|
307
|
+
)
|
|
286
308
|
try:
|
|
287
|
-
|
|
288
|
-
# We perform eval in the context of the dataframe
|
|
289
|
-
raw_score = df_target.eval(formula)
|
|
309
|
+
raw_score = df_target.eval(formula, engine="python")
|
|
290
310
|
except Exception as e:
|
|
291
311
|
raise ValueError(f"Error evaluating formula '{formula}': {e}")
|
|
292
312
|
elif callable(formula):
|