pythonflex 0.2.1__tar.gz → 0.2.3__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.
- {pythonflex-0.2.1 → pythonflex-0.2.3}/PKG-INFO +1 -1
- {pythonflex-0.2.1 → pythonflex-0.2.3}/pyproject.toml +1 -1
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/utils.py +47 -26
- {pythonflex-0.2.1 → pythonflex-0.2.3}/.gitignore +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/.python-version +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/README.md +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/__init__.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/analysis.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/dataset/liver_cell_lines_500_genes.csv +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/dataset/melanoma_cell_lines_500_genes.csv +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/dataset/neuroblastoma_cell_lines_500_genes.csv +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/gold_standard/CORUM.parquet +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/gold_standard/GOBP.parquet +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/gold_standard/PATHWAY.parquet +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/gold_standard/corum.csv +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/gold_standard/gobp.csv +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/gold_standard/pathway.csv +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/examples/basic_usage.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/examples/dataset_filtering.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/examples/test.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/logging_config.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/plotting.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/preprocessing.py +0 -0
- {pythonflex-0.2.1 → pythonflex-0.2.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonflex
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: pythonFLEX is a benchmarking toolkit for evaluating CRISPR screen results against biological gold standards. The toolkit computes gene-level and complex-level performance metrics, helping researchers systematically assess the biological relevance and resolution of their CRISPR screening data.
|
|
5
5
|
Author-email: Yasir Demirtaş <tyasird@hotmail.com>
|
|
6
6
|
Requires-Python: >=3.9
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pythonflex"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
description = "pythonFLEX is a benchmarking toolkit for evaluating CRISPR screen results against biological gold standards. The toolkit computes gene-level and complex-level performance metrics, helping researchers systematically assess the biological relevance and resolution of their CRISPR screening data."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -9,19 +9,7 @@ import pandas as pd
|
|
|
9
9
|
TMP_ROOT = ".tmp"
|
|
10
10
|
VALID_EXTS = {".feather", ".parquet", ".npy", ".pkl"}
|
|
11
11
|
|
|
12
|
-
#
|
|
13
|
-
original_to_feather = pd.DataFrame.to_feather
|
|
14
|
-
def safe_to_feather(self, path, **kwargs):
|
|
15
|
-
try:
|
|
16
|
-
return original_to_feather(self, path, **kwargs)
|
|
17
|
-
except ValueError as e:
|
|
18
|
-
if "feather does not support serializing" in str(e):
|
|
19
|
-
# FIXED: Better path handling
|
|
20
|
-
parquet_path = os.path.splitext(path)[0] + '.parquet'
|
|
21
|
-
self.to_parquet(parquet_path, **kwargs)
|
|
22
|
-
else:
|
|
23
|
-
raise
|
|
24
|
-
pd.DataFrame.to_feather = safe_to_feather
|
|
12
|
+
# REMOVE THE MONKEY PATCH FROM HERE - it should be in your main script!
|
|
25
13
|
|
|
26
14
|
# Helper to sanitize names (make filesystem-safe)
|
|
27
15
|
def _sanitize(name):
|
|
@@ -40,7 +28,7 @@ def _safe_path(category, name=None, ext=".pkl"):
|
|
|
40
28
|
safe_name = _sanitize(name) if name else "data"
|
|
41
29
|
return os.path.join(dir_path, f"{safe_name}{ext}")
|
|
42
30
|
|
|
43
|
-
# Save function
|
|
31
|
+
# Save function - with built-in parquet fallback
|
|
44
32
|
def dsave(data, category, name=None, path=None): # 'path' ignored for compatibility with old code
|
|
45
33
|
# If data is dict and no name, recurse on each item
|
|
46
34
|
if name is None and isinstance(data, dict):
|
|
@@ -50,14 +38,41 @@ def dsave(data, category, name=None, path=None): # 'path' ignored for compatibi
|
|
|
50
38
|
|
|
51
39
|
# Choose best extension based on type
|
|
52
40
|
if isinstance(data, pd.DataFrame):
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
# Try Feather first, fallback to Parquet if it fails
|
|
42
|
+
target_feather = _safe_path(category, name, ".feather")
|
|
43
|
+
target_parquet = _safe_path(category, name, ".parquet")
|
|
44
|
+
|
|
45
|
+
# Try Feather first
|
|
46
|
+
try:
|
|
47
|
+
with tempfile.NamedTemporaryFile(dir=os.path.dirname(target_feather), delete=False, suffix='.feather') as tf:
|
|
48
|
+
tmp_path = tf.name
|
|
49
|
+
tf.close()
|
|
50
|
+
data.to_feather(tmp_path)
|
|
51
|
+
os.replace(tmp_path, target_feather)
|
|
52
|
+
return
|
|
53
|
+
except ValueError as e:
|
|
54
|
+
if "feather does not support serializing" in str(e):
|
|
55
|
+
print(f"Feather failed for {name}, using Parquet instead")
|
|
56
|
+
# Clean up failed feather temp file
|
|
57
|
+
if os.path.exists(tmp_path):
|
|
58
|
+
os.unlink(tmp_path)
|
|
59
|
+
|
|
60
|
+
# Save as Parquet
|
|
61
|
+
with tempfile.NamedTemporaryFile(dir=os.path.dirname(target_parquet), delete=False, suffix='.parquet') as tf:
|
|
62
|
+
tmp_path = tf.name
|
|
63
|
+
tf.close()
|
|
64
|
+
data.to_parquet(tmp_path)
|
|
65
|
+
os.replace(tmp_path, target_parquet)
|
|
66
|
+
return
|
|
67
|
+
else:
|
|
68
|
+
raise
|
|
69
|
+
|
|
55
70
|
elif isinstance(data, np.ndarray):
|
|
56
71
|
ext = ".npy"
|
|
57
72
|
save_func = lambda p: np.save(p, data, allow_pickle=False)
|
|
58
73
|
else:
|
|
59
74
|
ext = ".pkl"
|
|
60
|
-
save_func = lambda p: joblib.dump(data, p, compress=0)
|
|
75
|
+
save_func = lambda p: joblib.dump(data, p, compress=0)
|
|
61
76
|
|
|
62
77
|
target = _safe_path(category, name, ext)
|
|
63
78
|
|
|
@@ -68,7 +83,7 @@ def dsave(data, category, name=None, path=None): # 'path' ignored for compatibi
|
|
|
68
83
|
save_func(tmp_path)
|
|
69
84
|
os.replace(tmp_path, target) # Atomic move
|
|
70
85
|
|
|
71
|
-
# Load function -
|
|
86
|
+
# Load function - with parquet support and better error handling
|
|
72
87
|
def dload(category, name=None, path=None): # 'path' ignored for compatibility
|
|
73
88
|
dir_path = os.path.join(TMP_ROOT, _sanitize(category))
|
|
74
89
|
|
|
@@ -86,7 +101,7 @@ def dload(category, name=None, path=None): # 'path' ignored for compatibility
|
|
|
86
101
|
try:
|
|
87
102
|
if filename.endswith(".feather"):
|
|
88
103
|
out[k] = pd.read_feather(full_path)
|
|
89
|
-
elif filename.endswith(".parquet"):
|
|
104
|
+
elif filename.endswith(".parquet"):
|
|
90
105
|
out[k] = pd.read_parquet(full_path)
|
|
91
106
|
elif filename.endswith(".npy"):
|
|
92
107
|
out[k] = np.load(full_path, mmap_mode="r") # MMap for perf
|
|
@@ -97,21 +112,27 @@ def dload(category, name=None, path=None): # 'path' ignored for compatibility
|
|
|
97
112
|
os.remove(full_path) # Delete corrupted file
|
|
98
113
|
return out
|
|
99
114
|
|
|
100
|
-
# Load specific name (try extensions in order)
|
|
101
|
-
|
|
115
|
+
# Load specific name (try extensions in order - prefer parquet for reliability)
|
|
116
|
+
preferred_order = [".parquet", ".feather", ".npy", ".pkl"]
|
|
117
|
+
|
|
118
|
+
for ext in preferred_order:
|
|
119
|
+
if ext not in VALID_EXTS:
|
|
120
|
+
continue
|
|
102
121
|
target = _safe_path(category, name, ext)
|
|
103
122
|
if os.path.exists(target):
|
|
104
123
|
try:
|
|
105
124
|
if ext == ".feather":
|
|
106
125
|
return pd.read_feather(target)
|
|
107
|
-
elif ext == ".parquet":
|
|
126
|
+
elif ext == ".parquet":
|
|
108
127
|
return pd.read_parquet(target)
|
|
109
128
|
elif ext == ".npy":
|
|
110
129
|
return np.load(target, mmap_mode="r") # MMap for perf
|
|
111
130
|
elif ext == ".pkl":
|
|
112
131
|
return joblib.load(target, mmap_mode="r") # MMap for perf
|
|
113
|
-
except (EOFError, ValueError, OSError):
|
|
114
|
-
print(f"Warning: '{target}' is corrupted.
|
|
115
|
-
os.remove(target)
|
|
116
|
-
|
|
132
|
+
except (EOFError, ValueError, OSError) as e:
|
|
133
|
+
print(f"Warning: '{target}' is corrupted ({e}). Trying next format...")
|
|
134
|
+
os.remove(target) # Delete corrupted file
|
|
135
|
+
continue # Try next format instead of returning {}
|
|
136
|
+
|
|
137
|
+
print(f"Warning: No valid file found for {category}/{name}")
|
|
117
138
|
return {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/dataset/liver_cell_lines_500_genes.csv
RENAMED
|
File without changes
|
{pythonflex-0.2.1 → pythonflex-0.2.3}/src/pythonflex/data/dataset/melanoma_cell_lines_500_genes.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|