spacr 0.3.47__py3-none-any.whl → 0.3.50__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
@@ -7,26 +7,52 @@ import pandas as pd
7
7
  from scipy.stats import fisher_exact
8
8
  from IPython.display import display
9
9
  from matplotlib.legend import Legend
10
+ from matplotlib.transforms import Bbox
11
+ from brokenaxes import brokenaxes
10
12
 
11
- def custom_volcano_plot(data_path, metadata_path, metadata_column='tagm_location', point_size=50, figsize=20, threshold=0, split_axis_lims = [10, None, None, 10], save_path=None, x_lim=[-0.5, 0.5]):
12
- """
13
- Create a volcano plot with the ability to control the shape of points based on a categorical column,
14
- color points based on a condition, annotate specific points based on p-value and coefficient thresholds,
15
- and control the size of points.
16
- """
17
- volcano_path = save_path
18
- padd = 30
19
- fontsize = 18
20
- # Load the data
13
+
14
+ from matplotlib.gridspec import GridSpec
15
+
16
+
17
+ def custom_volcano_plot(data_path, metadata_path, metadata_column='tagm_location',
18
+ point_size=50, figsize=20, threshold=0,
19
+ save_path=None, x_lim=[-0.5, 0.5], y_lims=[[0, 6], [9, 15]]):
20
+
21
+ markers = [
22
+ 'o', # Circle
23
+ 'X', # X-shaped marker
24
+ '^', # Upward triangle
25
+ 's', # Square
26
+ 'v', # Downward triangle
27
+ 'P', # Plus-filled pentagon
28
+ '*', # Star
29
+ '+', # Plus
30
+ 'x', # Cross
31
+ '.', # Point
32
+ ',', # Pixel
33
+ 'd', # Diamond
34
+ 'D', # Thin diamond
35
+ 'h', # Hexagon 1
36
+ 'H', # Hexagon 2
37
+ 'p', # Pentagon
38
+ '|', # Vertical line
39
+ '_', # Horizontal line
40
+ ]
41
+
42
+ plt.rcParams.update({'font.size': 14})
43
+
44
+ # Load data
21
45
  if isinstance(data_path, pd.DataFrame):
22
46
  data = data_path
23
47
  else:
24
48
  data = pd.read_csv(data_path)
25
-
49
+
50
+ fontsize = 18
51
+
52
+ plt.rcParams.update({'font.size': fontsize})
26
53
  data['variable'] = data['feature'].str.extract(r'\[(.*?)\]')
27
54
  data['variable'].fillna(data['feature'], inplace=True)
28
- split_columns = data['variable'].str.split('_', expand=True)
29
- data['gene_nr'] = split_columns[0]
55
+ data['gene_nr'] = data['variable'].str.split('_').str[0]
30
56
  data = data[data['variable'] != 'Intercept']
31
57
 
32
58
  # Load metadata
