discotoolkit 1.1.0__tar.gz → 1.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: discotoolkit
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: DISCOtoolkit is an python package that allows users to access data and use the tools provided by the DISCO database.
5
5
  Home-page: http://www.immunesinglecell.org/
6
6
  Author: Li Mengwei, Rom Uddamvathanak
@@ -8,7 +8,7 @@
8
8
  -->
9
9
  [![Documentation Status](https://readthedocs.org/projects/discotoolkit-py/badge/?version=latest)](https://discotoolkit-py.readthedocs.io/en/latest/?badge=latest) [![Downloads](https://static.pepy.tech/personalized-badge/discotoolkit?period=total&units=international_system&left_color=black&right_color=orange&left_text=Downloads)](https://pepy.tech/project/discotoolkit) [![PyPI version](https://img.shields.io/pypi/v/discotoolkit)](https://pypi.org/project/discotoolkit)
10
10
 
11
- # DISCOtoolkit 1.1.0
11
+ # DISCOtoolkit 1.1.2
12
12
 
13
13
  DISCOtoolkit is an python package that allows users to access data and use the tools provided by the [DISCO database](https://www.immunesinglecell.org/). Read the documentation [DISCOtoolkit](https://discotoolkit-py.readthedocs.io/en/latest/). It provides the following functions:
14
14
 
@@ -214,14 +214,14 @@ def CELLiD_cluster(rna, ref_data : pd.DataFrame = None, ref_deg : pd.DataFrame =
214
214
  Geneset enrichment analysis using DISCO data
215
215
  """
216
216
 
217
- def CELLiD_enrichment(input : pd.DataFrame, reference : pd.DataFrame = None, ref_path : str = None, ncores : int = 10):
217
+ def CELLiD_enrichment(input : pd.DataFrame, reference : pd.DataFrame = None, ref_path : str = None, ncores : int = 1):
218
218
  """Function to generate enrichment analysis based on the reference gene sets and following the DISCO pipeline.
219
219
 
220
220
  Args:
221
221
  input (Pandas DataFrame): User defined Dataframe in the format of `(gene, fc)`. `gene` refer to gene name and `fc` refer to log fold change.
222
222
  reference (Pandas DataFrame, optional): Reference datasets from DISCO. Recommend to put as None as the function will automatically retrieve the dataset from the server. Defaults to None.
223
223
  ref_path (String, optional): Path to the reference dataset or reading the file if it is existed. Defaults to None.
224
- ncores (Integer, optional): Number of CPU cores to run the function. Defaults to 10.
224
+ ncores (Integer, optional): Number of CPU cores to run the function. Defaults to 1.
225
225
 
226
226
  Returns:
227
227
  Pandas DataFrame: return the significant gene sets that is over-represented in a large set of genes.
@@ -262,6 +262,7 @@ def CELLiD_enrichment(input : pd.DataFrame, reference : pd.DataFrame = None, ref
262
262
  # downloading the geneset data from disco database
263
263
  response = requests.get(url=prefix_disco_url +"/getGeneSetPkl", timeout=timeout)
264
264
  open(ref_path + "/ref_geneset.pkl", "wb").write(response.content)
265
+ reference = pd.read_pickle(ref_path + "/ref_geneset.pkl", compression = {'method':'gzip','compresslevel':6})
265
266
 
266
267
  else:
267
268
  # read the data into pandas dataframe for subsequent analysis
@@ -269,39 +270,54 @@ def CELLiD_enrichment(input : pd.DataFrame, reference : pd.DataFrame = None, ref
269
270
 
270
271
  # rename the name data to include the reference atlas
271
272
  reference["name"] = reference["name"] + " in " + reference["atlas"]
272
-
273
+ input["gene"] = input["gene"].str.upper() # convert all the gene to upper string as the reference gene name is in uppercase
273
274
  # condition when the user provide the fold change for the enrichment analysis
274
275
  if input_shape == 2:
275
- input["fc"] == 2 ** input["fc"] # 2 to the power of fc
276
- input = input.set_index(["gene"]) # set index to the gene
277
- input["gene"] = input.index
278
- input = input.loc[np.intersect1d(reference["gene"], input["gene"])] # only get the common genes for comparison
276
+ input["fc"] = 2 ** input["fc"] # 2 to the power of fc
277
+ input = input.set_index("gene", drop = False) # set index to the gene
278
+ input = input.loc[list(set(reference["gene"]) & set(input['gene']))] # only get the common genes for comparison
279
279
 
280
280
  # else we only look at the ranked gene list
281
281
  else:
282
- input["gene"] = input["gene"].str.upper() # convert all the gene to upper string as the reference gene name is in uppercase
283
- input = input.loc[np.intersect1d(input["gene"], reference["gene"])] # get only the common gene by comparing to the reference data
284
-
282
+ input = input.set_index("gene", drop = False)
283
+ input = input.loc[list(set(reference["gene"]) & set(input['gene']))] # only get the common genes for comparison
285
284
  # filter to get only the geneset that contain the input genes from the user
286
285
  # this might good different result from the website so lets remove it for
287
286
  # unique_names = reference[reference["gene"].isin(input["gene"])]["name"].unique()
288
- unique_names = reference["name"].unique()
289
287
 
290
288
  # now run the enrichment analysis
291
289
  logging.info("Comparing the ranked gene list to reference gene sets...")
292
290
 
293
- # compile the regular expression pattern
294
- pattern = re.compile(r" in (.*?$)")
291
+ # optimise the CELLiD_enrichment function
292
+ atlas_dict = {}
293
+ name_dict = {}
294
+ reference_atlas = reference['atlas']
295
+ reference_name = reference['name']
295
296
 
297
+ # pre compute the parameters of the fisher exact test for the reference data
298
+ for rownum in range(len(reference)):
299
+ if reference_atlas[rownum] not in atlas_dict.keys():
300
+ atlas_dict[reference_atlas[rownum]] = [rownum]
301
+ else:
302
+ atlas_dict[reference_atlas[rownum]].append(rownum)
303
+
304
+ if reference_name[rownum] not in name_dict.keys():
305
+ name_dict[reference_name[rownum]] = [rownum]
306
+ else:
307
+ name_dict[reference_name[rownum]].append(rownum)
308
+
296
309
  # apply function to the dataframe
297
- def process_unique_name(unique_name, input, reference, input_shape):
298
- # use the compiled pattern to search for matches
299
- atlas = pattern.search(unique_name).group(1) # getting the atlas string base on the last word in reference name
300
- reference_filter = reference[reference["name"] == unique_name].copy() # subset the reference data
301
- reference_full = reference[reference["atlas"] == atlas].copy() # full reference to the atlas
302
- reference_filter = reference_filter.set_index(["gene"]) # set gene as the index
303
- reference_filter["gene"] = reference_filter.index
304
- input_filter = input.loc[np.intersect1d(reference_full["gene"], input["gene"])].copy() # subset the input genes
310
+ def process_unique_name(reference_filter, input, atlas_dfs, input_shape, atlas_dict):
311
+ # use the compile`d pattern to search for matches
312
+ unique_name = reference_filter['name'].head(1).values[0]
313
+ atlas = reference_filter['atlas'].head(1).values
314
+ # print(unique_name)
315
+ reference_full = atlas_dfs[list(atlas_dict.keys()).index(atlas)]
316
+ # reference_filter = reference.iloc[name_dict[unique_name]].copy() # subset the reference data
317
+ # reference_full = reference.iloc[atlas_dict[atlas]].copy() # full reference to the atlas
318
+ reference_filter = reference_filter.set_index(["gene"], drop = False) # set gene as the index
319
+ # reference_filter["gene"] = reference_filter.index
320
+ input_filter = input.loc[list(set(reference_full["gene"]) & set(input["gene"]))] # subset the input genes
305
321
 
306
322
  # condition for no passed gene set
307
323
  if input_filter.empty:
@@ -318,24 +334,28 @@ def CELLiD_enrichment(input : pd.DataFrame, reference : pd.DataFrame = None, ref
318
334
  b = len(np.setdiff1d(input_filter["gene"], reference_filter["gene"])) + 1
319
335
  c = len(np.setdiff1d(reference_filter["gene"], input_filter["gene"])) + 1
320
336
  d = len(set(reference_full["gene"])) - a - b - c
321
-
337
+
322
338
  # get both value from the fisher exact test
323
- _, p_value = stats.fisher_exact(np.array([[a, b], [c, d]]))
324
- odds = odds_ratio(np.array([[a, b], [c, d]]).astype("int"), kind="conditional").statistic
325
- # p_value = fast_fisher_exact(a, b, c, d, alternative='two-sided')
326
- # odds = odds_ratio(a, b, c, d)
327
-
339
+ # pval = pvalue(a, b, c, d).two_tail
340
+ _, pval = stats.fisher_exact(np.array([[a, b], [c, d]]))
341
+ odds = (a * d)/(b * c)
328
342
  # only get the significant p_value
329
343
  # we can make changes to the p_value as in like we allow the user to specify it so that they have more control on the result they can obtain
330
- if p_value < 0.01:
331
- return pd.Series({"pval": p_value, "or": odds, "name": unique_name,
344
+ if pval < 0.01:
345
+ return pd.Series({"pval": pval, "or": odds, "name": unique_name,
332
346
  "gene": ",".join(reference_filter.loc[reference_filter["gene"].isin(input_filter["gene"]), "gene"]),
333
347
  "background": len(set(reference_full["gene"])), "overlap": len(reference_filter.loc[reference_filter["gene"].isin(input_filter["gene"])]), "geneset": len(reference_filter)})
334
348
  else:
335
349
  return None
336
350
 
351
+ # Split them into cores
352
+ unique_name_dfs = [reference.iloc[name_dict[key], :] for key in name_dict.keys()]
353
+ atlas_dfs = [reference.iloc[atlas_dict[key], :] for key in atlas_dict.keys()]
354
+
355
+ # return unique_name_dfs, atlas_dfs, input, input_shape
356
+ # return unique_name_dfs, atlas_dfs
337
357
  # using joblib to apply multiprocessing
338
- results = Parallel(n_jobs=ncores, batch_size=64, verbose = 2)(delayed(process_unique_name)(unique_name, input, reference, input_shape) for unique_name in unique_names)
358
+ results = Parallel(n_jobs=ncores, verbose = 2, batch_size = 64)(delayed(process_unique_name)(unique_name_df, input, atlas_dfs, input_shape, atlas_dict) for unique_name_df in unique_name_dfs)
339
359
  results = [res for res in results if res is not None]
340
360
 
341
361
  # concatenate the result into the dataframe to the user
@@ -4,4 +4,4 @@ from .DownloadDiscoData import *
4
4
  from .CELLiD import *
5
5
  from .GeneSearch import *
6
6
 
7
- __version__ = "1.1.0"
7
+ __version__ = "1.1.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: discotoolkit
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: DISCOtoolkit is an python package that allows users to access data and use the tools provided by the DISCO database.
5
5
  Home-page: http://www.immunesinglecell.org/
6
6
  Author: Li Mengwei, Rom Uddamvathanak
@@ -6,7 +6,7 @@ with open("requirements.txt", "r") as f:
6
6
 
7
7
  setup(
8
8
  name='discotoolkit',
9
- version="1.1.0",
9
+ version="1.1.2",
10
10
  url='http://www.immunesinglecell.org/',
11
11
  author='Li Mengwei, Rom Uddamvathanak',
12
12
  author_email='uddamvathanak_rom@immunol.a-star.edu.sg',
File without changes
File without changes