scMultiChat 0.1.0__tar.gz → 0.1.2__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.
Files changed (52) hide show
  1. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Analysis/Intra_strength.py +276 -5
  2. scmultichat-0.1.2/MultiChat/Plot/Visualization.py +1046 -0
  3. scmultichat-0.1.2/MultiChat/__init__.py +13 -0
  4. scmultichat-0.1.2/PKG-INFO +30 -0
  5. scmultichat-0.1.2/requirements.txt +18 -0
  6. scmultichat-0.1.2/scMultiChat.egg-info/PKG-INFO +30 -0
  7. scmultichat-0.1.2/scMultiChat.egg-info/requires.txt +18 -0
  8. {scmultichat-0.1.0 → scmultichat-0.1.2}/setup.py +1 -1
  9. scmultichat-0.1.0/MultiChat/Plot/Visualization.py +0 -470
  10. scmultichat-0.1.0/MultiChat/__init__.py +0 -12
  11. scmultichat-0.1.0/PKG-INFO +0 -156
  12. scmultichat-0.1.0/requirements.txt +0 -144
  13. scmultichat-0.1.0/scMultiChat.egg-info/PKG-INFO +0 -156
  14. scmultichat-0.1.0/scMultiChat.egg-info/requires.txt +0 -144
  15. {scmultichat-0.1.0 → scmultichat-0.1.2}/MANIFEST.in +0 -0
  16. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Analysis/Processing.py +0 -0
  17. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Analysis/__init__.py +0 -0
  18. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/__init__.py +0 -0
  19. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/_settings.py +0 -0
  20. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/_utils.py +0 -0
  21. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/_version.py +0 -0
  22. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/plotting/__init__.py +0 -0
  23. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/plotting/_palettes.py +0 -0
  24. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/plotting/_plot.py +0 -0
  25. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/plotting/_post_training.py +0 -0
  26. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/plotting/_utils.py +0 -0
  27. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/preprocessing/__init__.py +0 -0
  28. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/preprocessing/_general.py +0 -0
  29. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/preprocessing/_pca.py +0 -0
  30. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/preprocessing/_qc.py +0 -0
  31. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/preprocessing/_utils.py +0 -0
  32. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/preprocessing/_variable_genes.py +0 -0
  33. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/readwrite.py +0 -0
  34. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/__init__.py +0 -0
  35. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/_gene_scores.py +0 -0
  36. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/_general.py +0 -0
  37. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/_integration.py +0 -0
  38. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/_pbg.py +0 -0
  39. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/_post_training.py +0 -0
  40. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/_umap.py +0 -0
  41. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Heterogeneous_g_emb/tools/_utils.py +0 -0
  42. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Model/Layers.py +0 -0
  43. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Model/__init__.py +0 -0
  44. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Model/model_training.py +0 -0
  45. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Model/modules.py +0 -0
  46. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Model/utilities.py +0 -0
  47. {scmultichat-0.1.0 → scmultichat-0.1.2}/MultiChat/Plot/__init__.py +0 -0
  48. {scmultichat-0.1.0 → scmultichat-0.1.2}/pyproject.toml +0 -0
  49. {scmultichat-0.1.0 → scmultichat-0.1.2}/scMultiChat.egg-info/SOURCES.txt +0 -0
  50. {scmultichat-0.1.0 → scmultichat-0.1.2}/scMultiChat.egg-info/dependency_links.txt +0 -0
  51. {scmultichat-0.1.0 → scmultichat-0.1.2}/scMultiChat.egg-info/top_level.txt +0 -0
  52. {scmultichat-0.1.0 → scmultichat-0.1.2}/setup.cfg +0 -0
@@ -272,10 +272,15 @@ def calculate_r_tf_tg_cor(
272
272
  receptors: List[str],
273
273
  tf_tg_pairs: List[str],
274
274
  reg_dir: str = "R_TF_TG_Reg",
275
- output_dir: str = "output_cells_cor"
275
+ output_dir: str = "output_cells_cor",
276
+ align_method: str = "pca",
277
+ target_dim: int = 50
276
278
  ) -> Tuple[Dict[str, csr_matrix], csr_matrix]:
277
279
  """
278
- Get correlation score
280
+ Get correlation score with automatic feature alignment.
281
+
282
+ If feature dimensions of cell/gene/tf representations do not match,
283
+ the function will automatically align them using PCA or truncation.
279
284
  """
280
285
  os.makedirs(output_dir, exist_ok=True)
281
286
 
@@ -294,9 +299,58 @@ def calculate_r_tf_tg_cor(
294
299
  tf, tg = pair.split("->")
295
300
  parsed_pairs.append((tf, tg, gene_index.get(tg, -1)))
296
301
 
302
+ # print("Precomputing PCC matrices...")
303
+ # cell_gene_pcc_matrix = 1 - cdist(cell_rep.values, gene_rep.values, metric='correlation')
304
+ # cell_tf_pcc_matrix = 1 - cdist(cell_rep.values, tf_rep.values, metric='correlation')
305
+
306
+ cell_arr = cell_rep.values
307
+ gene_arr = gene_rep.values
308
+ tf_arr = tf_rep.values
309
+
310
+ d_cell = cell_arr.shape[1]
311
+ d_gene = gene_arr.shape[1]
312
+ d_tf = tf_arr.shape[1]
313
+
314
+ print(f"[Info] Original dimensions: cell={d_cell}, gene={d_gene}, tf={d_tf}")
315
+
316
+ if not (d_cell == d_gene == d_tf):
317
+ print("[Info] Feature dimensions are inconsistent!")
318
+
319
+ if align_method == "pca":
320
+ from sklearn.decomposition import PCA
321
+
322
+ new_dim = min(target_dim, d_cell, d_gene, d_tf)
323
+ print(f"[Info] Applying PCA to align all representations to {new_dim} dimensions.")
324
+
325
+ pca = PCA(n_components=new_dim)
326
+
327
+ cell_arr = pca.fit_transform(cell_arr)
328
+ gene_arr = pca.fit_transform(gene_arr)
329
+ tf_arr = pca.fit_transform(tf_arr)
330
+
331
+ elif align_method == "truncate":
332
+ new_dim = min(d_cell, d_gene, d_tf)
333
+ print(f"[Info] Truncating all representations to {new_dim} dimensions.")
334
+
335
+ cell_arr = cell_arr[:, :new_dim]
336
+ gene_arr = gene_arr[:, :new_dim]
337
+ tf_arr = tf_arr[:, :new_dim]
338
+
339
+ else:
340
+ raise ValueError("align_method must be 'pca' or 'truncate'")
341
+
342
+ else:
343
+ print("[Info] Feature dimensions are already aligned. No processing needed.")
344
+
345
+ print(f"[Info] Final aligned dimension: {cell_arr.shape[1]}")
346
+
347
+ # ===============================
348
+ # PCC computation
349
+ # ===============================
297
350
  print("Precomputing PCC matrices...")
298
- cell_gene_pcc_matrix = 1 - cdist(cell_rep.values, gene_rep.values, metric='correlation')
299
- cell_tf_pcc_matrix = 1 - cdist(cell_rep.values, tf_rep.values, metric='correlation')
351
+ cell_gene_pcc_matrix = 1 - cdist(cell_arr, gene_arr, metric='correlation')
352
+ cell_tf_pcc_matrix = 1 - cdist(cell_arr, tf_arr, metric='correlation')
353
+
300
354
  cell_gene_pcc_matrix = np.abs(cell_gene_pcc_matrix)
301
355
  cell_tf_pcc_matrix = np.abs(cell_tf_pcc_matrix)
302
356
 
@@ -1755,4 +1809,221 @@ def Identify_concat_paths_celltype(sig_LR_pair_celltype,vola_LR_pair_celltype,ou
1755
1809
 
1756
1810
  sig_LR_pair_celltype_updated.to_csv(out_path, sep=",", index=False)
1757
1811
  print(f"sig_Path_pair_celltype_updated saved to {out_path}")
1758
- return sig_LR_pair_celltype_updated
1812
+ return sig_LR_pair_celltype_updated
1813
+
1814
+
1815
+ def sig_LR_with_source_target(base_path,db,cell_type):
1816
+
1817
+ ligand_unique = db['Ligand_Symbol'].unique()
1818
+
1819
+ to_lst = []
1820
+ path_lst = []
1821
+ comm_score_lst = []
1822
+ z_score_lst = []
1823
+ from_lst = []
1824
+ source_lst = []
1825
+ target_lst = []
1826
+
1827
+ sig_df = pd.read_csv(base_path+f'CCC/Significant_LRs.csv', index_col=None)
1828
+ Nei_adj = pd.read_csv(f'{base_path}CCC/Nei_adj.csv', index_col=None, header=None, sep='\t')
1829
+ rna_smooth = pd.read_csv(base_path+ f'CCC/expression_smooth.txt', index_col=0, sep='\t')
1830
+ Nei_adj_type = Nei_adj.copy()
1831
+
1832
+ for idx, row in sig_df.iterrows():
1833
+ lr_symbol = row['LR_Symbol']
1834
+ lig, rec = lr_symbol.split('->')
1835
+ Nei_adj_cur = Nei_adj_type.copy()
1836
+
1837
+ Nei_adj_cur.index = cell_type.index
1838
+ Nei_adj_cur = pd.concat([cell_type, Nei_adj_cur], axis=1)
1839
+ to_cell = row['Sample_Name']
1840
+ if to_cell not in Nei_adj_cur.index:
1841
+ continue
1842
+ from_cell_lst = Nei_adj_cur.index[Nei_adj_cur.loc[to_cell][1:-1].to_list()].to_list()
1843
+ for from_cell in from_cell_lst:
1844
+ if pd.isna(from_cell) or from_cell not in rna_smooth.columns:
1845
+ continue
1846
+ if lig in rna_smooth.index:
1847
+ lig_exp = rna_smooth.loc[lig, from_cell]
1848
+ if lig_exp > 0:
1849
+ to_lst.append(to_cell)
1850
+ path_lst.append(row['LR_Symbol'])
1851
+ comm_score_lst.append(row['Inter_Score'])
1852
+ z_score_lst.append(row['Z_Score'])
1853
+ from_lst.append(from_cell)
1854
+ source_lst.append(Nei_adj_cur.loc[from_cell]['cell_type'])
1855
+ target_lst.append(Nei_adj_cur.loc[to_cell]['cell_type'])
1856
+
1857
+ results_df = pd.DataFrame({
1858
+ 'from_cell': from_lst,
1859
+ 'to_cell': to_lst,
1860
+ 'source': source_lst,
1861
+ 'target': target_lst,
1862
+ 'path_symbol': path_lst,
1863
+ 'comm_score': comm_score_lst,
1864
+ 'z_score': z_score_lst
1865
+ })
1866
+ results_df.to_csv(os.path.join(base_path, f'CCC/Significant_LRs_res.csv'), index=False)
1867
+ print(f"Saved results for Significant_LRs to {os.path.join(base_path, f'CCC/Significant_LRs_res.csv')}, shape: {results_df.shape}")
1868
+
1869
+
1870
+ def Identify_significant_lr_pairs_celltypes(sif_df, agg_method='mean', min_cells_count=10):
1871
+ if not isinstance(sif_df, pd.DataFrame):
1872
+ raise ValueError("input needs to be pandas DataFrame")
1873
+
1874
+ required_cols = ['path_symbol', 'source', 'target', 'comm_score', 'z_score']
1875
+ missing = set(required_cols) - set(sif_df.columns)
1876
+ if missing:
1877
+ raise ValueError(f"sif_df is missing required columns: {missing}")
1878
+
1879
+ group_cols = ['path_symbol', 'source', 'target']
1880
+ count_df = sif_df.groupby(group_cols).size().reset_index(name='cells_count')
1881
+ valid_groups = count_df[count_df['cells_count'] >= min_cells_count]
1882
+
1883
+ sig_df_filtered = sif_df.merge(
1884
+ valid_groups[group_cols],
1885
+ on=group_cols,
1886
+ how='inner'
1887
+ )
1888
+
1889
+ result_df = (sig_df_filtered.groupby(group_cols).agg({
1890
+ 'comm_score': agg_method,
1891
+ 'z_score': agg_method
1892
+ }).reset_index())
1893
+
1894
+ result_df = result_df.rename(columns={'path_symbol': 'LR_Symbol',
1895
+ 'source': 'Source_Type',
1896
+ 'target': 'Target_Type',
1897
+ 'comm_score': 'Comm_Score',
1898
+ 'z_score': 'Z_Score'})
1899
+ return result_df
1900
+
1901
+
1902
+ def sig_path_with_source_target(base_path,db, cell_type):
1903
+ ligand_unique = db['Ligand_Symbol'].unique()
1904
+ to_lst = []
1905
+ path_lst = []
1906
+ comm_score_lst = []
1907
+ z_score_lst = []
1908
+ from_lst = []
1909
+ source_lst = []
1910
+ target_lst = []
1911
+
1912
+ cell_type = pd.read_csv('/home/nas2/biod/zhencaiwei/RegChatz_V2/Datasets/ISSAAC/inputs/celltype_info.csv', index_col=0, sep="\t")
1913
+ cell_type.rename(columns={'celltype': 'cell_type'}, inplace=True)
1914
+ Nei_adj = pd.read_csv(f'{base_path}CCC/Nei_adj.csv', index_col=None, header=None, sep='\t')
1915
+
1916
+ Nei_adj_type = Nei_adj.copy()
1917
+ Nei_adj_type.index = cell_type.index
1918
+ Nei_adj_type = pd.concat([cell_type, Nei_adj_type], axis=1)
1919
+
1920
+ for ligand in tqdm(ligand_unique, desc="Processing ligands"):
1921
+ sig_path_file = base_path+'CCC/Stats_results_Lig/Significant_paths_'+ligand+'.csv'
1922
+ if not os.path.exists(sig_path_file):
1923
+ print(f"Warning: File not found - {sig_path_file}")
1924
+ continue
1925
+ sig_df = pd.read_csv(sig_path_file, index_col=None)
1926
+ for idx, row in sig_df.iterrows():
1927
+ to_cell = row['Sample_Name']
1928
+ from_cell_lst = Nei_adj_type.index[Nei_adj_type.loc[to_cell][1:-1].to_list()].to_list()
1929
+ for from_cell in from_cell_lst:
1930
+ to_lst.append(to_cell)
1931
+ path_lst.append(row['Path_Symbol'])
1932
+ comm_score_lst.append(row['Comm_Score'])
1933
+ z_score_lst.append(row['Z_Score'])
1934
+ from_lst.append(from_cell)
1935
+ source_lst.append(Nei_adj_type.loc[from_cell]['cell_type'])
1936
+ target_lst.append(Nei_adj_type.loc[to_cell]['cell_type'])
1937
+ results_df = pd.DataFrame({
1938
+ 'from_cell': from_lst,
1939
+ 'to_cell': to_lst,
1940
+ 'source': source_lst,
1941
+ 'target': target_lst,
1942
+ 'path_symbol': path_lst,
1943
+ 'comm_score': comm_score_lst,
1944
+ 'z_score': z_score_lst
1945
+ })
1946
+ results_df.to_csv(os.path.join(base_path, f'CCC/Significant_paths_res.csv'), index=False)
1947
+ print(f"Saved results for Significant_paths to {os.path.join(base_path, f'CCC/Significant_paths_res.csv')}, shape: {results_df.shape}")
1948
+
1949
+
1950
+
1951
+ def Identify_significant_lrfg_paths_celltypes(sif_df, agg_method='mean', min_cells_count=10):
1952
+ if not isinstance(sif_df, pd.DataFrame):
1953
+ raise ValueError("input needs to be pandas DataFrame")
1954
+
1955
+ required_cols = ['path_symbol', 'source', 'target', 'comm_score', 'z_score']
1956
+ missing = set(required_cols) - set(sif_df.columns)
1957
+ if missing:
1958
+ raise ValueError(f"sif_df is missing required columns: {missing}")
1959
+
1960
+ group_cols = ['path_symbol', 'source', 'target']
1961
+ count_df = sif_df.groupby(group_cols).size().reset_index(name='cells_count')
1962
+ valid_groups = count_df[count_df['cells_count'] >= min_cells_count]
1963
+
1964
+ sig_df_filtered = sif_df.merge(
1965
+ valid_groups[group_cols],
1966
+ on=group_cols,
1967
+ how='inner'
1968
+ )
1969
+
1970
+ result_df = (sig_df_filtered.groupby(group_cols).agg({
1971
+ 'comm_score': agg_method,
1972
+ 'z_score': agg_method
1973
+ }).reset_index())
1974
+
1975
+ result_df = result_df.rename(columns={'path_symbol': 'LR_Symbol',
1976
+ 'source': 'Source_Type',
1977
+ 'target': 'Target_Type',
1978
+ 'comm_score': 'Comm_Score',
1979
+ 'z_score': 'Z_Score'})
1980
+ return result_df
1981
+
1982
+
1983
+
1984
+ def calculate_all_tf_tg_scores_ablation(rna_mat, tf_list, tg_list, path):
1985
+ """
1986
+ Calculate TF-TG score after ablation of ATAC information (dependent only on RNA expression level)
1987
+ """
1988
+
1989
+ os.makedirs(path, exist_ok=True)
1990
+ samples = rna_mat.columns
1991
+
1992
+ tfs = list(set(tf_list))
1993
+ tgs = list(set(tg_list))
1994
+
1995
+ tf_tg_columns = [f"{tf}->{tg}" for tf in tfs for tg in tgs]
1996
+
1997
+ final_results = pd.DataFrame(
1998
+ index=samples,
1999
+ columns=tf_tg_columns,
2000
+ dtype=float
2001
+ )
2002
+
2003
+ for sample in tqdm(samples, desc="Processing cells (Ablation Mode)"):
2004
+ sample_file = os.path.join(path, f"{sample}.csv")
2005
+
2006
+ if os.path.exists(sample_file):
2007
+ try:
2008
+ sample_results = pd.read_csv(sample_file, index_col=0)
2009
+ if sample_results.shape[0] == len(tfs) and sample_results.shape[1] == len(tgs):
2010
+ final_results.loc[sample] = sample_results.values.ravel()
2011
+ continue
2012
+ except:
2013
+ pass
2014
+
2015
+ sample_rna = rna_mat[sample]
2016
+
2017
+ tf_vals = sample_rna.reindex(tfs, fill_value=0.0).values
2018
+ tg_vals = sample_rna.reindex(tgs, fill_value=0.0).values
2019
+
2020
+ score_matrix = np.outer(tf_vals, tg_vals)
2021
+
2022
+ sample_results = pd.DataFrame(score_matrix, index=tfs, columns=tgs)
2023
+ sample_results.to_csv(sample_file)
2024
+
2025
+ final_results.loc[sample] = score_matrix.ravel()
2026
+
2027
+ final_results.to_csv(os.path.join(path, "all_samples_tf_tg_scores.csv"))
2028
+
2029
+ return final_results