@@ -34,173 +60,110 @@ def custom_volcano_plot(data_path, metadata_path, metadata_column='tagm_location
34
60
  metadata = metadata_path
35
61
  else:
36
62
  metadata = pd.read_csv(metadata_path)
37
-
38
63
  metadata['gene_nr'] = metadata['gene_nr'].astype(str)
39
64
  data['gene_nr'] = data['gene_nr'].astype(str)
40
65
 
41
- # Merge data and metadata on 'gene_nr'
42
- merged_data = pd.merge(data, metadata[['gene_nr', 'tagm_location']], on='gene_nr', how='left')
43
-
44
- merged_data.loc[merged_data['gene_nr'].str.startswith('4'), metadata_column] = 'GT1_gene'
45
- merged_data.loc[merged_data['gene_nr'] == 'Intercept', metadata_column] = 'Intercept'
46
- merged_data.loc[merged_data['condition'] == 'control', metadata_column] = 'control'
66
+ merged_data = pd.merge(data, metadata[['gene_nr', metadata_column]], on='gene_nr', how='left')
47
67
  merged_data[metadata_column].fillna('unknown', inplace=True)
48
68
 
49
- # Categorize condition for coloring
50
- merged_data['condition'] = pd.Categorical(
51
- merged_data['condition'],
52
- categories=['other','pc', 'nc', 'control'],
53
- ordered=True)
54
-
55
- # Create subplots with a broken y-axis
56
- figsize_2 = figsize / 2
57
- fig, (ax1, ax2) = plt.subplots(
58
- 2, 1, figsize=(figsize, figsize),
59
- sharex=True, gridspec_kw={'height_ratios': [1, 3]}
60
- )
69
+ # Define palette and markers
70
+ palette = {'pc': 'red', 'nc': 'green', 'control': 'white', 'other': 'gray'}
71
+ marker_dict = {val: marker for val, marker in zip(
72
+ merged_data[metadata_column].unique(), markers)}
61
73
 
62
- # Define color palette
63
- palette = {
64
- 'pc': 'red',
65
- 'nc': 'green',
66
- 'control': 'white',
67
- 'other': 'gray'}
68
-
69
- # Scatter plot on both axes with legend completely disabled
70
- sns.scatterplot(
71
- data=merged_data,
72
- x='coefficient',
73
- y='-log10(p_value)',
74
- hue='condition',
75
- style=metadata_column if metadata_column else None,
76
- s=point_size,
77
- edgecolor='black',
78
- palette=palette,
79
- legend=False, # Disable automatic legend
80
- alpha=0.6,
81
- ax=ax2 # Lower plot
82
- )
83
-
84
- sns.scatterplot(
85
- data=merged_data[merged_data['-log10(p_value)'] > 10],
86
- x='coefficient',
87
- y='-log10(p_value)',
88
- hue='condition',
89
- style=metadata_column if metadata_column else None,
90
- s=point_size,
91
- edgecolor='black',
92
- palette=palette,
93
- legend=False, # No legend on the upper plot
94
- alpha=0.6,
95
- ax=ax1 # Upper plot
96
- )
74
+ # Create the figure with custom spacing
75
+ fig = plt.figure(figsize=(figsize,figsize))
76
+ gs = GridSpec(2, 1, height_ratios=[1, 3], hspace=0.05)
97
77
 
98
- # Ensure no previous legends on ax1 or ax2
99
- if ax1.get_legend() is not None:
100
- ax1.get_legend().remove()
78
+ ax_upper = fig.add_subplot(gs[0])
79
+ ax_lower = fig.add_subplot(gs[1], sharex=ax_upper)
101
80
 
102
- if ax2.get_legend() is not None:
103
- ax2.get_legend().remove()
81
+ # Hide x-axis labels on the upper plot
82
+ ax_upper.tick_params(axis='x', which='both', bottom=False, labelbottom=False)
104
83
 
105
- # Manually gather handles and labels from ax2 after plotting
106
- handles, labels = ax2.get_legend_handles_labels()
84
+ hit_list = []
107
85
 
108
- # Debug: Print the captured handles and labels for verification
109
- print(f"Handles: {handles}")
110
- print(f"Labels: {labels}")
86
+ # Scatter plot on both axes
87
+ for _, row in merged_data.iterrows():
88
+ y_val = -np.log10(row['p_value'])
89
+ ax = ax_upper if y_val > y_lims[1][0] else ax_lower
111
90
 
112
- # Identify shape-based legend entries (skip color-based entries)
113
- n_color_entries = len(set(merged_data['condition']))
114
- shape_handles = handles[n_color_entries:]
115
- shape_labels = labels[n_color_entries:]
91
+ ax.scatter(
92
+ row['coefficient'], y_val,
93
+ color=palette.get(row['condition'], 'gray'),
94
+ marker=marker_dict.get(row[metadata_column], 'o'),
95
+ s=point_size, edgecolor='black', alpha=0.6
96
+ )
116
97
 
117
- # Create and add the legend with shape-based entries
118
- legend = Legend(
119
- ax2, shape_handles, shape_labels,
120
- bbox_to_anchor=(1.05, 1), loc='upper left',
121
- handletextpad=2.0, labelspacing=1.5, borderaxespad=1.0,
122
- markerscale=2.0, prop={'size': 14}
123
- )
124
- ax2.add_artist(legend)
125
-
126
- if isinstance(split_axis_lims, list):
127
- if len(split_axis_lims) == 4:
128
- ylim_min_ax1 = split_axis_lims[0]
129
- if split_axis_lims[1] is None:
130
- ylim_max_ax1 = merged_data['-log10(p_value)'].max() + 5
131
- else:
132
- ylim_max_ax1 = split_axis_lims[1]
133
- ylim_min_ax2 = split_axis_lims[2]
134
- ylim_max_ax2 = split_axis_lims[3]
135
- else:
136
- ylim_min_ax1 = None
137
- ylim_max_ax1 = merged_data['-log10(p_value)'].max() + 5
138
- ylim_min_ax2 = 0
139
- ylim_max_ax2 = None
140
-
141
- # Set axis limits and hide unnecessary parts
142
- ax1.set_ylim(ylim_min_ax1, ylim_max_ax1)
143
- ax2.set_ylim(0, ylim_max_ax2)
144
-
145
- if x_lim != None:
146
- ax1.set_xlim(x_lim)
147
- ax2.set_xlim(x_lim)
148
-
149
- ax1.spines['bottom'].set_visible(False)
150
- ax2.spines['top'].set_visible(False)
151
- ax1.tick_params(labelbottom=False)
152
-
153
- ax1.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)
154
-
155
- # Add vertical threshold lines to both plots
156
- if threshold > 0:
157
- for ax in (ax1, ax2):
158
- ax.axvline(x=-abs(threshold), linestyle='--', color='black')
159
- ax.axvline(x=abs(threshold), linestyle='--', color='black')
98
+ if row['p_value'] <= 0.05 and abs(row['coefficient']) >= abs(threshold):
99
+ hit_list.append(row['variable'])
160
100
 
