genal-python 1.2.4__tar.gz → 1.2.6__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 (108) hide show
  1. {genal_python-1.2.4 → genal_python-1.2.6}/PKG-INFO +1 -1
  2. {genal_python-1.2.4 → genal_python-1.2.6}/genal/Geno.py +9 -1
  3. {genal_python-1.2.4 → genal_python-1.2.6}/genal/__init__.py +1 -1
  4. {genal_python-1.2.4 → genal_python-1.2.6}/genal/association.py +23 -3
  5. {genal_python-1.2.4 → genal_python-1.2.6}/genal/extract_prs.py +15 -5
  6. {genal_python-1.2.4 → genal_python-1.2.6}/genal/lift.py +7 -3
  7. {genal_python-1.2.4 → genal_python-1.2.6}/pyproject.toml +1 -1
  8. {genal_python-1.2.4 → genal_python-1.2.6}/.DS_Store +0 -0
  9. {genal_python-1.2.4 → genal_python-1.2.6}/.gitignore +0 -0
  10. {genal_python-1.2.4 → genal_python-1.2.6}/.readthedocs.yaml +0 -0
  11. {genal_python-1.2.4 → genal_python-1.2.6}/Genal_flowchart.png +0 -0
  12. {genal_python-1.2.4 → genal_python-1.2.6}/LICENSE +0 -0
  13. {genal_python-1.2.4 → genal_python-1.2.6}/README.md +0 -0
  14. {genal_python-1.2.4 → genal_python-1.2.6}/docs/.DS_Store +0 -0
  15. {genal_python-1.2.4 → genal_python-1.2.6}/docs/Makefile +0 -0
  16. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.DS_Store +0 -0
  17. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.buildinfo +0 -0
  18. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.doctrees/api.doctree +0 -0
  19. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.doctrees/environment.pickle +0 -0
  20. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.doctrees/genal.doctree +0 -0
  21. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.doctrees/index.doctree +0 -0
  22. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.doctrees/introduction.doctree +0 -0
  23. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/.doctrees/modules.doctree +0 -0
  24. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_images/MR_plot_SBP_AS.png +0 -0
  25. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/Geno.html +0 -0
  26. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/MR.html +0 -0
  27. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/MR_tools.html +0 -0
  28. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/MRpresso.html +0 -0
  29. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/association.html +0 -0
  30. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/clump.html +0 -0
  31. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/extract_prs.html +0 -0
  32. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/geno_tools.html +0 -0
  33. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/lift.html +0 -0
  34. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/proxy.html +0 -0
  35. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/snp_query.html +0 -0
  36. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/genal/tools.html +0 -0
  37. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_modules/index.html +0 -0
  38. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_sources/api.rst.txt +0 -0
  39. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_sources/genal.rst.txt +0 -0
  40. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_sources/index.rst.txt +0 -0
  41. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_sources/introduction.rst.txt +0 -0
  42. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_sources/modules.rst.txt +0 -0
  43. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/basic.css +0 -0
  44. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/badge_only.css +0 -0
  45. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  46. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  47. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  48. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  49. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/fontawesome-webfont.eot +0 -0
  50. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/fontawesome-webfont.svg +0 -0
  51. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  52. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/fontawesome-webfont.woff +0 -0
  53. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  54. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-bold-italic.woff +0 -0
  55. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  56. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-bold.woff +0 -0
  57. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-bold.woff2 +0 -0
  58. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-normal-italic.woff +0 -0
  59. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  60. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-normal.woff +0 -0
  61. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/fonts/lato-normal.woff2 +0 -0
  62. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/css/theme.css +0 -0
  63. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/doctools.js +0 -0
  64. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/documentation_options.js +0 -0
  65. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/file.png +0 -0
  66. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/js/badge_only.js +0 -0
  67. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/js/html5shiv-printshiv.min.js +0 -0
  68. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/js/html5shiv.min.js +0 -0
  69. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/js/theme.js +0 -0
  70. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/language_data.js +0 -0
  71. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/minus.png +0 -0
  72. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/plus.png +0 -0
  73. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/pygments.css +0 -0
  74. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/searchtools.js +0 -0
  75. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/_static/sphinx_highlight.js +0 -0
  76. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/api.html +0 -0
  77. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/genal.html +0 -0
  78. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/genindex.html +0 -0
  79. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/index.html +0 -0
  80. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/introduction.html +0 -0
  81. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/modules.html +0 -0
  82. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/objects.inv +0 -0
  83. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/py-modindex.html +0 -0
  84. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/search.html +0 -0
  85. {genal_python-1.2.4 → genal_python-1.2.6}/docs/build/searchindex.js +0 -0
  86. {genal_python-1.2.4 → genal_python-1.2.6}/docs/make.bat +0 -0
  87. {genal_python-1.2.4 → genal_python-1.2.6}/docs/requirements.txt +0 -0
  88. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/.DS_Store +0 -0
  89. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/Images/Genal_flowchart.png +0 -0
  90. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/Images/MR_plot_SBP_AS.png +0 -0
  91. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/Images/genal_logo.png +0 -0
  92. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/api.rst +0 -0
  93. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/conf.py +0 -0
  94. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/index.rst +0 -0
  95. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/introduction.rst +0 -0
  96. {genal_python-1.2.4 → genal_python-1.2.6}/docs/source/modules.rst +0 -0
  97. {genal_python-1.2.4 → genal_python-1.2.6}/genal/MR.py +0 -0
  98. {genal_python-1.2.4 → genal_python-1.2.6}/genal/MR_tools.py +0 -0
  99. {genal_python-1.2.4 → genal_python-1.2.6}/genal/MRpresso.py +0 -0
  100. {genal_python-1.2.4 → genal_python-1.2.6}/genal/clump.py +0 -0
  101. {genal_python-1.2.4 → genal_python-1.2.6}/genal/constants.py +0 -0
  102. {genal_python-1.2.4 → genal_python-1.2.6}/genal/geno_tools.py +0 -0
  103. {genal_python-1.2.4 → genal_python-1.2.6}/genal/proxy.py +0 -0
  104. {genal_python-1.2.4 → genal_python-1.2.6}/genal/snp_query.py +0 -0
  105. {genal_python-1.2.4 → genal_python-1.2.6}/genal/tools.py +0 -0
  106. {genal_python-1.2.4 → genal_python-1.2.6}/genal_logo.png +0 -0
  107. {genal_python-1.2.4 → genal_python-1.2.6}/gitignore +0 -0
  108. {genal_python-1.2.4 → genal_python-1.2.6}/readthedocs.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: genal-python
