spacr 0.3.81__py3-none-any.whl → 0.4.1__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/toxo.py CHANGED
@@ -24,117 +24,128 @@ from sklearn.metrics import mean_absolute_error
24
24
 
25
25
  from matplotlib.gridspec import GridSpec
26
26
 
27
+ def custom_volcano_plot(data_path, metadata_path, metadata_column='tagm_location',point_size=50, figsize=20, threshold=0,save_path=None, x_lim=[-0.5, 0.5], y_lims=[[0, 6], [9, 20]]):
27
28
 
28
- def custom_volcano_plot(data_path, metadata_path, metadata_column='tagm_location',
29
- point_size=50, figsize=20, threshold=0,
30
- save_path=None, x_lim=[-0.5, 0.5], y_lims=[[0, 6], [9, 15]]):
29
+ # Dictionary mapping compartment to color
31
30
 
32
- markers = [
33
- 'o', # Circle
34
- 'X', # X-shaped marker
35
- '^', # Upward triangle
36
- 's', # Square
37
- 'v', # Downward triangle
38
- 'P', # Plus-filled pentagon
39
- '*', # Star
40
- '+', # Plus
41
- 'x', # Cross
42
- '.', # Point
43
- ',', # Pixel
44
- 'd', # Diamond
45
- 'D', # Thin diamond
46
- 'h', # Hexagon 1
47
- 'H', # Hexagon 2
48
- 'p', # Pentagon
49
- '|', # Vertical line
50
- '_', # Horizontal line
51
- ]
31
+ colors = {'micronemes':'black',
32
+ 'rhoptries 1':'darkviolet',
33
+ 'rhoptries 2':'darkviolet',
34
+ 'nucleus - chromatin':'blue',
35
+ 'nucleus - non-chromatin':'blue',
36
+ 'dense granules':'teal',
37
+ 'ER 1':'pink',
38
+ 'ER 2':'pink',
39
+ 'unknown':'black',
40
+ 'tubulin cytoskeleton':'slategray',
41
+ 'IMC':'slategray',
42
+ 'PM - peripheral 1':'slategray',
43
+ 'PM - peripheral 2':'slategray',
44
+ 'cytosol':'turquoise',
45
+ 'mitochondrion - soluble':'red',
46
+ 'mitochondrion - membranes':'red',
47
+ 'apicoplast':'slategray',
48
+ 'Golgi':'green',
49
+ 'PM - integral':'slategray',
50
+ 'apical 1':'orange',
51
+ 'apical 2':'orange',
52
+ '19S proteasome':'slategray',
53
+ '20S proteasome':'slategray',
54
+ '60S ribosome':'slategray',
55
+ '40S ribosome':'slategray',
56
+ }
57
+
58
+ # Increase font size for better readability
59
+ fontsize = 18
60
+ plt.rcParams.update({'font.size': fontsize})
52
61
 
53
- plt.rcParams.update({'font.size': 14})
54
-
55
- # Load data
62
+ # --- Load data ---
56
63
  if isinstance(data_path, pd.DataFrame):
57
64
  data = data_path
58
65
  else:
59
66
  data = pd.read_csv(data_path)
60
-
61
- fontsize = 18
62
-
63
- plt.rcParams.update({'font.size': fontsize})
67
+
68
+ # Extract ‘variable’ and ‘gene_nr’ from your feature notation
64
69
  data['variable'] = data['feature'].str.extract(r'\[(.*?)\]')
65
70
  data['variable'].fillna(data['feature'], inplace=True)
66
71
  data['gene_nr'] = data['variable'].str.split('_').str[0]
67
72
  data = data[data['variable'] != 'Intercept']
68
73
 
69
- # Load metadata
74
+ # --- Load metadata ---
70
75
  if isinstance(metadata_path, pd.DataFrame):
71
76
  metadata = metadata_path
72
77
  else:
73
78
  metadata = pd.read_csv(metadata_path)
79
+
74
80
  metadata['gene_nr'] = metadata['gene_nr'].astype(str)
75
81
  data['gene_nr'] = data['gene_nr'].astype(str)
76
82
 