161
- # Add a horizontal line at p-value threshold (0.05)
162
- ax2.axhline(y=-np.log10(0.05), color='black', linestyle='--')
101
+ # Set axis limits
102
+ ax_upper.set_ylim(y_lims[1])
103
+ ax_lower.set_ylim(y_lims[0])
104
+ ax_lower.set_xlim(x_lim)
163
105
 
164
- # Annotate significant points on both axes
165
- texts_ax1 = []
166
- texts_ax2 = []
106
+ ax_lower.spines['top'].set_visible(False)
107
+ ax_upper.spines['top'].set_visible(False)
108
+ ax_upper.spines['bottom'].set_visible(False)
167
109
 
168
- for i, row in merged_data.iterrows():
169
- if row['p_value'] <= 0.05 and abs(row['coefficient']) >= abs(threshold):
170
- ax = ax1 if row['-log10(p_value)'] >= ax1.get_ylim()[0] else ax2
171
- # Create the annotation on the selected axis
172
- text = ax.text(
173
- row['coefficient'],
174
- -np.log10(row['p_value']),
175
- row['variable'],
176
- fontsize=fontsize,
177
- ha='center',
178
- va='bottom',
179
- )
110
+ # Set x-axis and y-axis titles
111
+ ax_lower.set_xlabel('Coefficient') # X-axis title on the lower graph
112
+ ax_lower.set_ylabel('-log10(p-value)') # Y-axis title on the lower graph
113
+ ax_upper.set_ylabel('-log10(p-value)') # Y-axis title on the upper graph
114
+
115
+ for ax in [ax_upper, ax_lower]:
116
+ ax.spines['right'].set_visible(False)
180
117
 
181
- # Store the text annotation in the correct list
182
- if ax == ax1:
183
- texts_ax1.append(text)
184
- else:
185
- texts_ax2.append(text)
118
+ # Add threshold lines to both axes
119
+ for ax in [ax_upper, ax_lower]:
120
+ ax.axvline(x=-abs(threshold), linestyle='--', color='black')
121
+ ax.axvline(x=abs(threshold), linestyle='--', color='black')
186
122
 
187
- # Adjust text positions to avoid overlap for both axes
188
- adjust_text(texts_ax1, arrowprops=dict(arrowstyle='-', color='black'), ax=ax1, expand_points=(padd, padd), fontsize=fontsize)
189
- adjust_text(texts_ax2, arrowprops=dict(arrowstyle='-', color='black'), ax=ax2, expand_points=(padd, padd), fontsize=fontsize)
123
+ ax_lower.axhline(y=-np.log10(0.05), linestyle='--', color='black')
190
124
 
191
- # Move the legend outside the lower plot
192
- ax2.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0.)
125
+ # Annotate significant points
126
+ texts_upper, texts_lower = [], [] # Collect text annotations separately
193
127
 
194
- # Adjust the spacing between subplots and move the title
195
- plt.subplots_adjust(hspace=0.05)
196
- fig.suptitle('Custom Volcano Plot of Coefficients', y=1.02, fontsize=16) # Title above the top plot
128
+ for _, row in merged_data.iterrows():
129
+ y_val = -np.log10(row['p_value'])
130
+ if row['p_value'] > 0.05 or abs(row['coefficient']) < abs(threshold):
131
+ continue
197
132
 
