spacr 0.3.35__py3-none-any.whl → 0.3.37__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.
- spacr/gui_elements.py +11 -1
- spacr/ml.py +2 -2
- spacr/plot.py +51 -15
- spacr/utils.py +34 -6
- {spacr-0.3.35.dist-info → spacr-0.3.37.dist-info}/METADATA +1 -1
- {spacr-0.3.35.dist-info → spacr-0.3.37.dist-info}/RECORD +10 -10
- {spacr-0.3.35.dist-info → spacr-0.3.37.dist-info}/LICENSE +0 -0
- {spacr-0.3.35.dist-info → spacr-0.3.37.dist-info}/WHEEL +0 -0
- {spacr-0.3.35.dist-info → spacr-0.3.37.dist-info}/entry_points.txt +0 -0
- {spacr-0.3.35.dist-info → spacr-0.3.37.dist-info}/top_level.txt +0 -0
spacr/gui_elements.py
CHANGED
@@ -2267,14 +2267,24 @@ class AnnotateApp:
|
|
2267
2267
|
self.grid_rows = max(1, self.grid_rows)
|
2268
2268
|
|
2269
2269
|
def prefilter_paths_annotations(self):
|
2270
|
-
from .io import _read_and_join_tables
|
2270
|
+
from .io import _read_and_join_tables, _read_db
|
2271
2271
|
from .utils import is_list_of_lists
|
2272
2272
|
|
2273
2273
|
if self.measurement and self.threshold is not None:
|
2274
2274
|
df = _read_and_join_tables(self.db_path)
|
2275
|
+
png_list_df = _read_db(self.db_path, tables=['png_list'])[0]
|
2276
|
+
png_list_df = png_list_df.set_index('prcfo')
|
2277
|
+
df = df.merge(png_list_df, left_index=True, right_index=True)
|
2275
2278
|
df[self.annotation_column] = None
|
2276
2279
|
before = len(df)
|
2277
2280
|
|
2281
|
+
if isinstance(self.threshold, int):
|
2282
|
+
if isinstance(self.measurement, list):
|
2283
|
+
mes = self.measurement[0]
|
2284
|
+
if isinstance(self.measurement, str):
|
2285
|
+
mes = self.measurement
|
2286
|
+
df = df[df[f'{mes}'] == self.threshold]
|
2287
|
+
|
2278
2288
|
if is_list_of_lists(self.measurement):
|
2279
2289
|
if isinstance(self.threshold, list) or is_list_of_lists(self.threshold):
|
2280
2290
|
if len(self.measurement) == len(self.threshold):
|
spacr/ml.py
CHANGED
@@ -763,7 +763,7 @@ def generate_ml_scores(settings):
|
|
763
763
|
raise ValueError("The 'png_list_df' DataFrame must contain 'prcfo' and 'test' columns.")
|
764
764
|
annotated_df = png_list_df[['prcfo', settings['annotation_column']]].set_index('prcfo')
|
765
765
|
df = annotated_df.merge(df, left_index=True, right_index=True)
|
766
|
-
display(df)
|
766
|
+
#display(df)
|
767
767
|
unique_values = df[settings['annotation_column']].dropna().unique()
|
768
768
|
if len(unique_values) == 1:
|
769
769
|
unannotated_rows = df[df[settings['annotation_column']].isna()].index
|
@@ -846,6 +846,7 @@ def generate_ml_scores(settings):
|
|
846
846
|
return [output, plate_heatmap]
|
847
847
|
|
848
848
|
def ml_analysis(df, channel_of_interest=3, location_column='col', positive_control='c2', negative_control='c1', exclude=None, n_repeats=10, top_features=30, n_estimators=100, test_size=0.2, model_type='xgboost', n_jobs=-1, remove_low_variance_features=True, remove_highly_correlated_features=True, verbose=False):
|
849
|
+
|
849
850
|
"""
|
850
851
|
Calculates permutation importance for numerical features in the dataframe,
|
851
852
|
comparing groups based on specified column values and uses the model to predict
|
@@ -878,7 +879,6 @@ def ml_analysis(df, channel_of_interest=3, location_column='col', positive_contr
|
|
878
879
|
if 'cells_per_well' in df.columns:
|
879
880
|
df = df.drop(columns=['cells_per_well'])
|
880
881
|
|
881
|
-
|
882
882
|
df_metadata = df[[location_column]].copy()
|
883
883
|
|
884
884
|
df, features = filter_dataframe_features(df, channel_of_interest, exclude, remove_low_variance_features, remove_highly_correlated_features, verbose)
|
spacr/plot.py
CHANGED
@@ -2591,35 +2591,71 @@ class spacrGraph:
|
|
2591
2591
|
return self.fig
|
2592
2592
|
|
2593
2593
|
def plot_data_from_db(settings):
|
2594
|
-
from .io import _read_db
|
2594
|
+
from .io import _read_db, _read_and_merge_data
|
2595
2595
|
from .utils import annotate_conditions
|
2596
2596
|
"""
|
2597
2597
|
Extracts the specified table from the SQLite database and plots a specified column.
|
2598
2598
|
|
2599
2599
|
Args:
|
2600
2600
|
db_path (str): The path to the SQLite database.
|
2601
|
-
|
2601
|
+
table_names (str): The name of the table to extract.
|
2602
2602
|
column_name (str): The column to plot from the table.
|
2603
2603
|
|
2604
2604
|
Returns:
|
2605
2605
|
df (pd.DataFrame): The extracted table as a DataFrame.
|
2606
2606
|
"""
|
2607
|
+
|
2608
|
+
if isinstance(settings['src'], str):
|
2609
|
+
srcs = [settings['src']]
|
2610
|
+
elif isinstance(settings['src'], list):
|
2611
|
+
srcs = settings['src']
|
2612
|
+
if isinstance(settings['database'], str):
|
2613
|
+
settings['database'] = [settings['database'] for _ in range(len(srcs))]
|
2614
|
+
else:
|
2615
|
+
raise ValueError("src must be a string or a list of strings.")
|
2607
2616
|
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2617
|
+
dfs = []
|
2618
|
+
for i, src in enumerate(srcs):
|
2619
|
+
|
2620
|
+
db_loc = os.path.join(src, 'measurements', settings['database'][i])
|
2611
2621
|
|
2612
|
-
|
2613
|
-
|
2614
|
-
|
2615
|
-
|
2616
|
-
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2622
|
+
if settings['table_names'] in ['saliency_image_correlations']:
|
2623
|
+
[df1] = _read_db(db_loc, tables=[settings['table_names']])
|
2624
|
+
else:
|
2625
|
+
df1, _ = _read_and_merge_data(locs=[db_loc],
|
2626
|
+
tables = ['cell', 'nucleus', 'pathogen','cytoplasm'],
|
2627
|
+
verbose=settings['verbose'],
|
2628
|
+
nuclei_limit=settings['nuclei_limit'],
|
2629
|
+
pathogen_limit=settings['pathogen_limit'],
|
2630
|
+
uninfected=settings['uninfected'])
|
2631
|
+
|
2632
|
+
dft = annotate_conditions(df1,
|
2633
|
+
cells=settings['cell_types'],
|
2634
|
+
cell_loc=settings['cell_plate_metadata'],
|
2635
|
+
pathogens=settings['pathogen_types'],
|
2636
|
+
pathogen_loc=settings['pathogen_plate_metadata'],
|
2637
|
+
treatments=settings['treatments'],
|
2638
|
+
treatment_loc=settings['treatment_plate_metadata'])
|
2639
|
+
dfs.append(dft)
|
2640
|
+
|
2641
|
+
df = pd.concat(dfs, axis=0)
|
2620
2642
|
df['prc'] = df['plate'].astype(str) + '_' + df['row'].astype(str) + '_' + df['col'].astype(str)
|
2643
|
+
df['recruitment'] = df['pathogen_channel_1_mean_intensity'] / df['cytoplasm_channel_1_mean_intensity']
|
2644
|
+
|
2645
|
+
if settings['cell_plate_metadata'] != None:
|
2646
|
+
df = df.dropna(subset='host_cell')
|
2647
|
+
|
2648
|
+
if settings['pathogen_plate_metadata'] != None:
|
2649
|
+
df = df.dropna(subset='pathogen')
|
2650
|
+
|
2651
|
+
if settings['treatment_plate_metadata'] != None:
|
2652
|
+
df = df.dropna(subset='treatment')
|
2653
|
+
|
2621
2654
|
df = df.dropna(subset=settings['column_name'])
|
2622
|
-
df
|
2655
|
+
df = df.dropna(subset=settings['grouping_column'])
|
2656
|
+
#display(df)
|
2657
|
+
|
2658
|
+
#df['class'] = df['png_path'].apply(lambda x: 'class_1' if 'class_1' in x else ('class_0' if 'class_0' in x else None))
|
2623
2659
|
|
2624
2660
|
spacr_graph = spacrGraph(
|
2625
2661
|
df=df, # Your DataFrame
|
@@ -2632,7 +2668,7 @@ def plot_data_from_db(settings):
|
|
2632
2668
|
save=settings['save'], # Whether to save the plot and results
|
2633
2669
|
y_lim=settings['y_lim'], # Starting point for y-axis (optional)
|
2634
2670
|
error_bar_type='std', # Type of error bar ('std' or 'sem')
|
2635
|
-
representation='
|
2671
|
+
representation=settings['representation'],
|
2636
2672
|
theme=settings['theme'], # Seaborn color palette theme (e.g., 'pastel', 'muted')
|
2637
2673
|
)
|
2638
2674
|
|
spacr/utils.py
CHANGED
@@ -5045,25 +5045,52 @@ def generate_cytoplasm_mask(nucleus_mask, cell_mask):
|
|
5045
5045
|
|
5046
5046
|
def add_column_to_database(settings):
|
5047
5047
|
"""
|
5048
|
-
|
5049
|
-
|
5048
|
+
Adds a new column to the database table by matching on a common column from the DataFrame.
|
5049
|
+
If the column already exists in the database, it adds the column with a suffix.
|
5050
|
+
|
5050
5051
|
Parameters:
|
5051
5052
|
- settings: A dictionary containing the following keys:
|
5052
5053
|
- 'csv_path': Path to the CSV file with the data to be added.
|
5053
5054
|
- 'db_path': Path to the SQLite database (or connection string for other databases).
|
5054
5055
|
- 'table_name': The name of the table in the database.
|
5055
|
-
- 'update_column': The column to
|
5056
|
+
- 'update_column': The name of the new column in the DataFrame to add to the database.
|
5056
5057
|
- 'match_column': The common column used to match rows.
|
5057
5058
|
"""
|
5058
5059
|
|
5059
5060
|
# Read the DataFrame from the provided CSV path
|
5060
5061
|
df = pd.read_csv(settings['csv_path'])
|
5061
5062
|
|
5063
|
+
# Check for any 0 values in the update column and replace them with 2
|
5064
|
+
if (df[settings['update_column']] == 0).any():
|
5065
|
+
print("Replacing all 0 values with 2 in the update column.")
|
5066
|
+
df[settings['update_column']].replace(0, 2, inplace=True)
|
5067
|
+
|
5062
5068
|
# Connect to the SQLite database
|
5063
5069
|
conn = sqlite3.connect(settings['db_path'])
|
5064
5070
|
cursor = conn.cursor()
|
5065
5071
|
|
5066
|
-
#
|
5072
|
+
# Get the existing columns in the database table
|
5073
|
+
cursor.execute(f"PRAGMA table_info({settings['table_name']})")
|
5074
|
+
columns_in_db = [col[1] for col in cursor.fetchall()]
|
5075
|
+
|
5076
|
+
# Check if the update column already exists in the database
|
5077
|
+
if settings['update_column'] in columns_in_db:
|
5078
|
+
# Add a suffix to the column name (e.g., '_new', '_1', or similar)
|
5079
|
+
suffix = 1
|
5080
|
+
new_column_name = f"{settings['update_column']}_{suffix}"
|
5081
|
+
# Ensure uniqueness by incrementing the suffix if needed
|
5082
|
+
while new_column_name in columns_in_db:
|
5083
|
+
suffix += 1
|
5084
|
+
new_column_name = f"{settings['update_column']}_{suffix}"
|
5085
|
+
print(f"Column '{settings['update_column']}' already exists. Using new column name: '{new_column_name}'")
|
5086
|
+
else:
|
5087
|
+
new_column_name = settings['update_column']
|
5088
|
+
|
5089
|
+
# Add the new column to the database table
|
5090
|
+
cursor.execute(f"ALTER TABLE {settings['table_name']} ADD COLUMN {new_column_name} TEXT")
|
5091
|
+
print(f"Added new column '{new_column_name}' to the table '{settings['table_name']}'.")
|
5092
|
+
|
5093
|
+
# Iterate over the DataFrame and update the new column in the database
|
5067
5094
|
for index, row in df.iterrows():
|
5068
5095
|
value_to_update = row[settings['update_column']]
|
5069
5096
|
match_value = row[settings['match_column']]
|
@@ -5071,7 +5098,7 @@ def add_column_to_database(settings):
|
|
5071
5098
|
# Prepare and execute the SQL update query
|
5072
5099
|
query = f"""
|
5073
5100
|
UPDATE {settings['table_name']}
|
5074
|
-
SET {
|
5101
|
+
SET {new_column_name} = ?
|
5075
5102
|
WHERE {settings['match_column']} = ?
|
5076
5103
|
"""
|
5077
5104
|
cursor.execute(query, (value_to_update, match_value))
|
@@ -5080,6 +5107,7 @@ def add_column_to_database(settings):
|
|
5080
5107
|
conn.commit()
|
5081
5108
|
conn.close()
|
5082
5109
|
|
5083
|
-
print(f"Updated '{
|
5110
|
+
print(f"Updated '{new_column_name}' in '{settings['table_name']}' using '{settings['match_column']}'.")
|
5111
|
+
|
5084
5112
|
|
5085
5113
|
|
@@ -12,22 +12,22 @@ spacr/core.py,sha256=G_x-w7FRIHNfSOoPaIZPSf_A7mVj7PA7o9HQZ4nIu5o,48231
|
|
12
12
|
spacr/deep_spacr.py,sha256=HdOcNU8cHcE_19nP7_5uTz-ih3E169ffr2Hm--NvMvA,43255
|
13
13
|
spacr/gui.py,sha256=ARyn9Q_g8HoP-cXh1nzMLVFCKqthY4v2u9yORyaQqQE,8230
|
14
14
|
spacr/gui_core.py,sha256=LV_HX5zreu3Bye6sQFDbOuk8Dfj4StMoohy6hsrDEXA,41363
|
15
|
-
spacr/gui_elements.py,sha256=
|
15
|
+
spacr/gui_elements.py,sha256=w-S1MZdyxt5O3DsNAHNNXy_WGfwBPg0NhwQtCsJeiao,137071
|
16
16
|
spacr/gui_utils.py,sha256=7e9DsZIuV7-jh97kEf7v1In_cFzlFueV4SGcGYGpTxw,45454
|
17
17
|
spacr/io.py,sha256=AARmqn1fMmTgVDwWy8bEYK6SjH-6DZIulgCSPdBTyf0,143370
|
18
18
|
spacr/logger.py,sha256=lJhTqt-_wfAunCPl93xE65Wr9Y1oIHJWaZMjunHUeIw,1538
|
19
19
|
spacr/measure.py,sha256=BThn_sALgKrwGKnLOGpT4FyoJeRVoTZoP9SXbCtCMRw,54857
|
20
20
|
spacr/mediar.py,sha256=FwLvbLQW5LQzPgvJZG8Lw7GniA2vbZx6Jv6vIKu7I5c,14743
|
21
|
-
spacr/ml.py,sha256=
|
21
|
+
spacr/ml.py,sha256=ItibDL_q0cKwEsJdwpBtVqfpRQGPXGbb0BX5UB5iH5s,49342
|
22
22
|
spacr/openai.py,sha256=5vBZ3Jl2llYcW3oaTEXgdyCB2aJujMUIO5K038z7w_A,1246
|
23
|
-
spacr/plot.py,sha256=
|
23
|
+
spacr/plot.py,sha256=QYj2bV0-6UqKRTWeSj3eOOgr6dNMmCCc4TdRGTniQ4c,118083
|
24
24
|
spacr/sequencing.py,sha256=t18mgpK6rhWuB1LtFOsPxqgpFXxuUmrD06ecsaVQ0Gw,19655
|
25
25
|
spacr/settings.py,sha256=AzP9NGiXI1MqT69bHObxwDSCUk0kdstBVvl1JpcD_-w,75960
|
26
26
|
spacr/sim.py,sha256=1xKhXimNU3ukzIw-3l9cF3Znc_brW8h20yv8fSTzvss,71173
|
27
27
|
spacr/submodules.py,sha256=AB7s6-cULsaqz-haAaCtXfGEIi8uPZGT4xoCslUJC3Y,18391
|
28
28
|
spacr/timelapse.py,sha256=FSYpUtAVy6xc3lwprRYgyDTT9ysUhfRQ4zrP9_h2mvg,39465
|
29
29
|
spacr/toxo.py,sha256=us3pQyULtMTyfTq0MWPn4QJTTmQ6BwAJKChNf75jo3I,10082
|
30
|
-
spacr/utils.py,sha256=
|
30
|
+
spacr/utils.py,sha256=3SBf5yeeU3u9MVsIWeYmcHjhwqs8LJ6m9UF0wBSNq8M,216304
|
31
31
|
spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
|
32
32
|
spacr/resources/MEDIAR/.gitignore,sha256=Ff1q9Nme14JUd-4Q3jZ65aeQ5X4uttptssVDgBVHYo8,152
|
33
33
|
spacr/resources/MEDIAR/LICENSE,sha256=yEj_TRDLUfDpHDNM0StALXIt6mLqSgaV2hcCwa6_TcY,1065
|
@@ -150,9 +150,9 @@ spacr/resources/icons/umap.png,sha256=dOLF3DeLYy9k0nkUybiZMe1wzHQwLJFRmgccppw-8b
|
|
150
150
|
spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif,sha256=Tl0ZUfZ_AYAbu0up_nO0tPRtF1BxXhWQ3T3pURBCCRo,7958528
|
151
151
|
spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif,sha256=m8N-V71rA1TT4dFlENNg8s0Q0YEXXs8slIn7yObmZJQ,7958528
|
152
152
|
spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif,sha256=Pbhk7xn-KUP6RSIhJsxQcrHFImBm3GEpLkzx7WOc-5M,7958528
|
153
|
-
spacr-0.3.
|
154
|
-
spacr-0.3.
|
155
|
-
spacr-0.3.
|
156
|
-
spacr-0.3.
|
157
|
-
spacr-0.3.
|
158
|
-
spacr-0.3.
|
153
|
+
spacr-0.3.37.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
|
154
|
+
spacr-0.3.37.dist-info/METADATA,sha256=Y65Rn3Py1AHsgydWiBFLsd0_vPVhxubiYizcIpfFIbE,5949
|
155
|
+
spacr-0.3.37.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
156
|
+
spacr-0.3.37.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
|
157
|
+
spacr-0.3.37.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
|
158
|
+
spacr-0.3.37.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|