pyrolite 0.0.14__zip

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 (119) hide show
  1. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__init__.py +10 -0
  2. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/__init__.cpython-36.pyc +0 -0
  3. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/_version.cpython-36.pyc +0 -0
  4. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/alteration.cpython-36.pyc +0 -0
  5. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/classification.cpython-36.pyc +0 -0
  6. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/compositions.cpython-36.pyc +0 -0
  7. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/geochem.cpython-36.pyc +0 -0
  8. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/melts.cpython-36.pyc +0 -0
  9. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/norm.cpython-36.pyc +0 -0
  10. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/normalisation.cpython-36.pyc +0 -0
  11. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/__pycache__/plot.cpython-36.pyc +0 -0
  12. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/_version.py +21 -0
  13. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/alteration.py +66 -0
  14. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/classification.py +222 -0
  15. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/__init__.py +9 -0
  16. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/__pycache__/__init__.cpython-36.pyc +0 -0
  17. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/__pycache__/aggregate.cpython-36.pyc +0 -0
  18. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/__pycache__/codata.cpython-36.pyc +0 -0
  19. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/__pycache__/impute.cpython-36.pyc +0 -0
  20. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/__pycache__/renorm.cpython-36.pyc +0 -0
  21. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/aggregate.py +391 -0
  22. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/codata.py +266 -0
  23. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/impute.py +82 -0
  24. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/comp/renorm.py +40 -0
  25. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/compositions.py +524 -0
  26. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/georoc/GEOROC_CFB_Dataset_List.csv +42 -0
  27. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/georoc/GEOROC_Convergent_Dataset_List.csv +42 -0
  28. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/georoc/GEOROC_OBFB_Dataset_List.csv +5 -0
  29. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/georoc/GEOROC_OIB_Dataset_List.csv +49 -0
  30. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/georoc/GEOROC_OceanicPlateau_Dataset_List.csv +18 -0
  31. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/georoc/contents.json +1 -0
  32. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/melts/__pycache__/env.cpython-35.pyc +0 -0
  33. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/melts/__pycache__/env.cpython-36.pyc +0 -0
  34. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/melts/env.py +1063 -0
  35. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.Ba.modelfield +0 -0
  36. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.Bs.modelfield +0 -0
  37. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.F.modelfield +0 -0
  38. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.O1.modelfield +0 -0
  39. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.O2.modelfield +0 -0
  40. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.O3.modelfield +0 -0
  41. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.Pc.modelfield +0 -0
  42. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.Ph.modelfield +0 -0
  43. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.R.modelfield +0 -0
  44. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.S1.modelfield +0 -0
  45. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.S2.modelfield +0 -0
  46. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.S3.modelfield +0 -0
  47. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.T1.modelfield +0 -0
  48. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.T2.modelfield +0 -0
  49. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.U1.modelfield +0 -0
  50. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.U2.modelfield +0 -0
  51. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.U3.modelfield +0 -0
  52. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.modelfields +0 -0
  53. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.nan.modelfield +0 -0
  54. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS/TAS.none.modelfield +0 -0
  55. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/TAS.clsf.gz +0 -0
  56. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/aphanitic.clsf.gz +0 -0
  57. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/gabbroic.clsf.gz +0 -0
  58. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/peralkalinity.clsf.gz +0 -0
  59. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/phaneritic.clsf.gz +0 -0
  60. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/models/ultramafic.clsf.gz +0 -0
  61. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/refcomp/CH_PalmeONeill2014.csv +95 -0
  62. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/refcomp/DDMM_WorkmanHart2005.csv +105 -0
  63. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/refcomp/DMM_WorkmanHart2005.csv +105 -0
  64. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/refcomp/DM_SaltersStrake2004.csv +95 -0
  65. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/refcomp/EDMM_WorkmanHart2005.csv +105 -0
  66. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/refcomp/PM_PalmeONeill2014.csv +95 -0
  67. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/data/timescale/geotimescale_spans.csv +180 -0
  68. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/geochem.py +821 -0
  69. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/melts.py +92 -0
  70. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/__init__.py +10 -0
  71. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/__pycache__/__init__.cpython-36.pyc +0 -0
  72. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/__pycache__/db.cpython-36.pyc +0 -0
  73. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/__pycache__/ions.cpython-36.pyc +0 -0
  74. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/__pycache__/mineral.cpython-36.pyc +0 -0
  75. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/__pycache__/sites.cpython-36.pyc +0 -0
  76. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/db.py +88 -0
  77. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/ions.py +78 -0
  78. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/mineral.py +587 -0
  79. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/mineral/sites.py +134 -0
  80. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/norm.py +224 -0
  81. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/normalisation.py +204 -0
  82. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/plot.py +514 -0
  83. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__init__.py +13 -0
  84. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/__init__.cpython-36.pyc +0 -0
  85. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/database.cpython-36.pyc +0 -0
  86. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/env.cpython-36.pyc +0 -0
  87. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/general.cpython-36.pyc +0 -0
  88. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/georoc.cpython-36.pyc +0 -0
  89. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/math.cpython-36.pyc +0 -0
  90. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/melts.cpython-36.pyc +0 -0
  91. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/multip.cpython-36.pyc +0 -0
  92. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/multiprocessing.cpython-36.pyc +0 -0
  93. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/pd.cpython-36.pyc +0 -0
  94. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/plot.cpython-36.pyc +0 -0
  95. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/skl.cpython-36.pyc +0 -0
  96. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/spatial.cpython-36.pyc +0 -0
  97. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/text.cpython-36.pyc +0 -0
  98. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/time.cpython-36.pyc +0 -0
  99. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/__pycache__/wfs.cpython-36.pyc +0 -0
  100. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/database.py +88 -0
  101. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/env.py +81 -0
  102. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/general.py +266 -0
  103. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/georoc.py +444 -0
  104. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/math.py +371 -0
  105. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/melts.py +397 -0
  106. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/multip.py +29 -0
  107. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/multiprocessing.py +29 -0
  108. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/pd.py +214 -0
  109. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/plot.py +345 -0
  110. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/skl.py +847 -0
  111. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/spatial.py +91 -0
  112. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/text.py +207 -0
  113. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/time.py +224 -0
  114. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite/util/wfs.py +10 -0
  115. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite-0.0.14-py3.6.egg-info/PKG-INFO +61 -0
  116. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite-0.0.14-py3.6.egg-info/SOURCES.txt +83 -0
  117. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite-0.0.14-py3.6.egg-info/dependency_links.txt +1 -0
  118. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite-0.0.14-py3.6.egg-info/requires.txt +47 -0
  119. ProgramData/Anaconda3_64/Lib/site-packages/pyrolite-0.0.14-py3.6.egg-info/top_level.txt +1 -0