198
- # Save the plot as PDF
199
- plt.savefig(volcano_path, format='pdf', bbox_inches='tight')
200
- print(f'Saved Volcano plot: {volcano_path}')
133
+ ax = ax_upper if y_val > y_lims[1][0] else ax_lower
134
+ text = ax.text(row['coefficient'], y_val, row['variable'],
135
+ fontsize=fontsize, ha='center', va='bottom')
201
136
 
202
- # Show the plot
137
+ if ax == ax_upper:
138
+ texts_upper.append(text)
139
+ else:
140
+ texts_lower.append(text)
141
+
142
+ # Adjust text positions to avoid overlap
143
+ adjust_text(texts_upper, ax=ax_upper, arrowprops=dict(arrowstyle='-', color='black'))
144
+ adjust_text(texts_lower, ax=ax_lower, arrowprops=dict(arrowstyle='-', color='black'))
145
+
146
+ # Add a single legend on the lower axis
147
+ handles = [plt.Line2D([0], [0], marker=m, color='w', markerfacecolor='gray', markersize=10)
148
+ for m in marker_dict.values()]
149
+ labels = marker_dict.keys()
150
+ ax_lower.legend(handles,
151
+ labels,
152
+ bbox_to_anchor=(1.05, 1),
153
+ loc='upper left',
154
+ borderaxespad=0.25,
155
+ labelspacing=2,
156
+ handletextpad=0.25,
157
+ markerscale=2,
158
+ prop={'size': fontsize})
159
+
160
+
161
+ # Save and show the plot
162
+ if save_path:
163
+ plt.savefig(save_path, format='pdf', bbox_inches='tight')
203
164
  plt.show()
165
+
166
+ return hit_list
204
167
 
205
168
  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']):