77
- merged_data = pd.merge(data, metadata[['gene_nr', metadata_column]], on='gene_nr', how='left')
83
+ # Merge data and metadata
84
+ merged_data = pd.merge(data, metadata[['gene_nr', metadata_column]],
85
+ on='gene_nr', how='left')
78
86
  merged_data[metadata_column].fillna('unknown', inplace=True)
79
87
 
80
- # Define palette and markers
81
- palette = {'pc': 'red', 'nc': 'green', 'control': 'white', 'other': 'gray'}
82
- marker_dict = {val: marker for val, marker in zip(
83
- merged_data[metadata_column].unique(), markers)}
84
-
85
- # Create the figure with custom spacing
86
- fig = plt.figure(figsize=(figsize,figsize))
88
+ # --- Create figure with "upper" and "lower" subplots sharing the x-axis ---
89
+ fig = plt.figure(figsize=(figsize, figsize))
87
90
  gs = GridSpec(2, 1, height_ratios=[1, 3], hspace=0.05)
88
-
89
91
  ax_upper = fig.add_subplot(gs[0])
90
92
  ax_lower = fig.add_subplot(gs[1], sharex=ax_upper)
91
93
 
92
94
  # Hide x-axis labels on the upper plot
93
95
  ax_upper.tick_params(axis='x', which='both', bottom=False, labelbottom=False)
94
96
 
97
+ # List to collect the variables (hits) that meet threshold criteria
95
98
  hit_list = []
96
99
 
97
- # Scatter plot on both axes
100
+ # --- Scatter plot on both axes ---
98
101
  for _, row in merged_data.iterrows():
99
102
  y_val = -np.log10(row['p_value'])
103
+
104
+ # Decide which axis to draw on based on the p-value
100
105
  ax = ax_upper if y_val > y_lims[1][0] else ax_lower
101
106
 
107
+ # Here is the main change: color by the colors dict
102
108
  ax.scatter(
103
- row['coefficient'], y_val,
104
- color=palette.get(row['condition'], 'gray'),
105
- marker=marker_dict.get(row[metadata_column], 'o'),
106
- s=point_size, edgecolor='black', alpha=0.6
109
+ row['coefficient'],
110
+ y_val,
111
+ color=colors.get(row[metadata_column], 'gray'), # <-- Use your color dict
112
+ marker='o', # You can fix a single marker if desired
113
+ s=point_size,
114
+ edgecolor='black',
115
+ alpha=0.6
107
116
  )
108
117
 
109
- if row['p_value'] <= 0.05 and abs(row['coefficient']) >= abs(threshold):
118
+ # Check significance thresholds
119
+ if (row['p_value'] <= 0.05) and (abs(row['coefficient']) >= abs(threshold)):
110
120
  hit_list.append(row['variable'])
111
121
 
112
- # Set axis limits
122
+ # --- Adjust axis limits ---
113
123
  ax_upper.set_ylim(y_lims[1])
114
124
  ax_lower.set_ylim(y_lims[0])
115
125
  ax_lower.set_xlim(x_lim)
116
126
 
127
+ # Hide top spines
117
128
  ax_lower.spines['top'].set_visible(False)
118
129
  ax_upper.spines['top'].set_visible(False)
119
130
  ax_upper.spines['bottom'].set_visible(False)
120
131
 
121
- # Set x-axis and y-axis titles
122
- ax_lower.set_xlabel('Coefficient') # X-axis title on the lower graph
123
- ax_lower.set_ylabel('-log10(p-value)') # Y-axis title on the lower graph
124
- ax_upper.set_ylabel('-log10(p-value)') # Y-axis title on the upper graph
125
-
132
+ # Set x-axis and y-axis labels
133
+ ax_lower.set_xlabel('Coefficient')
134
+ ax_lower.set_ylabel('-log10(p-value)')
135
+ ax_upper.set_ylabel('-log10(p-value)')
136
+
126
137
  for ax in [ax_upper, ax_lower]:
127
138
  ax.spines['right'].set_visible(False)
128
139
 
129
- # Add threshold lines to both axes
140
+ # --- Add threshold lines to both axes ---
130
141
  for ax in [ax_upper, ax_lower]:
131
142
  ax.axvline(x=-abs(threshold), linestyle='--', color='black')
132
143
  ax.axvline(x=abs(threshold), linestyle='--', color='black')
133
144
 
134
145
  ax_lower.axhline(y=-np.log10(0.05), linestyle='--', color='black')
135
146
 
136
- # Annotate significant points
137
- texts_upper, texts_lower = [], [] # Collect text annotations separately
147
+ # --- Annotate significant points ---
148
+ texts_upper, texts_lower = [], []
138
149
 
139
150
  for _, row in merged_data.iterrows():
140
151
  y_val = -np.log10(row['p_value'])
@@ -142,38 +153,50 @@ def custom_volcano_plot(data_path, metadata_path, metadata_column='tagm_location
142
153
  continue
143
154
 
144
155
  ax = ax_upper if y_val > y_lims[1][0] else ax_lower
145
- text = ax.text(row['coefficient'], y_val, row['variable'],
146
- fontsize=fontsize, ha='center', va='bottom')
156
+ text = ax.text(
157
+ row['coefficient'],
158
+ y_val,
159
+ row['variable'],
160
+ fontsize=fontsize,
161
+ ha='center',
162
+ va='bottom'
163
+ )
147
164
 
148
165
  if ax == ax_upper:
149
166
  texts_upper.append(text)
150
167
  else:
151
168
  texts_lower.append(text)
152
169
 
153
- # Adjust text positions to avoid overlap
170
+ # Attempt to keep text labels from overlapping
154
171
  adjust_text(texts_upper, ax=ax_upper, arrowprops=dict(arrowstyle='-', color='black'))
155
172
  adjust_text(texts_lower, ax=ax_lower, arrowprops=dict(arrowstyle='-', color='black'))
156
173
 
157
- # Add a single legend on the lower axis
158
- handles = [plt.Line2D([0], [0], marker=m, color='w', markerfacecolor='gray', markersize=10)
159
- for m in marker_dict.values()]
160
- labels = marker_dict.keys()
161
- ax_lower.legend(handles,
162
- labels,
163
- bbox_to_anchor=(1.05, 1),
164
- loc='upper left',
165
- borderaxespad=0.25,
166
- labelspacing=2,
167
- handletextpad=0.25,
168
- markerscale=2,
169
- prop={'size': fontsize})
170
-
171
-
172
- # Save and show the plot
174
+ # --- Add a legend keyed by color (optional) ---
175
+ # If you'd like a legend that shows what each compartment color represents:
176
+ legend_handles = []
177
+ for comp, comp_color in colors.items():
178
+ # Create a “dummy” scatter for legend
179
+ legend_handles.append(
180
+ plt.Line2D([0], [0], marker='o', color=comp_color,
181
+ label=comp, linewidth=0, markersize=8)
182
+ )
183
+ # You can adjust the location and styling of the legend to taste:
184
+ ax_lower.legend(
185
+ handles=legend_handles,
186
+ bbox_to_anchor=(1.05, 1),
187
+ loc='upper left',
188
+ borderaxespad=0.25,
189
+ labelspacing=2,
190
+ handletextpad=0.25,
191
+ markerscale=1.5,
192
+ prop={'size': fontsize}
193
+ )
194
+
195
+ # --- Save and show ---
173
196
  if save_path:
174
197
  plt.savefig(save_path, format='pdf', bbox_inches='tight')
175
198
  plt.show()
176
-
199
+
177
200
  return hit_list
178
201
 
179
202
  def go_term_enrichment_by_column(significant_df, metadata_path, go_term_columns=['Computed GO Processes', 'Curated GO Components', 'Curated GO Functions', 'Curated GO Processes']):
spacr/utils.py CHANGED
@@ -1372,40 +1372,6 @@ def annotate_conditions(df, cells=None, cell_loc=None, pathogens=None, pathogen_
1372
1372
 
1373
1373
  return df
1374
1374
 
1375
- def _split_data_v1(df, group_by, object_type):
1376
- """
1377
- Splits the input dataframe into numeric and non-numeric parts, groups them by the specified column,
1378
- and returns the grouped dataframes.
1379
-
1380
- Parameters:
1381
- df (pandas.DataFrame): The input dataframe.
1382
- group_by (str): The column name to group the dataframes by.
1383
- object_type (str): The column name to concatenate with 'prcf' to create a new column 'prcfo'.
1384
-
1385
- Returns:
1386
- grouped_numeric (pandas.DataFrame): The grouped dataframe containing numeric columns.
1387
- grouped_non_numeric (pandas.DataFrame): The grouped dataframe containing non-numeric columns.
1388
- """
1389
-
1390
- if 'prcf' not in df.columns:
1391
- try:
1392
- df['prcf'] = df['plate'].astype(str) + '_' + df['row_name'].astype(str) + '_' + df['column_name'].astype(str) + '_' + df['field'].astype(str)
1393
- except Exception as e:
1394
- print(e)
1395
-
1396
- df['prcfo'] = df['prcf'] + '_' + df[object_type]
1397
- df = df.set_index(group_by, inplace=False)
1398
-
1399
- df_numeric = df.select_dtypes(include=np.number)
1400
- df_non_numeric = df.select_dtypes(exclude=np.number)
1401
-
1402
- []
1403
-
1404
- grouped_numeric = df_numeric.groupby(df_numeric.index).mean()
1405
- grouped_non_numeric = df_non_numeric.groupby(df_non_numeric.index).first()
1406
-
1407
- return pd.DataFrame(grouped_numeric), pd.DataFrame(grouped_non_numeric)
1408
-
1409
1375
  def _split_data(df, group_by, object_type):
1410
1376
  """
1411
1377
  Splits the input dataframe into numeric and non-numeric parts, groups them by the specified column,
@@ -5045,22 +5011,22 @@ def generate_cytoplasm_mask(nucleus_mask, cell_mask):
5045
5011
  return cytoplasm_mask
5046
5012
 
5047
5013
  def add_column_to_database(settings):
5048
- #"""
5049
- #Adds a new column to the database table by matching on a common column from the DataFrame.
5050
- #If the column already exists in the database, it adds the column with a suffix.
5051
- #NaN values will remain as NULL in the database.
5052
-
5053
- #Parameters:
5054
- # settings (dict): A dictionary containing the following keys:
5055
- # csv_path (str): Path to the CSV file with the data to be added.
5056
- # db_path (str): Path to the SQLite database (or connection string for other databases).
5057
- # table_name (str): The name of the table in the database.
5058
- # update_column (str): The name of the new column in the DataFrame to add to the database.
5059
- # match_column (str): The common column used to match rows.
5060
-
5061
- #Returns:
5062
- # None
5063
- #"""
5014
+ """
5015
+ Adds a new column to the database table by matching on a common column from the DataFrame.
5016
+ If the column already exists in the database, it adds the column with a suffix.
5017
+ NaN values will remain as NULL in the database.
5018
+
5019
+ Parameters:
5020
+ settings (dict): A dictionary containing the following keys:
5021
+ csv_path (str): Path to the CSV file with the data to be added.
5022
+ db_path (str): Path to the SQLite database (or connection string for other databases).
5023
+ table_name (str): The name of the table in the database.
5024
+ update_column (str): The name of the new column in the DataFrame to add to the database.
5025
+ match_column (str): The common column used to match rows.
5026
+
5027
+ Returns:
5028
+ None
5029
+ """
5064
5030
 
5065
5031
  # Read the DataFrame from the provided CSV path
5066
5032
  df = pd.read_csv(settings['csv_path'])
@@ -5150,8 +5116,8 @@ def correct_metadata_column_names(df):
5150
5116
  df = df.rename(columns={'plate_name': 'plate'})
5151
5117
  if 'column_name' in df.columns:
5152
5118
  df = df.rename(columns={'column_name': 'column'})
5153
- if 'column_name' in df.columns:
5154
- df = df.rename(columns={'column_name': 'column'})
5119
+ if 'col' in df.columns:
5120
+ df = df.rename(columns={'col': 'column'})
5155
5121
  if 'row_name' in df.columns:
5156
5122
  df = df.rename(columns={'row_name': 'row_name'})
5157
5123
  if 'grna_name' in df.columns:
@@ -5245,3 +5211,129 @@ def group_feature_class(df, feature_groups=['cell', 'cytoplasm', 'nucleus', 'pat
5245
5211
  , ignore_index=True)
5246
5212
 
5247
5213
  return df
5214
+
5215
+ def delete_intermedeate_files(settings):
5216
+
5217
+ path_orig = os.path.join(settings['src'], 'orig')
5218
+ path_stack = os.path.join(settings['src'], 'stack')
5219
+ merged_stack = os.path.join(settings['src'], 'merged')
5220
+ path_norm_chan_stack = os.path.join(settings['src'], 'norm_channel_stack')
5221
+ path_1 = os.path.join(settings['src'], '1')
5222
+ path_2 = os.path.join(settings['src'], '2')
5223
+ path_3 = os.path.join(settings['src'], '3')
5224
+ path_4 = os.path.join(settings['src'], '4')
5225
+ path_5 = os.path.join(settings['src'], '5')
5226
+ path_6 = os.path.join(settings['src'], '6')
5227
+ path_7 = os.path.join(settings['src'], '7')
5228
+ path_8 = os.path.join(settings['src'], '8')
5229
+ path_9 = os.path.join(settings['src'], '9')
5230
+ path_10 = os.path.join(settings['src'], '10')
5231
+
5232
+ paths = [path_stack, path_norm_chan_stack, path_1, path_2, path_3, path_4, path_5, path_6, path_7, path_8, path_9, path_10]
5233
+
5234
+ merged_len = len(merged_stack)
5235
+ stack_len = len(path_stack)
5236
+
5237
+ if merged_len == stack_len and stack_len != 0:
5238
+ if 'src' in settings:
5239
+ if os.path.exists(settings['src']):
5240
+ if os.path.exists(path_orig):
5241
+ for path in paths:
5242
+ if os.path.exists(path):
5243
+ try:
5244
+ shutil.rmtree(path)
5245
+ print(f"Deleted {path}")
5246
+ except OSError as e:
5247
+ print(f"{path} could not be deleted: {e}. Delete manually.")
5248
+ else:
5249
+ print(f"{path_orig} does not exist.")
5250
+ else:
5251
+ print(f"{settings['src']} does not exist.")
5252
+ else:
5253
+ print("No 'src' key in settings dictionary.")
5254
+
5255
+ def filter_and_save_csv(input_csv, output_csv, column_name, upper_threshold, lower_threshold):
5256
+ """
5257
+ Reads a CSV into a DataFrame, filters rows based on a column for values > upper_threshold and < lower_threshold,
5258
+ and saves the filtered DataFrame to a new CSV file.
5259
+
5260
+ Parameters:
5261
+ input_csv (str): Path to the input CSV file.
5262
+ output_csv (str): Path to save the filtered CSV file.
5263
+ column_name (str): Column name to apply the filters on.
5264
+ upper_threshold (float): Upper threshold for filtering (values greater than this are retained).
5265
+ lower_threshold (float): Lower threshold for filtering (values less than this are retained).
5266
+
5267
+ Returns:
5268
+ None
5269
+ """
5270
+ # Read the input CSV file into a DataFrame
5271
+ df = pd.read_csv(input_csv)
5272
+
5273
+ # Filter rows based on the thresholds
5274
+ filtered_df = df[(df[column_name] > upper_threshold) | (df[column_name] < lower_threshold)]
5275
+
5276
+ # Save the filtered DataFrame to a new CSV file
5277
+ filtered_df.to_csv(output_csv, index=False)
5278
+ display(filtered_df)
5279
+
5280
+ print(f"Filtered DataFrame saved to {output_csv}")
5281
+
5282
+ def extract_tar_bz2_files(folder_path):
5283
+ """
5284
+ Extracts all .tar.bz2 files in the given folder into subfolders with the same name as the tar file.
5285
+
5286
+ Parameters:
5287
+ folder_path (str): Path to the folder containing .tar.bz2 files.
5288
+ """
5289
+ if not os.path.isdir(folder_path):
5290
+ raise ValueError(f"The provided path '{folder_path}' is not a valid folder.")
5291
+
5292
+ # Iterate over files in the folder
5293
+ for file_name in os.listdir(folder_path):
5294
+ if file_name.endswith('.tar.bz2'):
5295
+ file_path = os.path.join(folder_path, file_name)
5296
+ extract_folder = os.path.join(folder_path, os.path.splitext(os.path.splitext(file_name)[0])[0])
5297
+
5298
+ # Create the subfolder for extraction if it doesn't exist
5299
+ os.makedirs(extract_folder, exist_ok=True)
5300
+
5301
+ # Extract the tar.bz2 file
5302
+ try:
5303
+ with tarfile.open(file_path, 'r:bz2') as tar:
5304
+ tar.extractall(path=extract_folder)
5305
+ print(f"Extracted: {file_name} -> {extract_folder}")
5306
+ except Exception as e:
5307
+ print(f"Failed to extract {file_name}: {e}")
5308
+
5309
+
5310
+ def calculate_shortest_distance(df, object1, object2):
5311
+ """
5312
+ Calculate the shortest edge-to-edge distance between two objects (e.g., pathogen and nucleus).
5313
+
5314
+ Parameters:
5315
+ - df: Pandas DataFrame containing measurements
5316
+ - object1: String, name of the first object (e.g., "pathogen")
5317
+ - object2: String, name of the second object (e.g., "nucleus")
5318
+
5319
+ Returns:
5320
+ - df: Pandas DataFrame with a new column for shortest edge-to-edge distance.
5321
+ """
5322
+
5323
+ # Compute centroid-to-centroid Euclidean distance
5324
+ centroid_distance = np.sqrt(
5325
+ (df[f'{object1}_channel_0_centroid_weighted-0'] - df[f'{object2}_channel_0_centroid_weighted-0'])**2 +
5326
+ (df[f'{object1}_channel_0_centroid_weighted-1'] - df[f'{object2}_channel_0_centroid_weighted-1'])**2
5327
+ )
5328
+
5329
+ # Estimate object radii using Feret diameters
5330
+ object1_radius = df[f'{object1}_feret_diameter_max'] / 2
5331
+ object2_radius = df[f'{object2}_feret_diameter_max'] / 2
5332
+
5333
+ # Compute shortest edge-to-edge distance
5334
+ shortest_distance = centroid_distance - (object1_radius + object2_radius)
5335
+
5336
+ # Ensure distances are non-negative (overlapping objects should have distance 0)
5337
+ df[f'{object1}_{object2}_shortest_distance'] = np.maximum(shortest_distance, 0)
5338
+
5339
+ return df
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.3.81
3
+ Version: 0.4.1
4
4
  Summary: Spatial phenotype analysis of crisp screens (SpaCr)
5
5
  Home-page: https://github.com/EinarOlafsson/spacr
6
6
  Author: Einar Birnir Olafsson
@@ -32,6 +32,7 @@ Requires-Dist: monai>=1.3.0
32
32
  Requires-Dist: captum<1.0,>=0.7.0
33
33
  Requires-Dist: seaborn<1.0,>=0.13.2
34
34
  Requires-Dist: matplotlib<4.0,>=3.8.3
35
+ Requires-Dist: matplotlib-venn<2.0,>=1.1
35
36
  Requires-Dist: adjustText<2.0,>=1.2.0
36
37
  Requires-Dist: bottleneck<2.0,>=1.3.6
37
38
  Requires-Dist: numexpr<3.0,>=2.8.4
@@ -1,4 +1,4 @@
1
- spacr/__init__.py,sha256=fvk5JfLpOqUA1W0yPcsVZnS9qbpXFOceFk09LKolVfw,1627
1
+ spacr/__init__.py,sha256=iPlE-WRc1CjSNGPMbVvEKlJsTQlKjq29VjzvNUCpcOM,1401
2
2
  spacr/__main__.py,sha256=bkAJJD2kjIqOP-u1kLvct9jQQCeUXzlEjdgitwi1Lm8,75
3
3
  spacr/app_annotate.py,sha256=W9eLPa_LZIvXsXx_-0iDFEU938LBDvRy6prXo0qF4KQ,2533
4
4
  spacr/app_classify.py,sha256=urTP_wlZ58hSyM5a19slYlBxN0PdC-9-ga0hvq8CGWc,165
@@ -9,27 +9,28 @@ spacr/app_sequencing.py,sha256=DjG26jy4cpddnV8WOOAIiExtOe9MleVMY4MFa5uTo5w,157
9
9
  spacr/app_umap.py,sha256=ZWAmf_OsIKbYvolYuWPMYhdlVe-n2CADoJulAizMiEo,153
10
10
  spacr/cellpose.py,sha256=RBHMs2vwXcfkj0xqAULpALyzJYXddSRycgZSzmwI7v0,14755
11
11
  spacr/chat_bot.py,sha256=n3Fhqg3qofVXHmh3H9sUcmfYy9MmgRnr48663MVdY9E,1244
12
- spacr/core.py,sha256=3u2qKmPmTlswvE1uKTF4gi7KQ3sJBHV9No_ysgk7JCU,48487
13
- spacr/deep_spacr.py,sha256=V3diLyxX-0_F5UxhX_b94ROOvL9eoLvnoUmF3nMBqPQ,43250
12
+ spacr/core.py,sha256=lKeqmsVrGQ8cPU_WkoNGNBWrk-gtR1RkRkwDdnJ0u64,48829
13
+ spacr/deep_spacr.py,sha256=WN64EaQqF87JZg3Uan46t5Y28xsAGD2KMjr2ht6CyDs,54563
14
14
  spacr/gui.py,sha256=ARyn9Q_g8HoP-cXh1nzMLVFCKqthY4v2u9yORyaQqQE,8230
15
- spacr/gui_core.py,sha256=3S1S7rOtGfm5Z-Fb-jk1HxjsLZo6IboBxtXtsDMw1ME,46578
16
- spacr/gui_elements.py,sha256=fc9z-GP_PmtJy2lIsfi3fx5r5puTJ-zz8ntB9pC53Gc,138246
17
- spacr/gui_utils.py,sha256=u9RoIOWpAXFEOnUlLpMQZrc1pWSg6omZsJMIhJdRv_g,41211
18
- spacr/io.py,sha256=LF6lpphw7GSeuoHQijPykjKNF56wNTFEWFZuDQp3O6Q,145739
15
+ spacr/gui_core.py,sha256=U0A7waKgWq_Es9fMwcZbXUZYGzCqt2bgfY3HbxiFXnw,47466
16
+ spacr/gui_elements.py,sha256=HmITDncklKwtdFhxLhtYXOwndsRfgwWIPVi83VlXHB4,146419
17
+ spacr/gui_utils.py,sha256=0rDF23BUGcmjSJvfCiLoxhlGJdHkio1jTxyCzrMXr-g,41211
18
+ spacr/io.py,sha256=oqJwDJWksVdWE0bRAwytTOsjlL0o-J9lr_pQaw2cQ4Y,138288
19
19
  spacr/logger.py,sha256=lJhTqt-_wfAunCPl93xE65Wr9Y1oIHJWaZMjunHUeIw,1538
20
- spacr/measure.py,sha256=2lK-ZcTxLM-MpXV1oZnucRD9iz5aprwahRKw9IEqshg,55085
20
+ spacr/measure.py,sha256=jmOnLBudq3TuY723Cfo1EJBn67P6rlEvL6I-2FSkUgI,55315
21
21
  spacr/mediar.py,sha256=FwLvbLQW5LQzPgvJZG8Lw7GniA2vbZx6Jv6vIKu7I5c,14743
22
- spacr/ml.py,sha256=x19S8OsR5omb8e6MU9I99Nz95J_QvM5siyk-zaAU3p8,82866
22
+ spacr/ml.py,sha256=MrIAtUUxMOibWVL1SjCUnYlizawCp3l3SeY4Y9yEsPw,97251
23
23
  spacr/openai.py,sha256=5vBZ3Jl2llYcW3oaTEXgdyCB2aJujMUIO5K038z7w_A,1246
24
- spacr/plot.py,sha256=gXC7y3uT4sx8KRODeSFWQG_A1CylsuJ5B7HYe_un6so,165177
24
+ spacr/plot.py,sha256=Q5TbsR2NUWhA7z4HyF_2_FAEBFSNMU-G3UNDbRzW6mM,169485
25
25
  spacr/sequencing.py,sha256=ClUfwPPK6rNUbUuiEkzcwakzVyDKKUMv9ricrxT8qQY,25227
26
- spacr/settings.py,sha256=3bgBWBotIO7TZx2nh6JoEaqHNmwbChAiz1gW4xmURQs,81788
26
+ spacr/settings.py,sha256=fEk-9LSSvV1wGsn6xTaJWY7wF7_u8Fc-S1DaDHqZU3I,83997
27
27
  spacr/sim.py,sha256=1xKhXimNU3ukzIw-3l9cF3Znc_brW8h20yv8fSTzvss,71173
28
+ spacr/sp_stats.py,sha256=mbhwsyIqt5upsSD346qGjdCw7CFBa0tIS7zHU9e0jNI,9536
28
29
  spacr/stats.py,sha256=mbhwsyIqt5upsSD346qGjdCw7CFBa0tIS7zHU9e0jNI,9536
29
- spacr/submodules.py,sha256=SK8YEs850LAx30YAiwap7ecLpp1_p-bci6H-Or0GLoA,55500
30
+ spacr/submodules.py,sha256=mb2g0igUTws7y6xW1zIJw1E7eQyxsjEj5mk2Z-Qd8uw,67629
30
31
  spacr/timelapse.py,sha256=KGfG4L4-QnFfgbF7L6C5wL_3gd_rqr05Foje6RsoTBg,39603
31
- spacr/toxo.py,sha256=z2nT5aAze3NUIlwnBQcnkARihDwoPfqOgQIVoUluyK0,25087
32
- spacr/utils.py,sha256=jjZIqzJKl9nnWgj2eJiLFT27gED8hO6rAEsJLlimm-E,222298
32
+ spacr/toxo.py,sha256=TmuhejSIPLBvsgeblsUgSvBFCR1gOkApyTKidooJ5Us,26044
33
+ spacr/utils.py,sha256=of2t5Tq_RKdJ1QRDo4nJ3oEVev_6s2Oko3-lBxl4ScU,226293
33
34
  spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
34
35
  spacr/resources/MEDIAR/.gitignore,sha256=Ff1q9Nme14JUd-4Q3jZ65aeQ5X4uttptssVDgBVHYo8,152
35
36
  spacr/resources/MEDIAR/LICENSE,sha256=yEj_TRDLUfDpHDNM0StALXIt6mLqSgaV2hcCwa6_TcY,1065
@@ -152,9 +153,9 @@ spacr/resources/icons/umap.png,sha256=dOLF3DeLYy9k0nkUybiZMe1wzHQwLJFRmgccppw-8b
152
153
  spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif,sha256=Tl0ZUfZ_AYAbu0up_nO0tPRtF1BxXhWQ3T3pURBCCRo,7958528
153
154
  spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif,sha256=m8N-V71rA1TT4dFlENNg8s0Q0YEXXs8slIn7yObmZJQ,7958528
154
155
  spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif,sha256=Pbhk7xn-KUP6RSIhJsxQcrHFImBm3GEpLkzx7WOc-5M,7958528
155
- spacr-0.3.81.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
156
- spacr-0.3.81.dist-info/METADATA,sha256=TneYaiWWfNHUuqpSQpRAEzWzYia6KIksYDzNVDcsimw,6032
157
- spacr-0.3.81.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
158
- spacr-0.3.81.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
159
- spacr-0.3.81.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
160
- spacr-0.3.81.dist-info/RECORD,,
156
+ spacr-0.4.1.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
157
+ spacr-0.4.1.dist-info/METADATA,sha256=ibaavHM7Kuo-dVo-SkOgjKfL0D8mG8ouYCHEzTqsbwg,6072
158
+ spacr-0.4.1.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
159
+ spacr-0.4.1.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
160
+ spacr-0.4.1.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
161
+ spacr-0.4.1.dist-info/RECORD,,
File without changes