PyEvoMotion 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl
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.
- PyEvoMotion/cli.py +88 -11
- PyEvoMotion/core/base.py +373 -34
- PyEvoMotion/core/core.py +136 -43
- PyEvoMotion/core/parser.py +4 -1
- {pyevomotion-0.1.0.dist-info → pyevomotion-0.1.2.dist-info}/METADATA +72 -4
- pyevomotion-0.1.2.dist-info/RECORD +35 -0
- share/analyze_model_selection_accuracy.py +316 -0
- share/analyze_test_runs.py +436 -0
- share/anomalous_diffusion.pdf +0 -0
- share/confusion_matrix_heatmap.pdf +0 -0
- share/figUK.tsv +9949 -0
- share/figUK_plots.pdf +0 -0
- share/figUK_regression_results.json +65 -0
- share/figUK_run_args.json +14 -0
- share/figUK_stats.tsv +41 -0
- share/figUSA.tsv +9470 -0
- share/figUSA_plots.pdf +0 -0
- share/figUSA_regression_results.json +65 -0
- share/figUSA_run_args.json +14 -0
- share/figUSA_stats.tsv +34 -0
- share/figdataUK.tsv +10001 -0
- share/figdataUSA.tsv +10001 -0
- share/generate_sequences_from_synthdata.py +85 -0
- share/generate_sequences_from_test5_data.py +107 -0
- share/manuscript_figure.py +858 -43
- share/run_parallel_analysis.py +196 -0
- share/synth_figure.pdf +0 -0
- share/uk_time_windows.pdf +0 -0
- share/weekly_size.pdf +0 -0
- pyevomotion-0.1.0.dist-info/RECORD +0 -13
- {pyevomotion-0.1.0.dist-info → pyevomotion-0.1.2.dist-info}/WHEEL +0 -0
- {pyevomotion-0.1.0.dist-info → pyevomotion-0.1.2.dist-info}/entry_points.txt +0 -0
PyEvoMotion/cli.py
CHANGED
|
@@ -248,6 +248,13 @@ def _parse_arguments() -> argparse.Namespace:
|
|
|
248
248
|
action="store_true",
|
|
249
249
|
help="Export the plots of the analysis."
|
|
250
250
|
)
|
|
251
|
+
parser.add_argument(
|
|
252
|
+
"-cl",
|
|
253
|
+
"--confidence_level",
|
|
254
|
+
type=float,
|
|
255
|
+
default=0.95,
|
|
256
|
+
help="Confidence level for parameter confidence intervals (default 0.95 for 95%% CI). Must be between 0 and 1."
|
|
257
|
+
)
|
|
251
258
|
parser.add_argument(
|
|
252
259
|
"-l",
|
|
253
260
|
"--length_filter",
|
|
@@ -255,13 +262,6 @@ def _parse_arguments() -> argparse.Namespace:
|
|
|
255
262
|
default=0,
|
|
256
263
|
help="Length filter for the sequences (removes sequences with length less than the specified value). Default is 0."
|
|
257
264
|
)
|
|
258
|
-
parser.add_argument(
|
|
259
|
-
"-n",
|
|
260
|
-
"--n_threshold",
|
|
261
|
-
type=int,
|
|
262
|
-
default=2,
|
|
263
|
-
help="Minimum number of sequences required in a time interval to compute statistics. Default is 2."
|
|
264
|
-
)
|
|
265
265
|
parser.add_argument(
|
|
266
266
|
"-xj",
|
|
267
267
|
"--export_json",
|
|
@@ -364,6 +364,73 @@ def _simple_serializer(k: str, v: any) -> any:
|
|
|
364
364
|
return "..".join(map(lambda x: x.strftime("%Y-%m-%d") if x else "", v))
|
|
365
365
|
return v
|
|
366
366
|
|
|
367
|
+
def _remove_model_functions(obj):
|
|
368
|
+
"""Recursively remove 'model' keys containing lambda functions from nested dictionaries.
|
|
369
|
+
|
|
370
|
+
:param obj: Dictionary or other object to clean
|
|
371
|
+
:type obj: any
|
|
372
|
+
:return: Cleaned object with model functions removed
|
|
373
|
+
:rtype: any
|
|
374
|
+
"""
|
|
375
|
+
if isinstance(obj, dict):
|
|
376
|
+
# Create a copy to avoid modifying during iteration
|
|
377
|
+
cleaned_obj = {}
|
|
378
|
+
for key, value in obj.items():
|
|
379
|
+
if key == "model":
|
|
380
|
+
# Skip lambda model functions - they can't be serialized to JSON
|
|
381
|
+
continue
|
|
382
|
+
elif isinstance(value, dict):
|
|
383
|
+
# Recursively clean nested dictionaries
|
|
384
|
+
cleaned_obj[key] = _remove_model_functions(value)
|
|
385
|
+
else:
|
|
386
|
+
# Keep all other values
|
|
387
|
+
cleaned_obj[key] = value
|
|
388
|
+
return cleaned_obj
|
|
389
|
+
else:
|
|
390
|
+
return obj
|
|
391
|
+
|
|
392
|
+
def _restructure_regression_results(reg_results):
|
|
393
|
+
"""Restructure regression results for cleaner JSON export format.
|
|
394
|
+
|
|
395
|
+
:param reg_results: Raw regression results from analysis
|
|
396
|
+
:type reg_results: dict
|
|
397
|
+
:return: Restructured results with cleaner format
|
|
398
|
+
:rtype: dict
|
|
399
|
+
"""
|
|
400
|
+
restructured = {}
|
|
401
|
+
|
|
402
|
+
for key, value in reg_results.items():
|
|
403
|
+
if key.endswith("_full_results"):
|
|
404
|
+
# Extract the base name (remove _full_results suffix)
|
|
405
|
+
base_name = key.replace("_full_results", "")
|
|
406
|
+
|
|
407
|
+
# Create the new structure with only essential fields
|
|
408
|
+
restructured[base_name] = {
|
|
409
|
+
"linear_model": {
|
|
410
|
+
"parameters": value["linear_model"]["parameters"],
|
|
411
|
+
"confidence_intervals": value["linear_model"]["confidence_intervals"],
|
|
412
|
+
"expression": value["linear_model"]["expression"],
|
|
413
|
+
"r2": value["linear_model"]["r2"],
|
|
414
|
+
"confidence_level": value["linear_model"]["confidence_level"]
|
|
415
|
+
},
|
|
416
|
+
"power_law_model": {
|
|
417
|
+
"parameters": value["power_law_model"]["parameters"],
|
|
418
|
+
"confidence_intervals": value["power_law_model"]["confidence_intervals"],
|
|
419
|
+
"expression": value["power_law_model"]["expression"],
|
|
420
|
+
"r2": value["power_law_model"]["r2"],
|
|
421
|
+
"confidence_level": value["power_law_model"]["confidence_level"]
|
|
422
|
+
},
|
|
423
|
+
"model_selection": value["model_selection"]
|
|
424
|
+
}
|
|
425
|
+
else:
|
|
426
|
+
# Keep non-full-results entries as-is (backward compatibility models)
|
|
427
|
+
# But skip them if there's a corresponding _full_results entry
|
|
428
|
+
full_results_key = f"{key}_full_results"
|
|
429
|
+
if full_results_key not in reg_results:
|
|
430
|
+
restructured[key] = value
|
|
431
|
+
|
|
432
|
+
return restructured
|
|
433
|
+
|
|
367
434
|
def _main():
|
|
368
435
|
check_and_install_mafft()
|
|
369
436
|
"""
|
|
@@ -374,6 +441,11 @@ def _main():
|
|
|
374
441
|
print(BANNER)
|
|
375
442
|
args = _parse_arguments()
|
|
376
443
|
|
|
444
|
+
# Validate confidence level
|
|
445
|
+
if not (0 < args.confidence_level < 1):
|
|
446
|
+
parser = _ArgumentParserWithHelpOnError(description=PACKAGE_DESCRIPTION)
|
|
447
|
+
parser.error("Confidence level must be between 0 and 1 (exclusive)")
|
|
448
|
+
|
|
377
449
|
# If the -xj argument is passed, the arguments are exported to a JSON file before running the analysis altogether
|
|
378
450
|
if args.export_json:
|
|
379
451
|
with open(f"{args.out}_run_args.json", "w") as file:
|
|
@@ -407,20 +479,24 @@ def _main():
|
|
|
407
479
|
# Runs the analysis
|
|
408
480
|
stats, reg = instance.analysis(
|
|
409
481
|
length=args.length_filter,
|
|
410
|
-
n_threshold=args.n_threshold,
|
|
411
482
|
show=args.show,
|
|
412
483
|
mutation_kind=args.kind,
|
|
413
484
|
export_plots_filename=(
|
|
414
485
|
f"{args.out}_plots"
|
|
415
486
|
if args.export_plots
|
|
416
487
|
else None
|
|
417
|
-
)
|
|
488
|
+
),
|
|
489
|
+
confidence_level=args.confidence_level
|
|
418
490
|
)
|
|
419
491
|
|
|
420
492
|
_reg = reg.copy()
|
|
421
493
|
|
|
422
|
-
|
|
423
|
-
|
|
494
|
+
# First restructure the results to the desired export format
|
|
495
|
+
_reg = _restructure_regression_results(_reg)
|
|
496
|
+
|
|
497
|
+
# Then apply the cleaning function to remove lambda functions
|
|
498
|
+
for k in list(_reg.keys()):
|
|
499
|
+
_reg[k] = _remove_model_functions(_reg[k])
|
|
424
500
|
|
|
425
501
|
# Exports the statistic results to TSV file
|
|
426
502
|
stats.to_csv(
|
|
@@ -432,6 +508,7 @@ def _main():
|
|
|
432
508
|
# Exports the regression models to a JSON file
|
|
433
509
|
with open(f"{args.out}_regression_results.json", "w") as file:
|
|
434
510
|
json.dump(_reg, file, indent=4)
|
|
511
|
+
print(f"Regression results saved to {args.out}_regression_results.json")
|
|
435
512
|
|
|
436
513
|
# Exits the program with code 0 (success)
|
|
437
514
|
exit(0)
|