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,91 @@
1
+ import numpy as np
2
+ import itertools
3
+ import logging
4
+
5
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
6
+ logger = logging.getLogger()
7
+
8
+
9
+ def piecewise(segment_ranges: list, segments=2, output_fmt=np.float):
10
+ """
11
+ Generator to provide values of quantizable paramaters which define a grid,
12
+ here used to split up queries from databases to reduce load.
13
+ """
14
+ outf = np.vectorize(output_fmt)
15
+ if type(segments) == np.int:
16
+ segments = list(np.ones(len(segment_ranges), dtype=np.int) * segments)
17
+ else:
18
+ pass
19
+ seg_width = [
20
+ (x2 - x1) / segments[ix] # can have negative steps
21
+ for ix, (x1, x2) in enumerate(segment_ranges)
22
+ ]
23
+ separators = [
24
+ np.linspace(x1, x2, segments[ix] + 1)[:-1]
25
+ for ix, (x1, x2) in enumerate(segment_ranges)
26
+ ]
27
+ pieces = list(itertools.product(*separators))
28
+ for ix, i in enumerate(pieces):
29
+ i = np.array(i)
30
+ out = np.vstack((i, i + np.array(seg_width)))
31
+
32
+ yield outf(out)
33
+
34
+
35
+ def spatiotemporal_split(
36
+ segments=4,
37
+ nan_lims=[np.nan, np.nan],
38
+ # usebounds=False,
39
+ # order=['minx', 'miny', 'maxx', 'maxy'],
40
+ **kwargs
41
+ ):
42
+ """
43
+ Creates spatiotemporal grid using piecewise function and arbitrary
44
+ ranges for individial kw-parameters (e.g. age=(0., 450.)), and
45
+ sequentially returns individial grid cell attributes.
46
+ """
47
+ part = 0
48
+ for item in piecewise(kwargs.values(), segments=segments):
49
+ x1s, x2s = item
50
+ part += 1
51
+ params = {}
52
+ for vix, var in enumerate(kwargs.keys()):
53
+ vx1, vx2 = x1s[vix], x2s[vix]
54
+ params[var] = (vx1, vx2)
55
+
56
+ items = dict(
57
+ south=params.get("lat", nan_lims)[0],
58
+ north=params.get("lat", nan_lims)[1],
59
+ west=params.get("long", nan_lims)[0],
60
+ east=params.get("long", nan_lims)[1],
61
+ )
62
+ if "age" in params:
63
+ items.update(
64
+ dict(
65
+ minage=params.get("age", nan_lims)[0],
66
+ maxage=params.get("age", nan_lims)[1],
67
+ )
68
+ )
69
+
70
+ items = {k: v for (k, v) in items.items() if not np.isnan(v)}
71
+ # if usebounds:
72
+ # bounds = NSEW_2_bounds(items, order=order)
73
+ # yield bounds
74
+ # else:
75
+ yield items
76
+
77
+
78
+ def NSEW_2_bounds(cardinal, order=["minx", "miny", "maxx", "maxy"]):
79
+ """
80
+ Translates cardinal points to xy points in the form of bounds.
81
+ Useful for converting to the format required for WFS from REST
82
+ style queries.
83
+ """
84
+ tnsltr = {
85
+ xy: c
86
+ for xy, c in zip(
87
+ ["minx", "miny", "maxx", "maxy"], ["west", "south", "east", "north"]
88
+ )
89
+ }
90
+ bnds = [cardinal.get(tnsltr[o]) for o in order]
91
+ return bnds
@@ -0,0 +1,207 @@
1
+ import re
2
+ import textwrap
3
+ import numpy as np
4
+ import logging
5
+
6
+ try:
7
+ from sortedcollections import SortedSet as set
8
+ except:
9
+ pass
10
+
11
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
12
+ logger = logging.getLogger()
13
+
14
+
15
+ def to_width(multiline_string, width=79, **kwargs):
16
+ """Uses builtin textwapr for text wrapping to a specific width."""
17
+ return textwrap.fill(multiline_string, width, **kwargs)
18
+
19
+
20
+ def normalise_whitespace(strg):
21
+ """Substitutes extra tabs, newlines etc. for a single space."""
22
+ return re.sub("\s+", " ", strg).strip()
23
+
24
+
25
+ def remove_prefix(z, prefix):
26
+ """Remove a specific prefix from the start of a string."""
27
+ if z.startswith(prefix):
28
+ return re.sub("^{}".format(prefix), "", z)
29
+ else:
30
+ return z
31
+
32
+
33
+ def quoted_string(s):
34
+ # if " " in s or '-' in s or '_' in s:
35
+ s = '''"{}"'''.format(s)
36
+ return s
37
+
38
+
39
+ def titlecase(
40
+ s,
41
+ exceptions=["and", "in", "a"],
42
+ abbrv=["ID", "IGSN", "CIA", "CIW", "PIA", "SAR", "SiTiIndex", "WIP"],
43
+ capitalize_first=True,
44
+ split_on="[\s_-]+",
45
+ delim="",
46
+ ):
47
+ """
48
+ Formats strings in CamelCase, with exceptions for simple articles
49
+ and omitted abbreviations which retain their capitalization.
50
+ TODO: Option for retaining original CamelCase.
51
+ """
52
+ # Check if abbrv in string, in which case it'll need to be split first?
53
+ words = re.split(split_on, s)
54
+ out = []
55
+ first = words[0]
56
+ if capitalize_first and not (first in abbrv):
57
+ first = first.capitalize()
58
+
59
+ out.append(first)
60
+ for word in words[1:]:
61
+ if word in exceptions + abbrv:
62
+ pass
63
+ elif word.upper() in abbrv:
64
+ word = word.upper()
65
+ else:
66
+ word = word.capitalize()
67
+ out.append(word)
68
+ return delim.join(out)
69
+
70
+
71
+ def string_variations(
72
+ names,
73
+ preprocess=["lower", "strip"],
74
+ swaps=[(" ", "_"), (" ", "_"), ("-", " "), ("_", " "), ("-", ""), ("_", "")],
75
+ ):
76
+ """
77
+ Returns equilvaent string variations based on an input set of strings.
78
+
79
+ Parameters
80
+ ----------
81
+ names: {list, str}
82
+ String or list of strings to generate name variations of.
83
+ preprocess: list
84
+ List of preprocessing string functions to apply before generating
85
+ variations.
86
+ swaps: list
87
+ List of tuples for str.replace(out, in).
88
+
89
+ Returns
90
+ --------
91
+ set
92
+ Set (or SortedSet, if sortedcontainers installed) of unique string
93
+ variations.
94
+ """
95
+ vars = set()
96
+ # convert input to list if singular
97
+ if isinstance(names, str):
98
+ names = [names]
99
+
100
+ swapout = [s[0] for s in swaps]
101
+ for n in names:
102
+ n = str(n)
103
+ for p in preprocess:
104
+ n = getattr(n, p)()
105
+ vars.add(n)
106
+ if any([s in n for s in swapout]):
107
+ vars = vars.union([n.replace(*s) for s in swaps])
108
+ return vars
109
+
110
+
111
+ def parse_entry(
112
+ entry,
113
+ regex=r"(\s)*?(?P<value>[\.\w]+)(\s)*?",
114
+ delimiter=",",
115
+ values_only=True,
116
+ first_only=True,
117
+ errors=None,
118
+ replace_nan="None",
119
+ ):
120
+ """
121
+ Parses an arbitrary string data entry to return
122
+ values based on a regular expression containing
123
+ named fields including 'value' (and any others).
124
+ If the entry is of non-string type, this will
125
+ return the value (e.g. int, float, NaN, None).
126
+
127
+ Parameters
128
+ -----------------------
129
+ entry: str
130
+ String entry which to search for the regex pattern.
131
+ regex: str
132
+ Regular expression to compile and use to search the
133
+ entry for a value.
134
+ delimiter: str, ','
135
+ Optional delimiter to split the string in case of multiple
136
+ inclusion.
137
+ values_only: bool, True
138
+ Option to return only values (single or list), or to instead
139
+ return the dictionary corresponding to the matches.
140
+ first_only: bool, True
141
+ Option to return only the first match, or else all matches.
142
+
143
+ Not yet implemented:
144
+
145
+ errors: int|float|np.nan|None, None
146
+ Error value to denote 'no match'.
147
+ """
148
+
149
+ if isinstance(entry, str):
150
+ pattern = re.compile(regex)
151
+ matches = []
152
+ if not delimiter or (delimiter is None):
153
+ subparts = [entry]
154
+ else:
155
+ subparts = entry.split(delimiter)
156
+
157
+ for _l in subparts:
158
+ _m = pattern.match(_l)
159
+ if _m:
160
+ _d = dict(value=_m.group("value"))
161
+ # Add other groups
162
+ _d.update(
163
+ {
164
+ k: _m.group(k)
165
+ for (k, ind) in pattern.groupindex.items()
166
+ if not k == "value"
167
+ }
168
+ )
169
+
170
+ else:
171
+ _d = dict(value=replace_nan)
172
+ # Add other groups
173
+ _d.update(
174
+ {
175
+ k: replace_nan
176
+ for (k, ind) in pattern.groupindex.items()
177
+ if not k == "value"
178
+ }
179
+ )
180
+ matches.append(_d)
181
+
182
+ if values_only:
183
+ matches = [m["value"] for m in matches]
184
+
185
+ if first_only:
186
+ return matches[0]
187
+
188
+ return matches
189
+ else:
190
+ if entry is None:
191
+ entry = replace_nan
192
+ elif isinstance(entry, float):
193
+ if np.isnan(entry):
194
+ entry = replace_nan
195
+ if first_only:
196
+ return entry
197
+ else:
198
+ return [entry]
199
+
200
+
201
+ def split_records(data, delimiter="\r\n"):
202
+ """
203
+ Splits records in a csv where quotation marks are used.
204
+ Splits on a delimiter followed by an even number of quotation marks.
205
+ """
206
+ # https://stackoverflow.com/a/2787979
207
+ return re.split(delimiter + """(?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", data)
@@ -0,0 +1,224 @@
1
+ import pandas as pd
2
+ import numpy as np
3
+ from .general import pyrolite_datafolder
4
+ from .pd import to_frame, to_numeric
5
+ from .text import titlecase, string_variations
6
+ from .general import iscollection
7
+ from collections import ChainMap, defaultdict
8
+ import logging
9
+
10
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
11
+ logger = logging.getLogger()
12
+
13
+
14
+ __DATA__ = pyrolite_datafolder(subfolder="timescale") / "geotimescale_spans.csv"
15
+
16
+
17
+ def listify(df, axis=1):
18
+ """
19
+ Consdense text information across columns into a single list.
20
+
21
+ Parameters
22
+ ----------
23
+ df: pd.DataFrame
24
+ Dataframe (or slice of dataframe) to condense along axis.
25
+ axis: {1, 0}
26
+ Axis to condense along.
27
+ """
28
+ return df.copy(deep=True).apply(list, axis=axis)
29
+
30
+
31
+ def age_name(
32
+ agenamelist, prefixes=["Lower", "Middle", "Upper"], suffixes=["Stage", "Series"]
33
+ ):
34
+ """
35
+ Condenses an agename list to a specific agename, given a subset of
36
+ ambiguous_names.
37
+
38
+ Parameters
39
+ ----------
40
+ agenamelist: list
41
+ List of name components (i.e. [Eon, Era, Period, Epoch])
42
+ prefixes: list
43
+ Name components which occur prior to the higher order classification
44
+ (e.g. Upper Triassic).
45
+ suffixes: list
46
+ Name components which occur after the higher order classification
47
+ (e.g. Cambrian Series 2).
48
+ """
49
+ ambiguous_names = prefixes + suffixes
50
+ ambig_vars = [s.lower().strip() for s in ambiguous_names]
51
+ nameguess = agenamelist[-1]
52
+ # Process e.g. Stage 1 => Stage
53
+ nn_nameguess = "".join([i for i in nameguess if not i.isdigit()]).strip()
54
+
55
+ # check if the name guess corresponds to any of the ambiguous names
56
+ hit = [
57
+ ambiguous_names[ix]
58
+ for ix, vars in enumerate(ambig_vars)
59
+ if nn_nameguess.lower().strip() in vars
60
+ ][0:1]
61
+
62
+ if hit:
63
+ indexstart = len(agenamelist) - 1
64
+ outname = [agenamelist[indexstart]]
65
+ out_index_previous = 0
66
+ ambiguous_name = True
67
+ while ambiguous_name:
68
+ hitphrase = hit[0]
69
+ indexstart -= 1
70
+ nextup = agenamelist[indexstart]
71
+ if hitphrase in prefixes:
72
+ # insert the higher order component after the previous one
73
+ outname.insert(out_index_previous + 1, nextup)
74
+ out_index_previous += 1
75
+ else:
76
+ # insert the higher order component before the previous one
77
+ outname.insert(out_index_previous - 1, nextup)
78
+ out_index_previous -= 1
79
+
80
+ _nn_nextupguess = "".join([i for i in nextup if not i.isdigit()]).strip()
81
+ hit = [
82
+ ambiguous_names[ix]
83
+ for ix, vars in enumerate(ambig_vars)
84
+ if _nn_nextupguess.lower().strip() in vars
85
+ ][0:1]
86
+ if not hit:
87
+ ambiguous_name = False
88
+ return " ".join(outname)
89
+ else:
90
+ return nameguess
91
+
92
+
93
+ def timescale_reference_frame(filename=__DATA__, info_cols=["Start", "End", "Aliases"]):
94
+ """
95
+ Rearrange the text-based timescale dataframe. Utility function for
96
+ timescale class.
97
+
98
+ Parameters
99
+ ----------
100
+ filename: {str, pathlib.Path}
101
+ File from which to generate the timescale information.
102
+ info_cols: list
103
+ List of columns beyond hierarchial group labels (e.g. Eon, Era..).
104
+
105
+ Returns
106
+ -------
107
+ pd.DataFrame
108
+ Dataframe containing timescale information.
109
+ """
110
+
111
+ df = pd.read_csv(filename)
112
+ df.loc[:, ["Start", "End"]] = df.loc[:, ["Start", "End"]].apply(to_numeric)
113
+ _df = df.copy(deep=True)
114
+ grps = [i for i in _df.columns if not i in info_cols]
115
+ condensed = _df.loc[:, [i for i in _df.columns if not i in info_cols]].fillna(
116
+ value=""
117
+ )
118
+ _df["Level"] = condensed.apply(
119
+ lambda x: grps[[ix for ix, v in enumerate(x) if v][-1]], axis=1
120
+ )
121
+ condensed = listify(condensed).apply(lambda x: [i for i in x if i])
122
+ _df["Name"] = condensed.apply(age_name)
123
+ _df["Ident"] = condensed.apply("-".join)
124
+ _df["MeanAge"] = _df.apply(lambda x: (x.Start + x.End) / 2, axis=1)
125
+ _df["Unc"] = _df.apply(lambda x: (x.Start - x.End) / 2, axis=1)
126
+
127
+ # Aliases
128
+ _df.Aliases = _df.Aliases.apply(lambda x: [] if pd.isnull(x) else x.split(";"))
129
+ _df.Aliases = _df.apply(lambda x: [x.Name, x.Ident] + x.Aliases, axis=1)
130
+ _df.Aliases = _df.Aliases.apply(lambda x: [i.lower().strip() for i in x])
131
+
132
+ col_order = (
133
+ ["Ident", "Name", "Level", "Start", "End", "MeanAge", "Unc"]
134
+ + grps
135
+ + ["Aliases"]
136
+ )
137
+
138
+ return _df.loc[:, col_order]
139
+
140
+
141
+ class Timescale(object):
142
+ """
143
+ Geological Timescale class to provide time-focused utility functions.
144
+ """
145
+
146
+ def __init__(self, filename=None):
147
+ if filename is None:
148
+ self.data = timescale_reference_frame()
149
+ else:
150
+ self.data = timescale_reference_frame(filename)
151
+ self.levels = [i for i in self.data.Level.unique() if not pd.isnull(i)]
152
+ self.levels = [i for i in self.data.columns if i in self.levels]
153
+
154
+ def getnan():
155
+ return np.nan, np.nan
156
+
157
+ self.locate = defaultdict(getnan)
158
+ self.build()
159
+
160
+ def build(self):
161
+ for ix, g in enumerate(self.levels):
162
+ others = self.levels[ix + 1 :]
163
+ fltr = (
164
+ self.data.loc[:, others].isnull().all(axis=1)
165
+ & ~self.data.loc[:, g].isnull()
166
+ )
167
+ setattr(self, g + "s", self.data.loc[fltr, :])
168
+
169
+ dicts = self.data.apply(
170
+ lambda x: {a: (x.Start, x.End) for a in x.Aliases}, axis=1
171
+ )
172
+ # should check that the keys are unique across all of these
173
+ self.locate.update(dict(ChainMap(*dicts)))
174
+ self.data = self.data.set_index("Ident")
175
+
176
+ def text2age(self, entry, nulls=[None, "None", "none", np.nan, "NaN"]):
177
+ """
178
+ Converts a text-based age to the corresponding age range (in Ma).
179
+
180
+ String-based entries return (max_age, min_age). Collection-based entries
181
+ return a list of tuples.
182
+
183
+ Parameters
184
+ ------------
185
+ entry: str
186
+ String name, or series of string names, for geological age range.
187
+
188
+ """
189
+ try:
190
+ entry = np.float(entry)
191
+ return (entry, entry)
192
+ except:
193
+ return self.locate[entry.lower().strip()]
194
+
195
+ def named_age(self, age, level="Period"):
196
+ """
197
+ Converts a numeric age (in Ma) to named age at a specific level.
198
+
199
+ Parameters
200
+ ------------
201
+ age: float
202
+ Numeric age in Ma.
203
+ level: {'Eon', 'Era', 'Period', 'Superepoch',
204
+ 'Epoch', 'Age', 'Specific'}
205
+ Level of specificity.
206
+
207
+ Returns
208
+ ------------
209
+ str
210
+ String representation for the entry.
211
+ """
212
+
213
+ level = titlecase(level)
214
+ wthn_rng = lambda x: (age <= x.Start) & (age >= x.End)
215
+ relevant = self.data.loc[self.data.apply(wthn_rng, axis=1).values, :]
216
+ if level == "Specific": # take the rightmost grouping
217
+ relevant = relevant.loc[:, self.levels]
218
+ idx_rel_row = (~pd.isnull(relevant)).count(axis=1).idxmax()
219
+ rel_row = relevant.loc[idx_rel_row, :]
220
+ spec = rel_row[~pd.isnull(rel_row)].values[-1]
221
+ return spec
222
+ else:
223
+ relevant = relevant.loc[:, level]
224
+ return relevant.unique()[~pd.isnull(relevant.unique())][0]
@@ -0,0 +1,10 @@
1
+ from owslib.wfs import WebFeatureService
2
+ from owslib.fes import *
3
+ from owslib.etree import etree
4
+ import requests
5
+ import json, geojson
6
+ import codecs
7
+ import logging
8
+
9
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
10
+ logger = logging.getLogger()
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.1
2
+ Name: pyrolite
3
+ Version: 0.0.14
4
+ Summary: Tools for geochemical data analysis.
5
+ Home-page: https://github.com/morganjwilliams/pyrolite
6
+ Author: Morgan Williams
7
+ Author-email: morgan.williams@csiro.au
8
+ License: CSIRO Modifed MIT/BSD
9
+ Description: # `pyrolite`
10
+
11
+ <p align="left">
12
+ <a href="https://pypi.python.org/pypi/pyrolite/">
13
+ <img src="https://img.shields.io/pypi/v/pyrolite.svg" alt="PyPI"></a>
14
+ <a href="https://pyrolite.readthedocs.io/">
15
+ <img src="https://readthedocs.org/projects/pyrolite/badge/?version=latest" alt="Docs"/></a>
16
+ <a href="https://github.com/ambv/black">
17
+ <img src="https://img.shields.io/badge/code%20style-black-000000.svg"
18
+ alt="Code Style: Black"></a>
19
+ <a href="https://pypi.python.org/pypi/pyrolite/">
20
+ <img src="https://img.shields.io/pypi/pyversions/pyrolite.svg"
21
+ alt="Compatible Versions"></a>
22
+ <a href="https://github.com/morganjwilliams/pyrolite/blob/master/LICENSE" >
23
+ <img src="https://img.shields.io/badge/License-CSIRO_BSD/MIT_License-blue.svg"
24
+ alt="License: CSIRO Modified BSD/MIT License"></a>
25
+ <a href="https://saythanks.io/to/morganjwilliams">
26
+ <img src="https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg"
27
+ alt="Say Thanks"></a>
28
+ </p>
29
+
30
+ ### Install
31
+
32
+ ```bash
33
+ pip install pyrolite
34
+ ```
35
+
36
+ ### Build Status
37
+
38
+
39
+ | **master** | **develop** |
40
+ |:----------:|:-----------:|
41
+ | [![Build Status](https://travis-ci.org/morganjwilliams/pyrolite.svg?branch=master)](https://travis-ci.org/morganjwilliams/pyrolite) | [![Build Status](https://travis-ci.org/morganjwilliams/pyrolite.svg?branch=develop)](https://travis-ci.org/morganjwilliams/pyrolite) |
42
+ | [![Coverage Status](https://coveralls.io/repos/github/morganjwilliams/pyrolite/badge.svg?branch=master)](https://coveralls.io/github/morganjwilliams/pyrolite?branch=master) | [![Coverage Status](https://coveralls.io/repos/github/morganjwilliams/pyrolite/badge.svg?branch=develop)](https://coveralls.io/github/morganjwilliams/pyrolite?branch=develop) |
43
+
44
+ **Maintainer**: Morgan Williams (morgan.williams _at_ csiro.au)
45
+
46
+ Platform: UNKNOWN
47
+ Classifier: Development Status :: 3 - Alpha
48
+ Classifier: Intended Audience :: Science/Research
49
+ Classifier: Natural Language :: English
50
+ Classifier: Programming Language :: Python :: 3 :: Only
51
+ Classifier: Programming Language :: Python :: 3.5
52
+ Classifier: Programming Language :: Python :: 3.6
53
+ Classifier: Programming Language :: Python :: 3.7
54
+ Classifier: Topic :: Scientific/Engineering
55
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
56
+ Description-Content-Type: text/markdown
57
+ Provides-Extra: skl
58
+ Provides-Extra: spatial
59
+ Provides-Extra: dev
60
+ Provides-Extra: db
61
+ Provides-Extra: impute
@@ -0,0 +1,83 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ setup.cfg
5
+ setup.py
6
+ versioneer.py
7
+ pyrolite/__init__.py
8
+ pyrolite/_version.py
9
+ pyrolite/alteration.py
10
+ pyrolite/classification.py
11
+ pyrolite/geochem.py
12
+ pyrolite/norm.py
13
+ pyrolite/plot.py
14
+ pyrolite.egg-info/PKG-INFO
15
+ pyrolite.egg-info/SOURCES.txt
16
+ pyrolite.egg-info/dependency_links.txt
17
+ pyrolite.egg-info/requires.txt
18
+ pyrolite.egg-info/top_level.txt
19
+ pyrolite/comp/__init__.py
20
+ pyrolite/comp/aggregate.py
21
+ pyrolite/comp/codata.py
22
+ pyrolite/comp/impute.py
23
+ pyrolite/data/georoc/contents.json
24
+ pyrolite/data/melts/env.py
25
+ pyrolite/data/melts/__pycache__/env.cpython-35.pyc
26
+ pyrolite/data/melts/__pycache__/env.cpython-36.pyc
27
+ pyrolite/data/models/TAS.clsf.gz
28
+ pyrolite/data/models/aphanitic.clsf.gz
29
+ pyrolite/data/models/gabbroic.clsf.gz
30
+ pyrolite/data/models/peralkalinity.clsf.gz
31
+ pyrolite/data/models/phaneritic.clsf.gz
32
+ pyrolite/data/models/ultramafic.clsf.gz
33
+ pyrolite/data/models/TAS/TAS.Ba.modelfield
34
+ pyrolite/data/models/TAS/TAS.Bs.modelfield
35
+ pyrolite/data/models/TAS/TAS.F.modelfield
36
+ pyrolite/data/models/TAS/TAS.O1.modelfield
37
+ pyrolite/data/models/TAS/TAS.O2.modelfield
38
+ pyrolite/data/models/TAS/TAS.O3.modelfield
39
+ pyrolite/data/models/TAS/TAS.Pc.modelfield
40
+ pyrolite/data/models/TAS/TAS.Ph.modelfield
41
+ pyrolite/data/models/TAS/TAS.R.modelfield
42
+ pyrolite/data/models/TAS/TAS.S1.modelfield
43
+ pyrolite/data/models/TAS/TAS.S2.modelfield
44
+ pyrolite/data/models/TAS/TAS.S3.modelfield
45
+ pyrolite/data/models/TAS/TAS.T1.modelfield
46
+ pyrolite/data/models/TAS/TAS.T2.modelfield
47
+ pyrolite/data/models/TAS/TAS.U1.modelfield
48
+ pyrolite/data/models/TAS/TAS.U2.modelfield
49
+ pyrolite/data/models/TAS/TAS.U3.modelfield
50
+ pyrolite/data/models/TAS/TAS.modelfields
51
+ pyrolite/data/models/TAS/TAS.nan.modelfield
52
+ pyrolite/data/models/TAS/TAS.none.modelfield
53
+ pyrolite/data/refcomp/CH_PalmeONeill2014.csv
54
+ pyrolite/data/refcomp/DDMM_WorkmanHart2005.csv
55
+ pyrolite/data/refcomp/DMM_WorkmanHart2005.csv
56
+ pyrolite/data/refcomp/DM_SaltersStrake2004.csv
57
+ pyrolite/data/refcomp/EDMM_WorkmanHart2005.csv
58
+ pyrolite/data/refcomp/PM_PalmeONeill2014.csv
59
+ pyrolite/data/timescale/geotimescale_spans.csv
60
+ pyrolite/mineral/__init__.py
61
+ pyrolite/mineral/db.py
62
+ pyrolite/mineral/ions.py
63
+ pyrolite/mineral/mineral.py
64
+ pyrolite/mineral/sites.py
65
+ pyrolite/util/__init__.py
66
+ pyrolite/util/database.py
67
+ pyrolite/util/env.py
68
+ pyrolite/util/general.py
69
+ pyrolite/util/georoc.py
70
+ pyrolite/util/math.py
71
+ pyrolite/util/multip.py
72
+ pyrolite/util/pd.py
73
+ pyrolite/util/plot.py
74
+ pyrolite/util/skl.py
75
+ pyrolite/util/spatial.py
76
+ pyrolite/util/text.py
77
+ pyrolite/util/time.py
78
+ pyrolite/util/wfs.py
79
+ test/test_alteration.py
80
+ test/test_classification.py
81
+ test/test_geochem.py
82
+ test/test_norm.py
83
+ test/test_plot.py