206
169
  """
@@ -341,4 +304,150 @@ def go_term_enrichment_by_column(significant_df, metadata_path, go_term_columns=
341
304
 
342
305
  # Show the combined plot
343
306
  plt.tight_layout()
307
+ plt.show()
308
+
309
+ def plot_gene_phenotypes(data, gene_list, x_column='Gene ID', data_column='T.gondii GT1 CRISPR Phenotype - Mean Phenotype',error_column='T.gondii GT1 CRISPR Phenotype - Standard Error', save_path=None):
310
+ """
311
+ Plot a line graph for the mean phenotype with standard error shading and highlighted genes.
312
+
313
+ Args:
314
+ data (pd.DataFrame): The input DataFrame containing gene data.
315
+ gene_list (list): A list of gene names to highlight on the plot.
316
+ """
317
+ # Ensure x_column is properly processed
318
+ def extract_gene_id(gene):
319
+ if isinstance(gene, str) and '_' in gene:
320
+ return gene.split('_')[1]
321
+ return str(gene)
322
+
323
+ data.loc[:, data_column] = pd.to_numeric(data[data_column], errors='coerce')
324
+ data = data.dropna(subset=[data_column])
325
+ data.loc[:, error_column] = pd.to_numeric(data[error_column], errors='coerce')
326
+ data = data.dropna(subset=[error_column])
327
+
328
+ data['x'] = data[x_column].apply(extract_gene_id)
329
+
330
+ # Sort by the data_column and assign ranks
331
+ data = data.sort_values(by=data_column).reset_index(drop=True)
332
+ data['rank'] = range(1, len(data) + 1)
333
+
334
+ # Prepare the x, y, and error values for plotting
335
+ x = data['rank']
336
+ y = data[data_column]
337
+ yerr = data[error_column]
338
+
339
+ # Create the plot
340
+ plt.figure(figsize=(10, 10))
341
+
342
+ # Plot the mean phenotype with standard error shading
343
+ plt.plot(x, y, label='Mean Phenotype', color=(0/255, 155/255, 155/255), linewidth=2)
344
+ plt.fill_between(
345
+ x, y - yerr, y + yerr,
346
+ color=(0/255, 155/255, 155/255), alpha=0.1, label='Standard Error'
347
+ )
348
+
349
+ # Prepare for adjustText
350
+ texts = [] # Store text objects for adjustment
351
+
352
+ # Highlight the genes in the gene_list
353
+ for gene in gene_list:
354
+ gene_id = extract_gene_id(gene)
355
+ gene_data = data[data['x'] == gene_id]
356
+ if not gene_data.empty:
357
+ # Scatter the highlighted points in purple and add labels for adjustment
358
+ plt.scatter(
359
+ gene_data['rank'],
360
+ gene_data[data_column],
361
+ color=(155/255, 55/255, 155/255),
362
+ s=200,
363
+ alpha=0.6,
364
+ label=f'Highlighted Gene: {gene}',
365
+ zorder=3 # Ensure the points are on top
366
+ )
367
+ # Add the text label next to the highlighted gene
368
+ texts.append(
369
+ plt.text(
370
+ gene_data['rank'].values[0],
371
+ gene_data[data_column].values[0],
372
+ gene,
373
+ fontsize=18,
374
+ ha='right'
375
+ )
376
+ )
377
+
378
+ # Adjust text to avoid overlap with lines drawn from points to text
379
+ adjust_text(texts, arrowprops=dict(arrowstyle='-', color='gray'))
380
+
381
+ # Label the plot
382
+ plt.xlabel('Rank')
383
+ plt.ylabel('Mean Phenotype')
384
+ #plt.xticks(rotation=90) # Rotate x-axis labels for readability
385
+ plt.legend().remove() # Remove the legend if not needed
386
+ plt.tight_layout()
387
+
388
+ # Save the plot if a path is provided
389
+ if save_path:
390
+ plt.savefig(save_path, format='pdf', dpi=600, bbox_inches='tight')
391
+ print(f"Figure saved to {save_path}")
392
+
393
+ plt.show()
394
+
395
+ def plot_gene_heatmaps(data, gene_list, columns, x_column='Gene ID', normalize=False, save_path=None):
396
+ """
397
+ Generate a teal-to-white heatmap with the specified columns and genes.
398
+
399
+ Args:
400
+ data (pd.DataFrame): The input DataFrame containing gene data.
401
+ gene_list (list): A list of genes to include in the heatmap.
402
+ columns (list): A list of column names to visualize as heatmaps.
403
+ normalize (bool): If True, normalize the values for each gene between 0 and 1.
404
+ save_path (str): Optional. If provided, the plot will be saved to this path.
405
+ """
406
+ # Ensure x_column is properly processed
407
+ def extract_gene_id(gene):
408
+ if isinstance(gene, str) and '_' in gene:
409
+ return gene.split('_')[1]
410
+ return str(gene)
411
+
412
+ data['x'] = data[x_column].apply(extract_gene_id)
413
+
414
+ # Filter the data to only include the specified genes
415
+ filtered_data = data[data['x'].isin(gene_list)].set_index('x')[columns]
416
+
417
+ # Normalize each gene's values between 0 and 1 if normalize=True
418
+ if normalize:
419
+ filtered_data = filtered_data.apply(lambda x: (x - x.min()) / (x.max() - x.min()), axis=1)
420
+
421
+ # Define the figure size dynamically based on the number of genes and columns
422
+ width = len(columns) * 4
423
+ height = len(gene_list) * 1
424
+
425
+ # Create the heatmap
426
+ plt.figure(figsize=(width, height))
427
+ cmap = sns.color_palette("viridis", as_cmap=True)
428
+
429
+ # Plot the heatmap with genes on the y-axis and columns on the x-axis
430
+ sns.heatmap(
431
+ filtered_data,
432
+ cmap=cmap,
433
+ cbar=True,
434
+ annot=False,
435
+ linewidths=0.5,
436
+ square=True
437
+ )
438
+
439
+ # Set the labels
440
+ plt.xticks(rotation=90, ha='center') # Rotate x-axis labels for better readability
441
+ plt.yticks(rotation=0) # Keep y-axis labels horizontal
442
+ plt.xlabel('')
443
+ plt.ylabel('')
444
+
445
+ # Adjust layout to ensure the plot fits well
446
+ plt.tight_layout()
447
+
448
+ # Save the plot if a path is provided
449
+ if save_path:
450
+ plt.savefig(save_path, format='pdf', dpi=600, bbox_inches='tight')
451
+ print(f"Figure saved to {save_path}")
452
+
344
453
  plt.show()
spacr/utils.py CHANGED
@@ -4067,7 +4067,7 @@ def generate_path_list_from_db(db_path, file_metadata):
4067
4067
 
4068
4068
  return all_paths
4069
4069
 
4070
- def correct_paths(df, base_path):
4070
+ def correct_paths(df, base_path, folder='data'):
4071
4071
 
4072
4072
  if isinstance(df, pd.DataFrame):
4073
4073
 
@@ -4083,9 +4083,9 @@ def correct_paths(df, base_path):
4083
4083
  adjusted_image_paths = []
4084
4084
  for path in image_paths:
4085
4085
  if base_path not in path:
4086
- parts = path.split('/data/')
4086
+ parts = path.split(f'/{folder}/')
4087
4087
  if len(parts) > 1:
4088
- new_path = os.path.join(base_path, 'data', parts[1])
4088
+ new_path = os.path.join(base_path, f'{folder}', parts[1])
4089
4089
  adjusted_image_paths.append(new_path)
4090
4090
  else:
4091
4091
  adjusted_image_paths.append(path)
@@ -5224,4 +5224,12 @@ def correct_metadata_column_names(df):
5224
5224
  df = df.rename(columns={'grna_name': 'grna'})
5225
5225
  if 'plate_row' in df.columns:
5226
5226
  df[['plate', 'row']] = df['plate_row'].str.split('_', expand=True)
5227
- return df
5227
+ return df
5228
+
5229
+ def control_filelist(folder, mode='column', values=['01','02']):
5230
+ files = os.listdir(folder)
5231
+ if mode is 'column':
5232
+ filtered_files = [file for file in files if file.split('_')[1][1:] in values]
5233
+ if mode is 'row':
5234
+ filtered_files = [file for file in files if file.split('_')[1][:1] in values]
5235
+ return filtered_files
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.3.47
3
+ Version: 0.3.50
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
@@ -66,6 +66,7 @@ Requires-Dist: gdown
66
66
  Requires-Dist: IPython<9.0,>=8.18.1
67
67
  Requires-Dist: ipykernel
68
68
  Requires-Dist: ipywidgets<9.0,>=8.1.2
69
+ Requires-Dist: brokenaxes<1.0,>=0.6.2
69
70
  Requires-Dist: huggingface-hub<0.25,>=0.24.0
70
71
  Provides-Extra: dev
71
72
  Requires-Dist: pytest<3.11,>=3.9; extra == "dev"
@@ -8,26 +8,27 @@ spacr/app_measure.py,sha256=_K7APYIeOKpV6e_LcqabBjvEi7mfq9Fch8175x1x0k8,162
8
8
  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
+ spacr/chat_bot.py,sha256=n3Fhqg3qofVXHmh3H9sUcmfYy9MmgRnr48663MVdY9E,1244
11
12
  spacr/core.py,sha256=dW9RrAKFLfVsFhX0-kaVMc2T7b47Ky0pTXK-CEVOeWQ,48235
12
13
  spacr/deep_spacr.py,sha256=HdOcNU8cHcE_19nP7_5uTz-ih3E169ffr2Hm--NvMvA,43255
13
14
  spacr/gui.py,sha256=ARyn9Q_g8HoP-cXh1nzMLVFCKqthY4v2u9yORyaQqQE,8230
14
15
  spacr/gui_core.py,sha256=N7R7yvfK_dJhOReM_kW3Ci8Bokhi1OzsxeKqvSGdvV4,41460
15
- spacr/gui_elements.py,sha256=w-S1MZdyxt5O3DsNAHNNXy_WGfwBPg0NhwQtCsJeiao,137071
16
+ spacr/gui_elements.py,sha256=Dr9KEek41LggJ2z2zfh28a7w86sZXg1jzF388rF2BT4,138249
16
17
  spacr/gui_utils.py,sha256=KDWDWsi7UdZVhXk1ZWGx3ZqJMIxCUm3lGfjrVhbk52s,45463
17
18
  spacr/io.py,sha256=1rIdJ_8dyn7W4D2zXjaOqlgyo_Y5Z7X86aRp4hNYWCU,144194
18
19
  spacr/logger.py,sha256=lJhTqt-_wfAunCPl93xE65Wr9Y1oIHJWaZMjunHUeIw,1538
19
20
  spacr/measure.py,sha256=KdboGXoi85BO5-_6er7932FgjFI7G7tuaQDnWSiEuew,54817
20
21
  spacr/mediar.py,sha256=FwLvbLQW5LQzPgvJZG8Lw7GniA2vbZx6Jv6vIKu7I5c,14743
21
- spacr/ml.py,sha256=Mkxl4n3OvNsVix8bbPQ09-HTgP3YTzQOESso4_exKLs,54634
22
+ spacr/ml.py,sha256=Oykp3drBxZrcwrWQh2n6Xt1OzZER6pSIiaR-W0GO2_E,67353
22
23
  spacr/openai.py,sha256=5vBZ3Jl2llYcW3oaTEXgdyCB2aJujMUIO5K038z7w_A,1246
23
- spacr/plot.py,sha256=M04Cbv1n_FHxO0Qg3VNu_IQXRGt7lb-sgWzh9jjL4rI,145733
24
- spacr/sequencing.py,sha256=aP2QUfb9wpeJRZFLWFwxq1o4EtVpSvyVohOcm3Wvrq0,24965
25
- spacr/settings.py,sha256=XEpo9sQXmQ3-sdRNmcsss6q0j7ZAvoAFO-_D8ecgYQc,77710
24
+ spacr/plot.py,sha256=Wy5ac-InIn0VCfHNm1-MzFncNZqsTs4tHDWWFRdPz3Y,163420
25
+ spacr/sequencing.py,sha256=HDpF_C3hRd-fk6ZENPmI3vgYoom3HIvaeIIZWLhaIAY,25037
26
+ spacr/settings.py,sha256=QXtnWbDlABezc3wQjV-jEJvJTfEupkK3WYyKTcHkghk,77710
26
27
  spacr/sim.py,sha256=1xKhXimNU3ukzIw-3l9cF3Znc_brW8h20yv8fSTzvss,71173
27
28
  spacr/submodules.py,sha256=3C5M4UbI9Ral1MX4PTpucaAaqhL3RADuCOCqaHhMyUg,28048
28
29
  spacr/timelapse.py,sha256=FSYpUtAVy6xc3lwprRYgyDTT9ysUhfRQ4zrP9_h2mvg,39465
29
- spacr/toxo.py,sha256=RjAqI2sCcYYr-eiLPGnyJUn96zR_ATENuyiM2CZT408,13358
30
- spacr/utils.py,sha256=zkgUP_w_w9HJe4000KhVmpwO2gELoeIvdYNrXlRAzG8,221050
30
+ spacr/toxo.py,sha256=od_nHj3xSkqBnRqIy0Pr9rzBpexxuBMKLUrWKucNRpc,17055
31
+ spacr/utils.py,sha256=PKePCs3BVpaSV0XWLEcXMntI1l4hWiajM3eorHdo8Z8,221417
31
32
  spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
32
33
  spacr/resources/MEDIAR/.gitignore,sha256=Ff1q9Nme14JUd-4Q3jZ65aeQ5X4uttptssVDgBVHYo8,152
33
34
  spacr/resources/MEDIAR/LICENSE,sha256=yEj_TRDLUfDpHDNM0StALXIt6mLqSgaV2hcCwa6_TcY,1065
@@ -150,9 +151,9 @@ spacr/resources/icons/umap.png,sha256=dOLF3DeLYy9k0nkUybiZMe1wzHQwLJFRmgccppw-8b
150
151
  spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif,sha256=Tl0ZUfZ_AYAbu0up_nO0tPRtF1BxXhWQ3T3pURBCCRo,7958528
151
152
  spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif,sha256=m8N-V71rA1TT4dFlENNg8s0Q0YEXXs8slIn7yObmZJQ,7958528
152
153
  spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif,sha256=Pbhk7xn-KUP6RSIhJsxQcrHFImBm3GEpLkzx7WOc-5M,7958528
153
- spacr-0.3.47.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
154
- spacr-0.3.47.dist-info/METADATA,sha256=NEQNKKM40sYjqLkD1M-R4eOVTPSAQJ4zDD_5juTElbk,5949
155
- spacr-0.3.47.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
156
- spacr-0.3.47.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
157
- spacr-0.3.47.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
158
- spacr-0.3.47.dist-info/RECORD,,
154
+ spacr-0.3.50.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
155
+ spacr-0.3.50.dist-info/METADATA,sha256=daGbAWScl6sfl9uYXfvBZ3R9FjG9uHmROss7eKpgZYk,5987
156
+ spacr-0.3.50.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
157
+ spacr-0.3.50.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
158
+ spacr-0.3.50.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
159
+ spacr-0.3.50.dist-info/RECORD,,
File without changes