@@ -0,0 +1,397 @@
1
+ import os, sys, platform
2
+ import subprocess
3
+ from pathlib import Path
4
+ import io
5
+ import requests
6
+ from xml.etree import ElementTree as ET
7
+ import xmljson
8
+ import dicttoxml
9
+ import zipfile
10
+ import logging
11
+ import shutil
12
+ from .general import copy_file, extract_zip, remove_tempdir, internet_connection
13
+ from .env import environment_manager, validate_update_envvar
14
+ from .text import remove_prefix
15
+ from pyrolite.data.melts.env import MELTS_environment_variables
16
+
17
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ def output_formatter(value):
22
+ """Output formatter for environment variable values."""
23
+ if value and (value is not None):
24
+ return str(value)
25
+ else:
26
+ return ''
27
+
28
+
29
+ class MELTS_Env(object):
30
+
31
+ def __init__(self,
32
+ prefix='ALPHAMELTS_',
33
+ variable_model=MELTS_environment_variables):
34
+ super()
35
+ self.prefix = prefix
36
+ self.spec = variable_model
37
+ self.force_active = False
38
+ self.output_formatter = output_formatter
39
+ self.export_default_env(init=True)
40
+
41
+ def export_default_env(self, init=False):
42
+ """
43
+ Parse any environment variables which are already set.
44
+ Rest environment variables after substituding defaults for unset
45
+ variables.
46
+ """
47
+ _dump = self.dump()
48
+
49
+ for var, template in self.spec.items():
50
+ _spec = template
51
+ name = self.prefix + var
52
+ is_already_set = (name in os.environ) or \
53
+ (var in _dump.keys())
54
+ if not is_already_set and _spec['set']:
55
+ setting = True # should be set by default
56
+ elif is_already_set and _spec['set']:
57
+ setting = True # set, should be set by default
58
+ elif is_already_set and not _spec['set']:
59
+ setting = True # set, not set by default
60
+ elif not is_already_set and not _spec['set']:
61
+ setting = False # not set, should not be set
62
+
63
+ if setting: setattr(self, var, None)
64
+
65
+ def dump(self):
66
+ """Export environment configuration to a dictionary."""
67
+ keys = [k for k in self.spec.keys()]
68
+ pkeys = [self.prefix+k for k in keys]
69
+ values = [os.getenv(p) for p in pkeys]
70
+ types = [self.spec[k]['type']
71
+ if self.spec[k].get('type', None) is not None else str
72
+ for k in keys]
73
+
74
+ # Evironment variable are always imported as strings
75
+ _env = [(k, t(v)) if v and v not in [None, 'None']
76
+ else (k, None)
77
+ for k, p, v, t in zip(keys, pkeys, values, types)]
78
+ return {k: v for k, v in _env}
79
+
80
+
81
+ def __setattr__(self, name, value):
82
+ """
83
+ Custom setattr to set environment variables.
84
+
85
+ Setting attributes with or without the specified prefix should set
86
+ the appropriate prefixed environment variable.
87
+ """
88
+
89
+ if hasattr(self, 'spec'):
90
+ prefix = getattr(self, 'prefix', '')
91
+ dump = self.dump()
92
+ name = remove_prefix(name, prefix)
93
+ if name in self.spec:
94
+ validate_update_envvar(name,
95
+ value=value,
96
+ prefix=self.prefix,
97
+ force_active=self.force_active,
98
+ variable_model=self.spec,
99
+ formatter=self.output_formatter)
100
+ else: # other object attributes
101
+ self.__dict__[name]=value
102
+ else:
103
+ self.__dict__[name]=value
104
+
105
+
106
+ def run_wds_command(command):
107
+ """
108
+ Run a command within command prompt on Windows.
109
+
110
+ Here can be used to run alphamelts by specifing 'alphamelts'.
111
+ """
112
+ os.system("start /wait cmd /c {}".format(command))
113
+
114
+
115
+ def check_perl():
116
+ """Checks whether perl is installed on the system."""
117
+ try:
118
+ p = subprocess.check_output("perl -v")
119
+ returncode = 0
120
+ except subprocess.CalledProcessError as e:
121
+ output = e.output
122
+ returncode = e.returncode
123
+ except FileNotFoundError:
124
+ returncode = 1.
125
+
126
+ return returncode == 0
127
+
128
+
129
+ def download_melts(directory):
130
+ """
131
+ Download and extract melts zip file to a given directory.
132
+
133
+ TODO:
134
+ #2. Check install folder doens't have current installation
135
+ #3. If it does, and update is True - overwrite
136
+
137
+ Parameters
138
+ ----------
139
+ directory : str | pathlib.Path
140
+ Directory into which to extract melts.
141
+ """
142
+ try:
143
+ assert internet_connection()
144
+ system = platform.system()
145
+ release = platform.release()
146
+ version = platform.version()
147
+ bits, linkage = platform.architecture()
148
+ bits = bits[:2]
149
+
150
+ zipsource = "https://magmasource.caltech.edu/alphamelts/zipfiles/"
151
+ if system =='Linux':
152
+ if ('Microsoft' in release) or ('Microsoft' in version):
153
+ url = zipsource + "wsl_alphamelts_1-8.zip"
154
+ else:
155
+ url = zipsource + "linux_alphamelts_1-8.zip"
156
+
157
+ elif system == 'Darwin':
158
+ url = zipsource + "macosx_alphamelts_1-8.zip"
159
+ elif system == 'Windows':
160
+ url = zipsource + "windows_alphamelts_1-8.zip"
161
+ install_file = 'alphamelts_win{}.exe'.format(bits)
162
+ else:
163
+ raise NotImplementedError('System unknown: {}'.format(system))
164
+
165
+ # Set install directory for .bat files
166
+ directory = Path(directory)
167
+ if directory:
168
+ install_dir = directory
169
+ else:
170
+ install_dir = '.'
171
+
172
+ if not install_dir.exists():
173
+ install_dir.mkdir(parents=True)
174
+
175
+ r = requests.get(url, stream=True)
176
+ if r.ok:
177
+ z = zipfile.ZipFile(io.BytesIO(r.content))
178
+ extract_zip(z, install_dir)
179
+ except AssertionError:
180
+ raise AssertionError('Need an internet connection to download.')
181
+
182
+
183
+ def install_melts(install_dir,
184
+ link_dir=None,
185
+ eg_dir=None,
186
+ native=True,
187
+ temp_dir=Path("~").expanduser()/'temp'/'temp_melts',
188
+ keep_tempdir=False):
189
+ """
190
+ Parameters
191
+ ----------
192
+ install_dir : str | pathlib.Path
193
+ Directory into which to install melts executable.
194
+ link_dir : str | pathlib.Path, None
195
+ Directory into which to deposit melts links.
196
+ eg_dir : str | pathlib.Path
197
+ Directory into which to deposit melts examples.
198
+ native : bool, True
199
+ Whether to install using perl scripts (windows).
200
+ temp_dir : str | pathlib.Path, $USER$/temp/temp_melts
201
+ Temporary directory for melts file download and install.
202
+ keep_tempdir : bool, False
203
+ Whether to cache tempoary files and preserve the temporary directory.
204
+ """
205
+ system = platform.system()
206
+ release = platform.release()
207
+ version = platform.version()
208
+ bits, linkage = platform.architecture()
209
+ bits = bits[:2]
210
+
211
+ temp_dir = Path(temp_dir)
212
+
213
+ if (temp_dir / 'install.command').exists():
214
+ pass
215
+ else:
216
+ print('Downloading Melts')
217
+ if not temp_dir.exists():
218
+ temp_dir.mkdir(parents=True)
219
+ download_melts(temp_dir)
220
+
221
+ install_dir = Path(install_dir)
222
+
223
+ if not install_dir.exists():
224
+ install_dir.mkdir(parents=True)
225
+
226
+ if link_dir is not None:
227
+ link_dir = Path(link_dir)
228
+ else:
229
+ link_dir = install_dir / 'links'
230
+
231
+ if not link_dir.exists():
232
+ link_dir.mkdir(parents=True)
233
+
234
+ if eg_dir is not None:
235
+ eg_dir = Path(eg_dir)
236
+ else:
237
+ eg_dir = install_dir / 'examples'
238
+
239
+ if not eg_dir.exists():
240
+ eg_dir.mkdir(parents=True)
241
+
242
+ print("Installing to {} from {}".format(install_dir, temp_dir))
243
+ try:
244
+ if check_perl() and (not native):
245
+ """
246
+ Note: setting an install folder other than the download folder
247
+ seems to fail here.
248
+ Melts gets confused with the directory structure...
249
+ and creates .bat files which point to the wrong place
250
+ """
251
+ install_source = os.path.join(str(temp_dir), 'install.command')
252
+ args = ["perl", install_source]
253
+
254
+ # [C:\Users\<>\Documents\bin]
255
+ # [./\examples]
256
+ # use default settings file
257
+ # continue
258
+ # return to finish
259
+ inputs = ['', str(link_dir), str(eg_dir), '', 'y', '', '',]
260
+ p = subprocess.run(args,
261
+ input=('\n'.join(inputs)).encode('UTF-8'),
262
+ stdout=subprocess.PIPE)
263
+
264
+ for line in p.stdout.decode('UTF-8').split('\r\n'):
265
+ print(line)
266
+ assert p.returncode == 0
267
+
268
+ # copy files from tempdir to install_dir
269
+ regs = []#'command', 'command_auto_file', 'path', 'perl']
270
+ comms = ['column_pick', 'file_format', 'run_alphamelts']
271
+ for (prefixes, ext) in [(regs, '.reg'),
272
+ (comms, '.command')]:
273
+ for prefix in prefixes:
274
+ temp_regpath = (temp_dir / prefix).with_suffix(ext)
275
+ install_regpath = install_dir / temp_regpath.name
276
+ shutil.copy(str(temp_regpath), str(install_regpath))
277
+ elif native:
278
+
279
+ # need to split into platforms
280
+ egs = []
281
+ for g in ['*.melts', '*.txt', '*.m ']:
282
+ egs += list(temp_dir.glob(g))
283
+ comms = ['column_pick', 'file_format', 'run_alphamelts']
284
+ comms = [(temp_dir / i).with_suffix('.command') for i in comms]
285
+
286
+ files_to_copy = []
287
+ if system == 'Windows':
288
+ alphafile = temp_dir / 'alphamelts_win{}.exe'.format(bits)
289
+ bats = comms + [temp_dir / 'alphamelts']
290
+ bats = [i.with_suffix('.bat') for i in bats]
291
+ batdata = {}
292
+
293
+ for cf in comms:
294
+ batdata[cf.stem] = '''@echo off\n"{}" %*'''.format(
295
+ install_dir / cf.name)
296
+ batdata['alphamelts'] = '''@echo off\n"{}"'''.format(
297
+ install_dir / alphafile.name)
298
+ for b in bats:
299
+ with open(str(b), 'w') as fout:
300
+ fout.write(batdata[b.stem]) # dummy bats
301
+
302
+ files_to_copy += [(link_dir, bats)]
303
+
304
+ #regs = ['command', 'command_auto_file', 'path', 'perl']
305
+
306
+ elif system == 'Linux':
307
+ alphafile = temp_dir / 'alphamelts_linux{}'.format(bits)
308
+ elif system == 'Darwin':
309
+ alphafile = temp_dir / 'alphamelts_macosx{}'.format(bits)
310
+
311
+
312
+ files_to_copy += [(eg_dir, egs),
313
+ (install_dir, comms),
314
+ (install_dir, [alphafile])]
315
+ for (target, files) in files_to_copy:
316
+ for fn in files:
317
+ copy_file(temp_dir / fn.name, target / fn.name)
318
+ except AssertionError:
319
+ raise AssertionError
320
+ finally:
321
+ if not keep_tempdir:
322
+ remove_tempdir(temp_dir)
323
+
324
+
325
+ def melts_query(data_dict, url_sfx='Compute'):
326
+ """
327
+ Execute query against the MELTS web services.
328
+
329
+ Parameters
330
+ ----------
331
+ data_dict : dict
332
+ Dictionary containing data to be sent to the web query.
333
+ url_sfx : str, Compute
334
+ URL suffix to denote specific web service (Compute | Oxides | Phases).
335
+ """
336
+ try:
337
+ assert internet_connection()
338
+ url = 'http://thermofit.ofm-research.org:8080/multiMELTSWSBxApp/' + url_sfx
339
+ xmldata = dicttoxml.dicttoxml(data_dict,
340
+ custom_root='MELTSinput',
341
+ root=True,
342
+ attr_type=False)
343
+ headers = {"content-type": "text/xml",
344
+ "data-type": "xml"}
345
+ resp = requests.post(url, data=xmldata, headers=headers)
346
+ resp.raise_for_status()
347
+ result = xmljson.parker.data(ET.fromstring(resp.text))
348
+ return result
349
+ except AssertionError:
350
+ raise AssertionError('Must be connected to the internet to run query.')
351
+
352
+
353
+ def melts_compute(data_dict):
354
+ """
355
+ Execute 'Compute' query against the MELTS web services.
356
+
357
+ Parameters
358
+ ----------
359
+ data_dict : dict
360
+ Dictionary containing data to be sent to the Compute web query.
361
+ """
362
+ url_sfx = "Compute"
363
+ result = melts_query(data_dict, url_sfx=url_sfx)
364
+ assert 'Success' in result['status']
365
+ return result
366
+
367
+
368
+ def melts_oxides(data_dict):
369
+ """
370
+ Execute 'Oxides' query against the MELTS web services.
371
+
372
+ Parameters
373
+ ----------
374
+ data_dict : dict
375
+ Dictionary containing data to be sent to the Oxides web query.
376
+ """
377
+ model = data_dict['initialize'].pop('modelSelection', 'MELTS_v1.0.x')
378
+ data_dict = {'modelSelection': model}
379
+ url_sfx = "Oxides"
380
+ result = melts_query(data_dict, url_sfx=url_sfx)
381
+ return result['Oxide']
382
+
383
+
384
+ def melts_phases(data_dict):
385
+ """
386
+ Execute 'Phases' query against the MELTS web services.
387
+
388
+ Parameters
389
+ ----------
390
+ data_dict : dict
391
+ Dictionary containing data to be sent to the Phases web query.
392
+ """
393
+ model = data_dict['initialize'].pop('modelSelection', 'MELTS_v1.0.x')
394
+ data_dict = {'modelSelection': model}
395
+ url_sfx = "Phases"
396
+ result = melts_query(data_dict, url_sfx=url_sfx)
397
+ return result['Phase']
@@ -0,0 +1,29 @@
1
+ try:
2
+ from pathos.multiprocessing import ProcessingPool as Pool
3
+ except ImportError:
4
+ from multiprocessing import Pool
5
+
6
+ import logging
7
+
8
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
9
+ logger = logging.getLogger()
10
+
11
+ # Note : Using pathos multiprocessing which leverages dill over standard
12
+ # pickle, which has a hard time serializing even simple objects
13
+
14
+
15
+ def func_wrapper(arg):
16
+ func, kwargs = arg
17
+ return func(**kwargs)
18
+
19
+
20
+ def multiprocess(func, param_sets):
21
+ """
22
+ Multiprocessing utility function, targeted towards large requests.
23
+ Note that async is commonly slower for this use case.
24
+ """
25
+ jobs = [(func, params) for params in param_sets]
26
+ with Pool(processes=len(jobs)) as p:
27
+ results = p.map(func_wrapper, jobs)
28
+
29
+ return results
@@ -0,0 +1,29 @@
1
+ try:
2
+ from pathos.multiprocessing import ProcessingPool as Pool
3
+ except ImportError:
4
+ from multiprocessing import Pool
5
+
6
+ import logging
7
+
8
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
9
+ logger = logging.getLogger()
10
+
11
+ # Note : Using pathos multiprocessing which leverages dill over standard
12
+ # pickle, which has a hard time serializing even simple objects
13
+
14
+
15
+ def func_wrapper(arg):
16
+ func, kwargs = arg
17
+ return func(**kwargs)
18
+
19
+
20
+ def multiprocess(func, param_sets):
21
+ """
22
+ Multiprocessing utility function, targeted towards large requests.
23
+ Note that async is commonly slower for this use case.
24
+ """
25
+ jobs = [(func, params) for params in param_sets]
26
+ with Pool(processes=len(jobs)) as p:
27
+ results = p.map(func_wrapper, jobs)
28
+
29
+ return results
@@ -0,0 +1,214 @@
1
+ import pandas as pd
2
+ import hashlib
3
+ from functools import partial
4
+ from pathlib import Path
5
+ import numpy as np
6
+ import logging
7
+ import inspect
8
+
9
+ from .general import pathify
10
+
11
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
12
+ logger = logging.getLogger()
13
+
14
+
15
+ def test_df(cols=["SiO2", "CaO", "MgO", "FeO", "TiO2"], index_length=10):
16
+ """
17
+ Creates a pandas.DataFrame with random data.
18
+ """
19
+ return pd.DataFrame(
20
+ {k: v for k, v in zip(cols, np.random.rand(len(cols), index_length))}
21
+ )
22
+
23
+
24
+ def test_ser(index=["SiO2", "CaO", "MgO", "FeO", "TiO2"]):
25
+ """
26
+ Creates a pandas.Series with random data.
27
+ """
28
+ return pd.Series({k: v for k, v in zip(index, np.random.rand(len(index)))})
29
+
30
+
31
+ def column_ordered_append(df1, df2, **kwargs):
32
+ """
33
+ Appends one dataframe to another, preserving the column order of the
34
+ first and adding new columns on the right. Also accepts and passes on
35
+ standard keyword arguments for pd.DataFrame.append.
36
+
37
+ Parameters
38
+ ------------
39
+ df1: pd.DataFrame
40
+ The dataframe for which columns order is preserved in the output.
41
+ df2: pd.DataFrame
42
+ The dataframe for which new columns are appended to the output.
43
+
44
+ """
45
+ outcols = list(df1.columns) + [i for i in df2.columns if not i in df1.columns]
46
+ return df1.append(df2, **kwargs).reindex(columns=outcols)
47
+
48
+
49
+ def accumulate(dfs, ignore_index=False, trace_source=False, names=[]):
50
+ """
51
+ Accumulate an iterable containing pandas dataframes to a single frame.
52
+ """
53
+ acc = None
54
+ for ix, df in enumerate(dfs):
55
+ if trace_source:
56
+ if names:
57
+ df["src_idx"] = names[ix]
58
+ else:
59
+ df["src_idx"] = ix
60
+ if acc is None:
61
+ acc = df
62
+ else:
63
+ acc = column_ordered_append(acc, df, ignore_index=ignore_index)
64
+ return acc
65
+
66
+
67
+ def to_frame(df):
68
+ """
69
+ Simple utility for converting to pandas dataframes.
70
+ """
71
+
72
+ if type(df) == pd.Series: # using series instead of dataframe
73
+ df = df.to_frame().T
74
+ elif type(df) == pd.DataFrame: # 1 column slice
75
+ if df.columns.size == 1:
76
+ df = df.T
77
+ else:
78
+ msg = "Conversion from {} to dataframe not yet implemented".format(type(df))
79
+ raise NotImplementedError(msg)
80
+
81
+ return df
82
+
83
+
84
+ def to_ser(df):
85
+ """
86
+ Simple utility for converting single column pandas dataframes to series.
87
+ """
88
+ if type(df) == pd.DataFrame:
89
+ assert (df.columns.size == 1) or (
90
+ df.index.size == 1
91
+ ), """Can't convert DataFrame to Series:
92
+ either columns or index need to have size 1."""
93
+ if df.columns.size == 1:
94
+ return df.iloc[:, 0]
95
+ else:
96
+ return df.iloc[0, :]
97
+ else:
98
+ return df
99
+
100
+
101
+ def to_numeric(df, errors: str = "coerce"):
102
+ """
103
+ Takes all non-metadata columns and converts to numeric type where possible.
104
+
105
+ Notes
106
+ -----
107
+ Avoid using .loc or .iloc on the LHS to make sure that data dtypes
108
+ are propagated.
109
+ """
110
+ return df.apply(pd.to_numeric, errors=errors)
111
+
112
+
113
+ def outliers(
114
+ df,
115
+ cols=[],
116
+ detect=lambda x, quantile, qntls: (
117
+ (x > quantile.loc[qntls[0], x.name]) & (x < quantile.loc[qntls[1], x.name])
118
+ ),
119
+ quantile_select=(0.02, 0.98),
120
+ logquantile=False,
121
+ exclude=False,
122
+ ):
123
+ """
124
+ """
125
+ if not cols:
126
+ cols = df.columns
127
+ colfltr = (df.dtypes == np.float) & ([i in cols for i in df.columns])
128
+ low, high = np.min(quantile_select), np.max(quantile_select)
129
+ if not logquantile:
130
+ quantile = df.loc[:, colfltr].quantile([low, high])
131
+ else:
132
+ quantile = df.loc[:, colfltr].apply(np.log).quantile([low, high])
133
+ whereout = (
134
+ df.loc[:, colfltr]
135
+ .apply(detect, args=(quantile, quantile_select), axis=0)
136
+ .sum(axis=1)
137
+ > 0
138
+ )
139
+ if not exclude:
140
+ whereout = np.logical_not(whereout)
141
+ return df.loc[whereout, colfltr]
142
+
143
+
144
+ def concat_columns(df, columns, astype=str, **kwargs):
145
+ out = pd.Series(index=df.index, **kwargs)
146
+ for ix, c in enumerate(columns):
147
+ if ix == 0:
148
+ out = df.loc[:, c].astype(astype)
149
+ else:
150
+ out += df.loc[:, c].astype(astype)
151
+ return out
152
+
153
+
154
+ def uniques_from_concat(df, cols, hashit=True):
155
+ """
156
+ Creates ideally unique keys from multiple columns.
157
+ Optionally hashes string to standardise length of identifier.
158
+ """
159
+ if hashit:
160
+ fmt = lambda x: hashlib.md5(x.encode("UTF-8")).hexdigest()
161
+ else:
162
+ fmt = lambda x: x.encode("UTF-8")
163
+
164
+ return concat_columns(df, cols, dtype="category").apply(fmt)
165
+
166
+
167
+ def df_from_csvs(csvs, dropna=True, ignore_index=False, **kwargs):
168
+ """
169
+ Takes a list of .csv filenames and converts to a single DataFrame.
170
+ Combines columns across dataframes, preserving order of the first entered.
171
+
172
+ TODO: Attempt to preserve column ordering across column sets, assuming
173
+ they are generally in the same order but preserving only some of the
174
+ information.
175
+
176
+ E.g.
177
+ SiO2, Al2O3, MgO, MnO, CaO
178
+ SiO2, MgO, FeO, CaO
179
+ SiO2, Na2O, Al2O3, FeO, CaO
180
+ =>
181
+ SiO2, Na2O, Al2O3, MgO, FeO, MnO, CaO
182
+ - Existing neighbours take priority (i.e. FeO won't be inserted bf Al2O3)
183
+ - Earlier inputs take priority (where ordering is ambiguous, place the earlier first)
184
+ """
185
+ cols = []
186
+ dfs = []
187
+ for ix, t in enumerate(csvs):
188
+ dfs.append(pd.read_csv(t, **kwargs))
189
+ cols = cols + [i for i in dfs[-1].columns if i not in cols]
190
+
191
+ df = accumulate(dfs, ignore_index=ignore_index)
192
+ return df
193
+
194
+
195
+ def pickle_from_csvs(targets, out_filename, sep="\t", suffix=".pkl"):
196
+ df = df_from_csvs(targets, sep=sep, low_memory=False)
197
+ sparse_pickle_df(df, out_filename, suffix=suffix)
198
+
199
+
200
+ def sparse_pickle_df(df: pd.DataFrame, filename, suffix=".pkl"):
201
+ """
202
+ Converts dataframe to sparse dataframe before pickling to disk.
203
+ """
204
+ df.to_sparse().to_pickle(pathify(filename).with_suffix(suffix))
205
+
206
+
207
+ def load_sparse_pickle_df(filename, suffix=".pkl", keep_sparse=False):
208
+ """
209
+ Loads sparse dataframe from disk, with optional densification.
210
+ """
211
+ if keep_sparse:
212
+ return pd.read_pickle(pathify(filename).with_suffix(suffix))
213
+ else:
214
+ return pd.read_pickle(pathify(filename).with_suffix(suffix)).to_dense()