3
- Version: 1.2.4
3
+ Version: 1.2.6
4
4
  Summary: A python toolkit for polygenic risk scoring and mendelian randomization.
5
5
  Author-email: Cyprien Rivier <riviercyprien@gmail.com>
6
6
  Requires-Python: >=3.8
@@ -41,7 +41,8 @@ from .constants import STANDARD_COLUMNS, REF_PANEL_COLUMNS, CHECKS_DICT, MR_METH
41
41
  # Consider reference panels in build 38
42
42
  # Add proxying function (input is df + searchspace (list of SNP or path to .bim, can be separated by chromosomes) and returns proxied df)
43
43
  # Get proxies (simply return a list of proxies)
44
- # Multi-MR with python MR
44
+ # Include proxying option to association_test
45
+ # Multi-MR
45
46
  # Check stability with variants on sexual chromosomes
46
47
 
47
48
 
@@ -482,6 +483,8 @@ class Geno:
482
483
  # Extract the SNP list
483
484
  snp_list = self.data["SNP"]
484
485
 
486
+ # Renaming to avoid conflicts with previous extraction
487
+ self.name = str(uuid.uuid4())[:8]
485
488
  # Extract SNPs using the provided path and SNP list
486
489
  _ = extract_snps_func(snp_list, self.name, path)
487
490
 
@@ -638,6 +641,9 @@ class Geno:
638
641
  if n_del > 0:
639
642
  data_prs.drop(index=duplicate_indices, inplace=True)
640
643
  print(f"After proxying, {n_del} SNPs had duplicated IDs and were removed.")
644
+
645
+ # Renaming to avoid conflicts with previous extraction
646
+ self.name = str(uuid.uuid4())[:8]
641
647
  # Compute PRS
642
648
  prs_data = prs_func(data_prs, weighted, path, ram=self.ram, name=self.name)
643
649
 
@@ -729,6 +735,8 @@ class Geno:
729
735
  # Extract the SNP list
730
736
  snp_list = data["SNP"]
731
737
 
738
+ # Renaming to avoid conflicts with previous extraction
739
+ self.name = str(uuid.uuid4())[:8]
732
740
  # Extract SNPs using the provided path and SNP list
733
741
  path = extract_snps_func(snp_list, self.name, path)
734
742
  if path == "FAILED":
@@ -4,7 +4,7 @@ from .tools import default_config, write_config, set_plink, install_plink, delet
4
4
  from .geno_tools import Combine_Geno
5
5
  from .constants import CONFIG_DIR
6
6
 
7
- __version__ = "1.2.4"
7
+ __version__ = "1.2.6"
8
8
 
9
9
  config_path = os.path.join(CONFIG_DIR, "config.json")
10
10
 
@@ -90,7 +90,27 @@ def _run_plink2_assoc_test(
90
90
 
91
91
  command.extend(["--out", output])
92
92
 
93
- subprocess.run(command, capture_output=True, text=True, check=True)
93
+ try:
94
+ subprocess.run(command, capture_output=True, text=True, check=True)
95
+ except Exception as e:
96
+ #Handle the case where the association fails because of numerical instability in the covariates
97
+ if "scales vary too widely" in str(e):
98
+ print("The association test failed because of numerical instability in the covariates. Rescaling the covariates.")
99
+ command.extend(["--covar-variance-standardize"])
100
+ try:
101
+ subprocess.run(command, capture_output=True, text=True, check=True)
102
+ except Exception as e:
103
+ print(f"Error running PLINK command: {e}")
104
+ print(f"PLINK stdout: {e.stdout}")
105
+ print(f"PLINK stderr: {e.stderr}")
106
+ raise ValueError("PLINK command failed. Check the error messages above for details.")
107
+
108
+ else:
109
+ print(f"Error running PLINK command: {e}")
110
+ print(f"PLINK stdout: {e.stdout}")
111
+ print(f"PLINK stderr: {e.stderr}")
112
+ raise ValueError("PLINK command failed. Check the error messages above for details.")
113
+
94
114
  return output
95
115
 
96
116
  def _process_results_plink2(output, data, pheno_type):
@@ -113,7 +133,7 @@ def _process_results_plink2(output, data, pheno_type):
113
133
 
114
134
  # Merge results with the clumped data
115
135
  data = data.drop(axis=1, columns=["BETA", "SE", "P"], errors="ignore").merge(
116
- assoc[["CHR","POS", "BETA", "A1", "P"]], how="inner", on=["CHR", "POS"]
136
+ assoc[["CHR","POS", "BETA", "SE", "A1", "P"]], how="inner", on=["CHR", "POS"]
117
137
  )
118
138
 
119
139
  # Adjust beta values based on allele match
@@ -309,7 +329,7 @@ def _standardize_column_names(data, PHENO, IID, FID):
309
329
  else:
310
330
  data["FID"] = data["IID"]
311
331
  print(
312
- "The FID column was not provided. The IID column will be used as the FID column."
332
+ "The FID column was not provided. The FIDs are assumed to be the same as the IIDs."
313
333
  )
314
334
 
315
335
  return data
@@ -193,17 +193,17 @@ def create_bedlist(bedlist_path, output_name, not_found):
193
193
  not_found (List[int]): List of chromosome numbers for which no files were found.
194
194
  """
195
195
  with open(bedlist_path, "w+") as bedlist_file:
196
- n_lines = 0
196
+ found = []
197
197
  for i in range(1, 23):
198
198
  if i in not_found:
199
199
  print(f"bed/bim/fam or pgen/pvar/psam files not found for chr{i}.")
200
200
  elif check_pfiles(f"{output_name}_chr{i}"):
201
201
  bedlist_file.write(f"{output_name}_chr{i}\n")
202
- n_lines += 1
202
+ found.append(i)
203
203
  print(f"SNPs extracted for chr{i}.")
204
204
  else:
205
205
  print(f"No SNPs extracted for chr{i}.")
206
- return n_lines
206
+ return found
207
207
 
208
208
 
209
209
  def extract_snps_from_split_data(name, path, output_path, snp_list_path, filetype):
@@ -225,11 +225,18 @@ def extract_snps_from_split_data(name, path, output_path, snp_list_path, filetyp
225
225
  # Merge extracted SNPs from each chromosome
226
226
  bedlist_name = f"{name}_bedlist.txt"
227
227
  bedlist_path = os.path.join("tmp_GENAL", bedlist_name)
228
- n_lines = create_bedlist(
228
+ found = create_bedlist(
229
229
  bedlist_path, os.path.join("tmp_GENAL", f"{name}_extract"), not_found
230
230
  )
231
- if n_lines == 0:
231
+ if len(found) == 0:
232
232
  raise Warning("No SNPs were extracted from any chromosome.")
233
+
234
+ # If only one chromosome was extracted, no need to merge, simply rename the files
235
+ if len(found) == 1:
236
+ chr_path = os.path.join("tmp_GENAL", f"{name}_extract_chr{found[0]}")
237
+ for ext in [".pgen", ".pvar", ".psam", ".log"]:
238
+ os.rename(f"{chr_path}{ext}", f"{output_path}{ext}")
239
+ return None, bedlist_path
233
240
 
234
241
  print("Merging SNPs extracted from each chromosome...")
235
242
  merge_command = f"{get_plink_path()} --pmerge-list {bedlist_path} pfile --out {output_path}"
@@ -286,6 +293,9 @@ def report_snps_not_found(nrow, name):
286
293
  def handle_multiallelic_variants(name, merge_command, bedlist_path):
287
294
  """Handle multiallelic variants detected during merging."""
288
295
 
296
+ if merge_command is None:
297
+ return
298
+
289
299
  def remove_multiallelic():
290
300
  missnp_path = os.path.join(
291
301
  "tmp_GENAL", f"{name}_allchr.vmiss"
@@ -156,9 +156,13 @@ def lift_coordinates_liftover(data, object_id, chain_path, liftover_path):
156
156
  # Call the liftOver software
157
157
  command = f"{liftover_path} {to_lift_filename} \
158
158
  {chain_path} {lifted_filename} {unmapped_filename}"
159
- output = subprocess.run(
160
- command, shell=True, capture_output=True, text=True, check=True
161
- )
159
+ try:
160
+ output = subprocess.run(
161
+ command, shell=True, capture_output=True, text=True, check=True
162
+ )
163
+ except Exception as e:
164
+ print(f"Error running liftOver: {e}")
165
+ raise ValueError("Error running liftOver. Check error message for more details.")
162
166
 
163
167
  ## Read the output, print the number of unlifted SNPs and remove them from the prelift data.
164
168
  df_post = pd.read_csv(lifted_filename, sep="\t", header=None)
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "genal-python" # Updated name for PyPI
7
- version = "1.2.4"
7
+ version = "1.2.6"
8
8
  authors = [{name = "Cyprien Rivier", email = "riviercyprien@gmail.com"}]
9
9
  description = "A python toolkit for polygenic risk scoring and mendelian randomization."
10
10
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes