apsg 1.3.0__py3-none-any.whl → 1.3.2__py3-none-any.whl

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.
apsg/__init__.py CHANGED
@@ -1,6 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- import importlib.metadata
4
3
  from apsg.math import (
5
4
  Vector3 as vec,
6
5
  Vector2 as vec2,
@@ -99,6 +98,6 @@ __all__ = (
99
98
  "quicknet",
100
99
  )
101
100
 
102
- __version__ = importlib.metadata.version("apsg")
101
+ __version__ = "1.3.2"
103
102
  __author__ = "Ondrej Lexa"
104
103
  __email__ = "lexa.ondrej@gmail.com"
apsg/database/_alchemy.py CHANGED
@@ -13,7 +13,17 @@ from apsg.feature._container import LineationSet, FoliationSet
13
13
 
14
14
  from sqlalchemy import create_engine, event
15
15
  from sqlalchemy.orm import sessionmaker
16
- from sqlalchemy import Column, Float, ForeignKey, Integer, String, Table, Text, text
16
+ from sqlalchemy import (
17
+ Column,
18
+ Float,
19
+ ForeignKey,
20
+ Integer,
21
+ String,
22
+ Table,
23
+ Text,
24
+ text,
25
+ UniqueConstraint,
26
+ )
17
27
  from sqlalchemy.orm import relationship
18
28
  from sqlalchemy.ext.declarative import declarative_base
19
29
 
@@ -24,24 +34,31 @@ metadata = Base.metadata
24
34
  class Meta(Base):
25
35
  __tablename__ = "meta"
26
36
 
27
- id = Column(Integer, primary_key=True)
37
+ id = Column(Integer, primary_key=True, autoincrement=True)
28
38
  name = Column(String(16), nullable=False)
29
39
  value = Column(Text)
30
40
 
41
+ def __repr__(self):
42
+ return "Meta:{}={}".format(self.name, self.value)
43
+
31
44
 
32
45
  class Site(Base):
33
46
  __tablename__ = "sites"
34
47
 
35
- id = Column(Integer, primary_key=True)
48
+ id = Column(Integer, primary_key=True, autoincrement=True)
36
49
  id_units = Column(ForeignKey("units.id"), nullable=False, index=True)
37
- name = Column(String(16), nullable=False, server_default=text("''"))
50
+ name = Column(String(16), nullable=False)
38
51
  x_coord = Column(Float, server_default=text("NULL"))
39
52
  y_coord = Column(Float, server_default=text("NULL"))
40
53
  description = Column(Text)
41
54
 
42
- unit = relationship("Unit", back_populates="sites")
55
+ unit = relationship("Unit", back_populates="sites", cascade="save-update")
43
56
 
44
- structdata = relationship("Structdata", back_populates="site")
57
+ structdata = relationship(
58
+ "Structdata", back_populates="site", cascade="all, delete-orphan"
59
+ )
60
+
61
+ __table_args__ = (UniqueConstraint("name", name="_site_name_uc"),)
45
62
 
46
63
  def __repr__(self):
47
64
  return "Site:{} ({})".format(self.name, self.unit.name)
@@ -50,16 +67,22 @@ class Site(Base):
50
67
  tagged = Table(
51
68
  "tagged",
52
69
  metadata,
53
- Column("id", Integer, autoincrement=True),
54
- Column("id_tags", Integer, ForeignKey("tags.id"), primary_key=True),
55
- Column("id_structdata", Integer, ForeignKey("structdata.id"), primary_key=True),
70
+ Column("id", Integer, primary_key=True, autoincrement=True),
71
+ Column("id_tags", Integer, ForeignKey("tags.id"), nullable=False, index=True),
72
+ Column(
73
+ "id_structdata",
74
+ Integer,
75
+ ForeignKey("structdata.id"),
76
+ nullable=False,
77
+ index=True,
78
+ ),
56
79
  )
57
80
 
58
81
 
59
82
  class Attached(Base):
60
83
  __tablename__ = "attach"
61
84
 
62
- id = Column(Integer, primary_key=True)
85
+ id = Column(Integer, primary_key=True, autoincrement=True)
63
86
  id_structdata_planar = Column(
64
87
  ForeignKey("structdata.id"), nullable=False, index=True
65
88
  )
@@ -74,7 +97,7 @@ class Attached(Base):
74
97
  class Structdata(Base):
75
98
  __tablename__ = "structdata"
76
99
 
77
- id = Column(Integer, primary_key=True)
100
+ id = Column(Integer, primary_key=True, autoincrement=True)
78
101
  id_sites = Column(ForeignKey("sites.id"), nullable=False, index=True)
79
102
  id_structype = Column(ForeignKey("structype.id"), nullable=False, index=True)
80
103
  azimuth = Column(Float, nullable=False, server_default=text("0"))
@@ -82,9 +105,13 @@ class Structdata(Base):
82
105
  description = Column(Text)
83
106
 
84
107
  site = relationship("Site", back_populates="structdata")
85
- structype = relationship("Structype", back_populates="structdata")
108
+ structype = relationship(
109
+ "Structype", back_populates="structdata", cascade="save-update"
110
+ )
86
111
 
87
- tags = relationship("Tag", secondary=tagged, back_populates="structdata")
112
+ tags = relationship(
113
+ "Tag", secondary=tagged, back_populates="structdata", cascade="save-update"
114
+ )
88
115
 
89
116
  attach_planar = relationship(
90
117
  "Attached", backref="planar", primaryjoin=id == Attached.id_structdata_planar
@@ -102,7 +129,7 @@ class Structdata(Base):
102
129
  class Structype(Base):
103
130
  __tablename__ = "structype"
104
131
 
105
- id = Column(Integer, primary_key=True)
132
+ id = Column(Integer, primary_key=True, autoincrement=True)
106
133
  pos = Column(Integer, nullable=False, server_default=text("0"))
107
134
  structure = Column(String(16), nullable=False)
108
135
  description = Column(Text)
@@ -112,6 +139,8 @@ class Structype(Base):
112
139
 
113
140
  structdata = relationship("Structdata", back_populates="structype")
114
141
 
142
+ __table_args__ = (UniqueConstraint("structure", name="_structype_structure_uc"),)
143
+
115
144
  def __repr__(self):
116
145
  return "Type:{}".format(self.structure)
117
146
 
@@ -119,13 +148,15 @@ class Structype(Base):
119
148
  class Tag(Base):
120
149
  __tablename__ = "tags"
121
150
 
122
- id = Column(Integer, primary_key=True)
151
+ id = Column(Integer, primary_key=True, autoincrement=True)
123
152
  pos = Column(Integer, nullable=False, server_default=text("0"))
124
153
  name = Column(String(16), nullable=False)
125
154
  description = Column(Text)
126
155
 
127
156
  structdata = relationship("Structdata", secondary=tagged, back_populates="tags")
128
157
 
158
+ __table_args__ = (UniqueConstraint("name", name="_tag_name_uc"),)
159
+
129
160
  def __repr__(self):
130
161
  return "Tag:{}".format(self.name)
131
162
 
@@ -133,13 +164,15 @@ class Tag(Base):
133
164
  class Unit(Base):
134
165
  __tablename__ = "units"
135
166
 
136
- id = Column(Integer, primary_key=True)
167
+ id = Column(Integer, primary_key=True, autoincrement=True)
137
168
  pos = Column(Integer, nullable=False, server_default=text("0"))
138
169
  name = Column(String(60), nullable=False)
139
170
  description = Column(Text)
140
171
 
141
172
  sites = relationship("Site", back_populates="unit")
142
173
 
174
+ __table_args__ = (UniqueConstraint("name", name="_unit_name_uc"),)
175
+
143
176
  def __repr__(self):
144
177
  return "Unit:{}".format(self.name)
145
178
 
@@ -203,7 +236,8 @@ class SDBSession:
203
236
  Keyword Args:
204
237
  create (bool): if True existing sdbfile will be deleted
205
238
  and new database will be created
206
- autocommit(bool): if True, each operation is autocommitted
239
+ autocommit(bool): if True, each operation is autocommitted.
240
+ Default False
207
241
 
208
242
  Example:
209
243
  >>> db = SDBSession('database.sdb', create=True)
@@ -277,7 +311,7 @@ class SDBSession:
277
311
 
278
312
  def meta(self, name, **kwargs):
279
313
  """
280
- Insert, update or retrieve (when kwargs empty) Meta
314
+ Query Meta when no kwargs or insert/update when kwargs provided
281
315
 
282
316
  Args:
283
317
  name (str): meta name
@@ -301,7 +335,7 @@ class SDBSession:
301
335
 
302
336
  def site(self, name, **kwargs):
303
337
  """
304
- Insert, update or retrieve (when kwargs empty) Site
338
+ Query Site when no kwargs or insert/update when kwargs provided
305
339
 
306
340
  Args:
307
341
  name (str): site name
@@ -328,7 +362,7 @@ class SDBSession:
328
362
 
329
363
  def unit(self, name, **kwargs):
330
364
  """
331
- Insert, update or retrieve (when kwargs empty) Unit
365
+ Query Unit when no kwargs or insert/update when kwargs provided
332
366
 
333
367
  Args:
334
368
  name (str): unit name
@@ -352,7 +386,7 @@ class SDBSession:
352
386
 
353
387
  def tag(self, name, **kwargs):
354
388
  """
355
- Insert, update or retrieve (when kwargs empty) Tag
389
+ Query Tag when no kwargs or insert/update when kwargs provided
356
390
 
357
391
  Args:
358
392
  name (str): tag name
@@ -376,14 +410,14 @@ class SDBSession:
376
410
 
377
411
  def structype(self, structure, **kwargs):
378
412
  """
379
- Insert, update or retrieve (when kwargs empty) Structype
413
+ Query Structype when no kwargs or insert/update when kwargs provided
380
414
 
381
415
  Args:
382
- structure (str): label for structure
416
+ structure (str): label used for structure
383
417
 
384
418
  Keyword Args:
385
- description (str): structype description
386
- planar (int): 1 for planar 0 for linear
419
+ description (str): Structype description
420
+ planar (int): 1 for planar 0 for linear Structype
387
421
  structcode (int): structcode (optional)
388
422
  groupcode (int): groupcode (optional)
389
423
 
@@ -405,11 +439,11 @@ class SDBSession:
405
439
 
406
440
  def add_structdata(self, site, structype, azimuth, inclination, **kwargs):
407
441
  """
408
- Add structdata to site
442
+ Add structural measurement to site
409
443
 
410
444
  Args:
411
- site (Site): site instance
412
- structype (Structype): structype instance
445
+ site (Site): Site instance
446
+ structype (Structype): Structype instance
413
447
  azimuth (float): dip direction or plunge direction
414
448
  inclination (float): dip or plunge
415
449
 
@@ -437,9 +471,9 @@ class SDBSession:
437
471
  Add Foliation to site
438
472
 
439
473
  Args:
440
- site (Site): site instance
441
- structype (Structype): structype instance
442
- fol (Foliation): foliation instance
474
+ site (Site): Site instance
475
+ structype (Structype): Structype instance
476
+ fol (Foliation): Foliation instance
443
477
 
444
478
  Keyword Args:
445
479
  description (str): structdata description
@@ -460,9 +494,9 @@ class SDBSession:
460
494
  Add Lineation to site
461
495
 
462
496
  Args:
463
- site (Site): site instance
464
- structype (Structype): structype instance
465
- lin (Lineation): lineation instance
497
+ site (Site): Site instance
498
+ structype (Structype): Structype instance
499
+ lin (Lineation): Lineation instance
466
500
 
467
501
  Keyword Args:
468
502
  description (str): structdata description
@@ -478,47 +512,50 @@ class SDBSession:
478
512
  azimuth, inclination = lin.geo
479
513
  return self.add_structdata(site, structype, azimuth, inclination, **kwargs)
480
514
 
481
- def attach(self, fol, lin):
515
+ def attach(self, planar, linear):
482
516
  """
483
- Add Lineation to site
517
+ Attach Foliation to Lineation
484
518
 
485
519
  Args:
486
- fol (Foliation): foliation instance
487
- lin (Lineation): lineation instance
520
+ planar (Structdata): planar Structdata
521
+ linear (Structdata): linear Structdata
488
522
 
489
523
  Returns:
490
524
  Attached
491
525
 
492
526
  """
493
- pair = Attached(planar=fol, linear=lin)
527
+ assert planar.structype.planar == 1, "First argument must be planar Structdata"
528
+ assert linear.structype.planar == 0, "Second argument must be linear Structdata"
529
+ pair = Attached(planar=planar, linear=linear)
494
530
  self.session.add(pair)
495
531
  if self.autocommit:
496
532
  self.commit()
497
533
  return pair
498
534
 
499
- def add_pair(self, pair, foltype, lintype, **kwargs):
535
+ def add_pair(self, site, foltype, lintype, pair, **kwargs):
500
536
  """
501
- Add attached foliation and lineation to database
537
+ Add attached foliation and lineation to database. Note that
538
+ measurements of foliation and lineation are corrected.
502
539
 
503
540
  Args:
504
- pair (Pair): pair instance
541
+ site (Site): site instance
505
542
  foltype (Structype): structype instance
506
543
  lintype (Structype): structype instance
544
+ pair (Pair): Pair instance
507
545
 
508
546
  Returns:
509
547
  Attached
510
548
 
511
549
  """
512
550
  assert isinstance(pair, Pair), "pair argument must be instance of Pair class"
513
- kwargs["structype"] = foltype
514
- fol = self.add_fol(pair.fol, **kwargs)
515
- kwargs["structype"] = lintype
516
- lin = self.add_lin(pair.lin, **kwargs)
551
+ fol = self.add_fol(site, foltype, pair.fol, **kwargs)
552
+ lin = self.add_lin(site, lintype, pair.lin, **kwargs)
517
553
  return self.attach(fol, lin)
518
554
 
519
555
  def sites(self, **kwargs):
520
556
  """
521
- Retrieve Site or list of Sites based on criteria in kwargs
557
+ Retrieve list of Site instances filtered by kwargs. If query results
558
+ in single site, instance of Site is returned.
522
559
 
523
560
  Keyword arguments are passed to sqlalchemy filter_by method
524
561
  """
@@ -533,7 +570,8 @@ class SDBSession:
533
570
 
534
571
  def units(self, **kwargs):
535
572
  """
536
- Retrieve Unit or list of Units based on criteria in kwargs
573
+ Retrieve list of Unit instances filtered by kwargs. If query results
574
+ in single unit, instance of Unit is returned.
537
575
 
538
576
  Keyword arguments are passed to sqlalchemy filter_by method
539
577
  """
@@ -548,7 +586,8 @@ class SDBSession:
548
586
 
549
587
  def structypes(self, **kwargs):
550
588
  """
551
- Retrieve Structype or list of Structypes based on criteria in kwargs
589
+ Retrieve list of Structype instances filtered by kwargs. If query results
590
+ in single structural type, instance of Structype is returned.
552
591
 
553
592
  Keyword arguments are passed to sqlalchemy filter_by method
554
593
  """
@@ -563,7 +602,8 @@ class SDBSession:
563
602
 
564
603
  def tags(self, **kwargs):
565
604
  """
566
- Retrieve Tag or list of Tags based on criteria in kwargs
605
+ Retrieve list of Tag instances filtered by kwargs. If query results
606
+ in single tag, instance of Tag is returned.
567
607
 
568
608
  Keyword arguments are passed to sqlalchemy filter_by method
569
609
  """
@@ -589,14 +629,14 @@ class SDBSession:
589
629
  structypes = (
590
630
  self.session.query(Structype).filter_by(structure=structype).all()
591
631
  )
592
- assert len(structypes) == 1, f"There is no structure {structype} in db"
632
+ assert len(structypes) == 1, f"There is no structure {structype} in db."
593
633
  structype = structypes[0]
594
634
  data = (
595
635
  self.session.query(Structdata)
596
636
  .filter_by(structype=structype, **kwargs)
597
637
  .all()
598
638
  )
599
- if structype.planar:
639
+ if structype.planar == 1:
600
640
  res = FoliationSet(
601
641
  [Foliation(v.azimuth, v.inclination) for v in data],
602
642
  name=structype.structure,
@@ -206,8 +206,7 @@ class StereoGrid:
206
206
  dcgrid = np.asarray(self.grid).T
207
207
  X, Y = self.proj.project_data(*dcgrid, clip_inside=False)
208
208
  cf = ax.tricontourf(X, Y, self.values, **parsed)
209
- for collection in cf.collections:
210
- collection.set_clip_path(primitive)
209
+ cf.set_clip_path(primitive)
211
210
  ax.set_xlim(-1.05, 1.05)
212
211
  ax.set_ylim(-1.05, 1.05)
213
212
  if colorbar:
@@ -249,15 +248,14 @@ class StereoGrid:
249
248
  radius=1,
250
249
  edgecolor="black",
251
250
  fill=False,
252
- clip_box="None",
251
+ clip_box=None,
253
252
  label="_nolegend_",
254
253
  )
255
254
  ax.add_patch(primitive)
256
255
  dcgrid = np.asarray(self.grid).T
257
256
  X, Y = self.proj.project_data(*dcgrid, clip_inside=False)
258
257
  cf = ax.tricontour(X, Y, self.values, **parsed)
259
- for collection in cf.collections:
260
- collection.set_clip_path(primitive)
258
+ cf.set_clip_path(primitive)
261
259
  if colorbar:
262
260
  fig.colorbar(cf, ax=ax, shrink=0.6)
263
261
  plt.show()
@@ -281,7 +279,7 @@ class StereoGrid:
281
279
  radius=1,
282
280
  edgecolor="black",
283
281
  fill=False,
284
- clip_box="None",
282
+ clip_box=None,
285
283
  label="_nolegend_",
286
284
  )
287
285
  ax.add_patch(primitive)
@@ -901,16 +901,14 @@ class StereoNet:
901
901
  dcgrid = np.asarray(self.grid.grid).T
902
902
  X, Y = self.proj.project_data(*dcgrid, clip_inside=False)
903
903
  cf = self.ax.tricontourf(X, Y, self.grid.values, **kwargs)
904
- for collection in cf.collections:
905
- collection.set_clip_path(self.primitive)
904
+ cf.set_clip_path(self.primitive)
906
905
  if clines:
907
906
  kwargs["cmap"] = None
908
907
  kwargs["colors"] = "k"
909
908
  kwargs["linewidths"] = linewidths
910
909
  kwargs["linestyles"] = linestyles
911
910
  cl = self.ax.tricontour(X, Y, self.grid.values, **kwargs)
912
- for collection in cl.collections:
913
- collection.set_clip_path(self.primitive)
911
+ cl.set_clip_path(self.primitive)
914
912
  if show_data:
915
913
  artist = StereoNetArtistFactory.create_point(*args[0], **data_kws)
916
914
  self._line(*artist.args, **artist.kwargs)
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ APSG - The package for structural geologists.
4
+ Copyright (c) 2015-2024, Ondrej Lexa
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.2
2
+ Name: apsg
3
+ Version: 1.3.2
4
+ Summary: APSG - The package for structural geologists
5
+ Author-email: Ondrej Lexa <lexa.ondrej@gmail.com>
6
+ Maintainer-email: Ondrej Lexa <lexa.ondrej@gmail.com>
7
+ License: MIT License
8
+
9
+ APSG - The package for structural geologists.
10
+ Copyright (c) 2015-2024, Ondrej Lexa
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+
30
+ Project-URL: Homepage, https://github.com/ondrolexa/apsg
31
+ Project-URL: Documentation, https://apsg.readthedocs.io
32
+ Project-URL: Repository, https://github.com/ondrolexa/apsg.git
33
+ Project-URL: Issues, https://github.com/ondrolexa/apsg/issues
34
+ Project-URL: Changelog, https://github.com/ondrolexa/apsg/blob/master/CHANGELOG.md
35
+ Keywords: structural geology,stereonet,orientation data
36
+ Classifier: Development Status :: 4 - Beta
37
+ Classifier: Intended Audience :: Science/Research
38
+ Classifier: License :: OSI Approved :: MIT License
39
+ Classifier: Operating System :: OS Independent
40
+ Classifier: Programming Language :: Python :: 3
41
+ Requires-Python: >=3.10
42
+ Description-Content-Type: text/markdown
43
+ License-File: LICENSE
44
+ Requires-Dist: numpy
45
+ Requires-Dist: matplotlib>=3.9
46
+ Requires-Dist: scipy
47
+ Requires-Dist: sqlalchemy
48
+ Requires-Dist: pandas
49
+ Provides-Extra: extra
50
+ Requires-Dist: jupyterlab; extra == "extra"
51
+ Requires-Dist: pyqt5; extra == "extra"
52
+ Provides-Extra: tests
53
+ Requires-Dist: pytest; extra == "tests"
54
+ Provides-Extra: docs
55
+ Requires-Dist: sphinx; extra == "docs"
56
+ Requires-Dist: sphinx_rtd_theme; extra == "docs"
57
+ Requires-Dist: readthedocs-sphinx-search; extra == "docs"
58
+ Requires-Dist: ipykernel; extra == "docs"
59
+ Requires-Dist: nbsphinx; extra == "docs"
60
+ Requires-Dist: autodocsumm; extra == "docs"
61
+ Provides-Extra: dev
62
+ Requires-Dist: pytest; extra == "dev"
63
+ Requires-Dist: black; extra == "dev"
64
+ Requires-Dist: sphinx; extra == "dev"
65
+ Requires-Dist: sphinx_rtd_theme; extra == "dev"
66
+ Requires-Dist: readthedocs-sphinx-search; extra == "dev"
67
+ Requires-Dist: ipykernel; extra == "dev"
68
+ Requires-Dist: nbsphinx; extra == "dev"
69
+ Requires-Dist: autodocsumm; extra == "dev"
70
+
71
+ <img src="https://ondrolexa.github.io/apsg/apsg_banner.svg" alt="APSG logo" width="300px"/>
72
+
73
+ [![PyPI - Version](https://img.shields.io/pypi/v/apsg)](https://pypi.org/project/apsg)
74
+ [![Conda](https://img.shields.io/conda/v/conda-forge/apsg)](https://anaconda.org/conda-forge/apsg)
75
+ [![Documentation Status](https://readthedocs.org/projects/apsg/badge/?version=stable)](https://apsg.readthedocs.io/en/stable/?badge=stable)
76
+ [![DOI](https://zenodo.org/badge/24879346.svg)](https://zenodo.org/badge/latestdoi/24879346)
77
+
78
+ ## :thinking: What is APSG?
79
+
80
+ APSG is the package for structural geologists. It defines several new python classes to easily manage, analyze and visualize orientational structural geology data.
81
+
82
+ > [!IMPORTANT]
83
+ > APSG has been significantly refactored from version 1.0 and several changes are
84
+ > breaking backward compatibility. The main APSG namespace provides often-used
85
+ > classes in lowercase names as aliases to `PascalCase` convention used in
86
+ > modules to provide a simplified interface for users. The `PascalCase` names of
87
+ > classes use longer and plain English names instead acronyms for better readability.
88
+ >
89
+ > Check [documentation](https://apsg.readthedocs.org) for more details.
90
+
91
+ ## :hammer_and_wrench: Requirements
92
+
93
+ You need Python 3.9 or later to run APSG. The package requires [NumPy](https://numpy.org/) and [SciPy](https://www.scipy.org/),
94
+ [Matplotlib](https://matplotlib.org/), [SciPy](https://scipy.org/), [SQLAlchemy](https://www.sqlalchemy.org/)
95
+ and [pandas](https://pandas.pydata.org/).
96
+
97
+ ## :rocket: How to install
98
+
99
+ It is strongly suggested to install **apsg** into separate environment. You can create
100
+ Python virtual environment. For Linux and macOS use:
101
+
102
+ python -m venv .venv
103
+ source .venv/bin/activate
104
+
105
+ for Windows use Command Prompt or PowerShell:
106
+
107
+ python -m venv .venv
108
+ .venv\Scripts\activate
109
+
110
+ > [!NOTE]
111
+ > On Microsoft Windows, it may be required to set the execution policy in PowerShell for the user.
112
+ > You can do this by issuing the following PowerShell command:
113
+ > ```
114
+ > Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
115
+ > ```
116
+
117
+ and install latest stable version of **apsg** using pip within the environment:
118
+
119
+ pip install apsg
120
+
121
+ To include jupyterlab and pyqt5 in installation, use `extra` option:
122
+
123
+ ## I'm using conda or mamba to manage environments
124
+
125
+ pip install apsg[extra]
126
+
127
+ or install **master** with:
128
+
129
+ pip install git+https://github.com/ondrolexa/apsg.git
130
+
131
+ Alternatively, you can clone the repository and do a local install (recommended for dev):
132
+ git clone https://github.com/ondrolexa/apsg.git
133
+ cd apsg
134
+ pip install -e .[dev]
135
+
136
+ #### Upgrading via pip
137
+
138
+ To upgrade an existing version of APSG from PyPI, execute:
139
+
140
+ pip install apsg --upgrade --no-deps
141
+
142
+ #### Comments on system-wide instalations on Debian systems
143
+
144
+ Latest Debian-based systems does not allow to install non-debian packages system-wide.
145
+ However, installing all requirements allows to force install APSG system-wide without troubles.
146
+
147
+ Install requirements using apt:
148
+
149
+ sudo apt install python3-numpy python3-matplotlib python3-scipy python3-sqlalchemy python3-pandas
150
+
151
+ and then install apsg using pip:
152
+
153
+ pip install --break-system-packages apsg
154
+
155
+ ### I'm using conda or mamba to manage environments
156
+
157
+ If you have already have conda or mamba installed, you can create environment with:
158
+
159
+ conda config --add channels conda-forge
160
+ conda create -n apsg python apsg jupyterlab pyqt
161
+
162
+ or using mamba
163
+
164
+ mamba create -n apsg python apsg jupyterlab pyqt
165
+
166
+ #### Current release info
167
+
168
+ | Name | Downloads | Version | Platforms |
169
+ | --- | --- | --- | --- |
170
+ | [![Conda Recipe](https://img.shields.io/badge/recipe-apsg-green.svg)](https://anaconda.org/conda-forge/apsg) | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/apsg.svg)](https://anaconda.org/conda-forge/apsg) | [![Conda Version](https://img.shields.io/conda/vn/conda-forge/apsg.svg)](https://anaconda.org/conda-forge/apsg) | [![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/apsg.svg)](https://anaconda.org/conda-forge/apsg) |
171
+
172
+ ## :blue_book: Documentation
173
+
174
+ Explore all the features of APSG. You can find detailed documentation [here](https://apsg.readthedocs.org).
175
+
176
+ ## :computer: Contributing
177
+
178
+ Most discussion happens on [Github](https://github.com/ondrolexa/apsg). Feel free to open [an issue](https://github.com/ondrolexa/apsg/issues/new) or comment on any open issue or pull request. Check ``CONTRIBUTING.md`` for more details.
179
+
180
+ ## :coin: Donate
181
+
182
+ APSG is an open-source project, available for you for free. It took a lot of time and resources to build this software. If you find this software useful and want to support its future development please consider donating me.
183
+
184
+ [![Donate via PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=QTYZWVUNDUAH8&item_name=APSG+development+donation&currency_code=EUR&source=url)
185
+
186
+ ## License
187
+
188
+ APSG is free software: you can redistribute it and/or modify it under the terms of the MIT License. A copy of this license is provided in ``LICENSE`` file.
@@ -1,10 +1,8 @@
1
- AUTHORS.md,sha256=OEu_2jVMx1fm5EOj4vBlI04uvX4P2sqjPYP12VjPIcI,130
2
- CHANGELOG.md,sha256=J5hRiMVHG88UP13uHGW-ljdNtFO2M4OdRRb9vNVwDrE,10217
3
- CONTRIBUTING.md,sha256=pcfp26JziGDVX-drzjXjkISUmkXyw_yxarJTS4FFqbI,2975
4
- apsg/__init__.py,sha256=HVGqE7LcE48TQc_mJpgKbKpfBB-gwWhvWgHxQjckVM4,2019
1
+ apsg/__init__.py,sha256=0HF522QDBElQju1ab_cwS3U0p00ZRfvzITYnTBRNDa4,1966
5
2
  apsg/config.py,sha256=X3_yXT96xXlVxFA94EfYFKJbrcGIHT0PvB9s8EKmYOg,4569
3
+ apsg/shell.py,sha256=UFIOy01KckLsOlqfB0UomyWZ1ITL36-lBUFhlxWdZLE,718
6
4
  apsg/database/__init__.py,sha256=7Rvcf1KBBBNhoM28ZlvQ01CkScQTroFkoS4d1kD55Ws,315
7
- apsg/database/_alchemy.py,sha256=nxHsUKfO-UvnVWqyLVRt0QfDYUQJOjOy3Wgr87lq97E,18281
5
+ apsg/database/_alchemy.py,sha256=cs8un4RJwUoE62GOberiTIQ2akFXYM0FoR-f1h4_DW8,19726
8
6
  apsg/database/_sdbread.py,sha256=Gzj0bpp0vnMvCfxIuX6Ktf01LoQWDCOcXST7HZp_XTY,10868
9
7
  apsg/decorator/__init__.py,sha256=fZ-dxpldQIk6-2JhVnCj-Tsl8bz2nvoGOyG7uXKvBfg,160
10
8
  apsg/decorator/_decorator.py,sha256=8TMSrcVvhU5UCbNMrnyrW3-65qo20_6N2ShtXd3bP-k,1194
@@ -30,11 +28,11 @@ apsg/plotting/_paleomagplots.py,sha256=Gw-fqYJVjNxTNXLwAiUKnFUBoOTZv2MEd3XACLmQ6
30
28
  apsg/plotting/_plot_artists.py,sha256=6S0EKCqYU6rlBxcxcXALTk9PaUK6QL-BgUKmZH8tkMc,21059
31
29
  apsg/plotting/_projection.py,sha256=qnJgTQaFW0v2Pu9ySAEPADHhLgpXmfJ6QIrydry8rXQ,11473
32
30
  apsg/plotting/_roseplot.py,sha256=jbaUXSb3DIcXs0pWAQUTZfdlA2XcbquT0yHLYDjLirQ,12808
33
- apsg/plotting/_stereogrid.py,sha256=Buj0kp5P4cvTPowN6Jyt8wzvRMu3h5If1pwVWaal53M,11981
34
- apsg/plotting/_stereonet.py,sha256=A9MN1n28nO4uUEPHwLDxitkpgqWKrY2UzfyjhbGKQLQ,36708
35
- apsg/shell.py,sha256=UFIOy01KckLsOlqfB0UomyWZ1ITL36-lBUFhlxWdZLE,718
36
- apsg-1.3.0.dist-info/AUTHORS.md,sha256=OEu_2jVMx1fm5EOj4vBlI04uvX4P2sqjPYP12VjPIcI,130
37
- apsg-1.3.0.dist-info/METADATA,sha256=GsnDqDd21YvCxSvEtTzY1lIM1krV-L1S78D9H8MgrXE,5665
38
- apsg-1.3.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
39
- apsg-1.3.0.dist-info/entry_points.txt,sha256=4iGMgjQjz3NMzNkYJFzDkYA9N4-ya6M-j2XUWdw8mY8,41
40
- apsg-1.3.0.dist-info/RECORD,,
31
+ apsg/plotting/_stereogrid.py,sha256=awh7MwN1WgszhOlr6UgR20wHQJ8u778-Tf_w1uflrV4,11869
32
+ apsg/plotting/_stereonet.py,sha256=-BFM9RCInI-RYs1DKz-ymNFkMFJLTWuw3JcyUs7YiGM,36596
33
+ apsg-1.3.2.dist-info/LICENSE,sha256=lY0kfpVRrzcgVZq7pI6rLK5WYiUMWe0bdKpDelN6hk8,1120
34
+ apsg-1.3.2.dist-info/METADATA,sha256=RtbuiUnWF0ArtuePgaLRg3Ve7kMPT3e6RJFHzZZKKhI,8276
35
+ apsg-1.3.2.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
36
+ apsg-1.3.2.dist-info/entry_points.txt,sha256=SowP7_uRI0NJuzznKBXyM9BJcSwBxbXo6Iz5LUo9mEQ,42
37
+ apsg-1.3.2.dist-info/top_level.txt,sha256=xWxwi0nqqOyKdmpsszfR-bmqnNpgVbhnLRuIKGJnaUM,5
38
+ apsg-1.3.2.dist-info/RECORD,,
@@ -1,4 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: setuptools (75.8.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ iapsg = apsg.shell:main
@@ -0,0 +1 @@
1
+ apsg
AUTHORS.md DELETED
@@ -1,9 +0,0 @@
1
- # Credits
2
-
3
- ## Development Lead
4
-
5
- * Ondrej Lexa <lexa.ondrej@gmail.com>
6
-
7
- ## Contributors
8
-
9
- * David Landa <david.landa@natur.cuni.cz>
CHANGELOG.md DELETED
@@ -1,304 +0,0 @@
1
- # Changelog
2
-
3
- ## 1.3.0 (Dec 14 2024)
4
- * Python 3.10 set as minimal version
5
- * Tensor3 eigenlins and eigenfols implemented as methods
6
- * pandas accessors G property returns apsg FeatureSet
7
-
8
- ### 1.2.3 (Nov 18 2024)
9
- * ClusterSet accepts PairSet and FaultSet
10
- * quicknet label option added
11
- * vector pow bug fix
12
-
13
- ### 1.2.2 (Oct 21 2024)
14
- * Fault sense could be defined by str, one of 's', 'd', 'n' and 'r'
15
-
16
- ### 1.2.1 (Sep 23 2024)
17
- * Fault sense could be defined by str, one of 's', 'd', 'n' and 'r'
18
-
19
- ## 1.2.0 (May 24 2024)
20
- * sqlalchemy and pandas added to requirements
21
- * quicknet fault bug fixed
22
-
23
- ### 1.1.5 (May 15 2024)
24
- * paleomag Core .dd bug fixed
25
- * fix round-off domain math error for acosd and asind
26
-
27
- ### 1.1.4 (Dec 13 2023)
28
- * Ellipsoid repr bugfix
29
-
30
- ### 1.1.3 (Oct 23 2023)
31
- Bugfix release
32
- * slip and dilatation tendency methods added to stress
33
- * proj alias of project for FeatureSet added
34
-
35
- ### 1.1.2 (Oct 09 2023)
36
- * added title_kws argument for plotting routines
37
-
38
- ### 1.1.1 (Oct 06 2023)
39
- * sigma estimate contour fix
40
-
41
- ## 1.1.0 (Oct 04 2023)
42
- APSG offers convenient pandas integration via pandas accessors.
43
-
44
- See documentation and Pandas interface tutorial for further details.
45
-
46
- * StereoNet tensor method added
47
- * Cluster class renamed to ClusterSet
48
-
49
- ### 1.0.3 (Apr 30 2023)
50
- * lambda properties of tensors renamed to S
51
- * cursor coordinates in stereonet show lin and fol
52
-
53
- ### 1.0.1 (Nov 22 2022)
54
- * density_lookup method implemented for StereoNet.grid
55
- * Stress tensor sigma* properties using inverted order of eigenvalues
56
- * render2fig method of StereoNet implemented
57
- * vector-like objects are not iterable, so properly render in pandas
58
-
59
- ## 1.0.0 (Oct 7 2022)
60
- New major release
61
-
62
- APSG has been significantly refactored from version 1.0 and several changes are
63
- breaking backward compatibility. The main APSG namespace provides often-used
64
- classes in lowercase names as aliases to `PascalCase` convention used in
65
- modules to provide a simplified interface for users. The `PascalCase` names of
66
- classes use longer and plain English names instead acronyms for better
67
- readability.
68
-
69
- See documentation for further details.
70
-
71
- ### 0.7.3 (Oct 6 2022)
72
- * figure window title removed from StereoNet
73
- * for future only bugfixes planned, foo further development see versions >=1.0
74
-
75
- ### 0.7.2 (Oct 6 2022)
76
- * bugfix release
77
-
78
- ### 0.7.1 (Jul 13 2021)
79
- * paleomag rs3 input/output improved
80
- * Simple SQLAlchemy API to sdb database implemented
81
- * StereoNet arc method fixed
82
- * StereoNet polygon method added
83
-
84
- ## 0.7.0 (Feb 3 2021)
85
-
86
- * Python 2 support dropped
87
- * RosePlot added
88
- * Ortensor has from_pairs method for Lisle tensor for orthogonal data
89
- * StereoNet scatter method has labels kwarg to show hover annotations
90
-
91
- ### 0.6.3 (Dec 6 2019)
92
-
93
- * Python 2/3 compatibility fix
94
-
95
- ### 0.6.2 (Dec 6 2019)
96
-
97
- * few minor bugs fixed
98
- * Stereogrid apply_func passes Vec3 instead numpy array
99
- * Pair H method to get mutual rotation implemented
100
- * velgrad method of DefGrad accepts steps kwarg
101
- to generate list of DefGrad tensors
102
- * Added Tensor class to work with deformation tensors
103
-
104
- ### 0.6.1 (Dec 12 2018)
105
-
106
- * Stereogrid always use Euclidean norms as weights
107
- * DefGrad properties e1, e2, e3 (natural principal strains) added
108
- * DefGrad properties eoct, goct (octahedral strains) added
109
- * DefGrad from_ratios class method added
110
- * DefGrad properties k, d, K, D (strain symmetries and intesities) added
111
- * New class Ellipsoid added to work with ellipsoids
112
- * FabricPLot renamed to VollmerPlot for consistency
113
- * RamsayPlot, FlinnPlot and HsuPlot implemented
114
- * All fabric plots have new path method accepting list of tensors
115
-
116
- ## 0.6.0 (Nov 7 2018)
117
-
118
- * Stress always gives eigenvalues sorted
119
- * Stress I1, I2, I3 properties for invariants implemented
120
- * Stress mean_stress property implemented
121
- * Stress hydrostatic and deviatoric properties implemented
122
- * precision added to settings to control numerical comparisms
123
- * figsize added to settings to control figure size across APSG
124
- * Animation examples fixed
125
- * rand class method implemented for Fol, Lin, Vec3 and Pair to
126
- generate random instance
127
- * Group to_csv and from_csv improved
128
- * SDB tags method works properly for multiple tags
129
- * SDB can modify database metadata
130
- * QGIS 3 plugin ReadSDB compatibility
131
-
132
- ### 0.5.4 (Oct 19 2018)
133
-
134
- * StereoNet has cbpad keyword for colorbar padding
135
- * FabricPlot bug introduced in 0.5.2 fixed.
136
-
137
- ### 0.5.3 (Oct 10 2018)
138
-
139
- * Bugfix release
140
-
141
- ### 0.5.2 (Oct 10 2018)
142
-
143
- * Fischer distribution sampling added
144
- * transform method has norm kwarg to normalize tranformed vectors
145
- * axisangle property to calculate axis and angle from rotation matrix
146
- * StereoNet arc method added
147
- * Vec3 and Group upper and flip properties implemented
148
- * DefGrad, VelGrad and Stress rotate method accepts also rotation matrix
149
- * velgrad method added to DefGrad to calculate matrix logarithm
150
- * StereoGrid has new methods max, min, max_at, min_at
151
-
152
- ### 0.5.1 (Dec 5 2017)
153
-
154
- * Kent distribution sampling added
155
- * Automatic kernel density estimate for contouring
156
- * UserWarnings fix
157
-
158
- ## 0.5.0 (Nov 19 2017)
159
-
160
- * bux fix minor release
161
-
162
- ### 0.4.4 (Mar 25 2017)
163
-
164
- * Group method centered improved
165
- * Group method halfspace added to reorient all vectors towards resultant
166
- halfspace
167
-
168
- ### 0.4.3 (Mar 25 2017)
169
-
170
- * Stress tensor with few basic methods implemented
171
- * StereoGrid keyword argument 'weighted' to control weighting
172
- * StereoNet kwargs are passed to underlying methods for immediate plots
173
- * StereoNet tensor method implemented (draw eigenlins or fols based on
174
- fol_plot settings)
175
- * Group totvar property and dot and proj methods implemented
176
- * Fol and Lin dot method returns absolute value of dot product
177
- * Vec3 H method to get mutual rotation implemented
178
- * StereoNet.contourf method draw contour lines as well by default. Option
179
- clines controls it.
180
- * centered bug fixed
181
- * StereoNet allows simple animations. Add `animate=True` kwarg to plotting
182
- method and finally call StereoNet animate method.
183
-
184
- ### 0.4.1-2 (Mar 4 2017)
185
-
186
- * bugfix
187
-
188
- ## 0.4.0 (Mar 4 2017)
189
-
190
- * Density class renamed to StereoGrid
191
- * Fault sense under rotation fixed
192
- * FaultSet example provided
193
- * Angelier-Mechler dihedra method implemented for FaultSet
194
- * StereoNet accepts StereoGrid and Ortensor as quick plot arguments
195
- * StereoNet instance has axtitle method to put text below stereonet
196
-
197
- ### 0.3.7 (Jan 5 2017)
198
-
199
- * conda build for all platforms
200
- * numpy, matplotlib and other helpres imported by default
201
- * ortensor is normed by default
202
- * ortensor MADp, MADo, MAD and kind properties added
203
-
204
- ### 0.3.6 (Jan 3 2017)
205
-
206
- * shell script iapsg opens interactive console
207
-
208
- ### 0.3.5 (Nov 12 2016)
209
-
210
- * Simple settings interface implemented in in apsg.core.seetings dictionary.
211
- To change settings use:
212
- ```
213
- from apsg.core import settings
214
- setting['name']=value
215
- ```
216
- * `notation` setting with values `dd` or `rhr` control how azimuth argument of
217
- Fol is represented.
218
- * `vec2dd` setting with values `True` or `False` control how `Vec3` is
219
- represented.
220
- * Vec3 could be instantiated by one arument (vector like), 2 arguments
221
- (azimuth, inclination) or 3 arguments (azimuth, inclination, magnitude).
222
- * Group and FaultSet can return array or list of user-defined attributes of
223
- all elements
224
-
225
- ### 0.3.4 (Jun 20 2016)
226
-
227
- * RTD fix
228
-
229
- ### 0.3.3 (Jun 4 2016)
230
-
231
- * Added E1,E2,E3 properties and polar decomposition method to DefGrad object
232
- * StereoNet has vector method to mimics lower and upper hemisphere plotting
233
- of Lin and Vec3 objects as used in paleomagnetic plots
234
- * StereoNet could be initialized with subplots
235
- * rake method of Fol added to return vector defined by rake
236
- * Density could be initialized without data for user-defined calculations
237
- New method apply_func could be used to calculate density
238
- * Contour(f) methods accept Density object as argument
239
- * Added Group class methods to generate Spherical Fibonacci and Golden Section
240
- based uniform distributions of Vec3, Lin and Fol
241
-
242
- ### 0.3.2 (Feb 22 2016)
243
-
244
- * FabricPlot - triangular fabric plot added
245
- * .asvec3 property has .V alias
246
- * Resultant of Fol and Lin is calculated as vectorial in centered position
247
- * dv property of Fol added to return dip slip vector
248
-
249
- ### 0.3.1 (Nov 20 2015)
250
-
251
- * SDB class improved. Support basic filtering including tags
252
- * StereoNet has close method to close figure and new method
253
- to re-initialize figure when closed in interactive mode
254
- * iapsg shell script added to invoke apsg ipython shell
255
-
256
- ## 0.3.0 (Nov 9 2015)
257
-
258
- * Group fancy indexing implemented. Group could be indexed by sequences
259
- of indexes like list, tuple or array as well as sliced.
260
- * Cluster class with hierarchical clustering implemented
261
- * Group to_file and from_file methods implemented to store data in file
262
- * Group copy method for shallow copy implemented
263
- * StereoNet now accept Vec3 and Fault object as well for instant plotting.
264
- * Ortensor updated with new properties E1,E2,E3 and Vollmer(1989) indexes
265
- P,G,R and C. Bug in Woodcocks's shape and strength values fixed.
266
- * uniform_lin and uniform_fol improved.
267
- * asvec3 method implemented for Fol and Lin
268
- * fol_plot property of StereoNet allows choose poles or great circles for
269
- immediate plotting
270
- * bootstrap method of Group provide generator of random resampling with
271
- replacements.
272
- * Group examples method provide few well-known datasets.
273
- * Matplotlib deprecation warnings are ignored by default
274
-
275
- ### 0.2.3 (Oct 21 2015)
276
-
277
- * New Docstrings format
278
- * StereoNet.getfols method bug fixed.
279
- * Shell scripts to run interactive session improved.
280
-
281
- ### 0.2.2 (Apr 17 2015)
282
-
283
- * FaultSet class added. Fault and Hoeppner methods of StereoNet implemented
284
- * VelGrad and DefGrad classes used for transformations added
285
- * G class to quickly create groups from strings added.
286
-
287
- ### 0.2.1 (Dec 9 2014)
288
-
289
- * Quick plotting of groups fixed.
290
-
291
- ## 0.2.0 (Dec 9 2014)
292
-
293
- * new StereoNet class for Schmidt projection
294
- * Quick plot when data are passed as argument `StereoNet` class instantiation
295
- * mplstereonet dependency depreceated
296
- * new `Pair` and `Fault` classes to manipulate paired data (full support in future)
297
- * new `uniform_lin` and `uniform_fol` `Group` methods
298
- * abs for `Group` implemented to calculate euclidean norms
299
- * new `Group` method normalized
300
- * new `Group` properties and methods to calculate spherical statistics
301
-
302
- ## 0.1.0 (Nov 1 2014)
303
-
304
- * First release of APSG
CONTRIBUTING.md DELETED
@@ -1,91 +0,0 @@
1
- # Contributing
2
-
3
- Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. You can contribute in many ways.
4
-
5
- ## Types of Contributions
6
-
7
- ### Report Bugs
8
-
9
- Report bugs at [https://github.com/ondrolexa/apsg/issues](https://github.com/ondrolexa/apsg/issues).
10
-
11
- If you are reporting a bug, please include:
12
-
13
- * Your operating system name and version.
14
- * Any details about your local setup that might be helpful in troubleshooting.
15
- * Detailed steps to reproduce the bug.
16
-
17
- ### Fix Bugs
18
-
19
- Look through the GitHub issues for bugs. Anything tagged with "bug"
20
- is open to whoever wants to implement it.
21
-
22
- ### Implement Features
23
-
24
- Look through the GitHub issues for features. Anything tagged with "feature"
25
- is open to whoever wants to implement it.
26
-
27
- ### Write Documentation
28
-
29
- APSG could always use more documentation, whether as part of the
30
- official APSG docs, in docstrings, or even on the web in blog posts,
31
- articles, and such.
32
-
33
- ### Submit Feedback
34
-
35
- The best way to send feedback is to file an issue at [https://github.com/ondrolexa/apsg/issues](https://github.com/ondrolexa/apsg/issues).
36
-
37
- If you are proposing a feature:
38
-
39
- * Explain in detail how it would work.
40
- * Keep the scope as narrow as possible, to make it easier to implement.
41
- * Remember that this is a volunteer-driven project, and that contributions
42
- are welcome :)
43
-
44
- ## Get Started!
45
-
46
- Ready to contribute? Here's how to set up `apsg` for local development.
47
-
48
- 1. Fork the `apsg` repo on GitHub.
49
- 2. Clone your fork locally with SSH or HTTPS.
50
- ```
51
- $ git clone git@github.com:ondrolexa/apsg.git
52
- $ git clone https://github.com/ondrolexa/apsg.git
53
- ```
54
-
55
- 3. Install your local copy and activate the virtual environment via `pipenv`.
56
- ```
57
- $ cd apsg/
58
- $ pipenv shell
59
- $ pipenv install --dev
60
- ```
61
- 4. Create a branch for local development.
62
- ```
63
- $ git checkout -b name-of-your-bugfix-or-feature
64
- ```
65
- 6. Now you can make your changes locally.
66
-
67
- 7. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox.
68
- ```
69
- $ flake8 apsg tests
70
- $ python setup.py test
71
- $ tox
72
- ```
73
- 8. Commit your changes and push your branch to GitHub.
74
- ```
75
- $ git add .
76
- $ git commit -m "Your detailed description of your changes."
77
- $ git push origin name-of-your-bugfix-or-feature
78
- ```
79
- 9. Submit a pull request through the GitHub website.
80
-
81
- ## Pull Request Guidelines
82
-
83
- Before you submit a pull request, check that it meets these guidelines:
84
-
85
- 1. The pull request should include tests.
86
- 2. If the pull request adds functionality, the docs should be updated. Put
87
- your new functionality into a function with a docstring, and add the
88
- feature to the list in ``README.md``.
89
- 3. The pull request should work for Python 2.7, 3.5, and 3.6.
90
- Check [https://travis-ci.org/ondrolexa/apsg/pull_requests](https://travis-ci.org/ondrolexa/apsg/pull_requests)
91
- and make sure that the tests pass for all supported Python versions.
@@ -1,9 +0,0 @@
1
- # Credits
2
-
3
- ## Development Lead
4
-
5
- * Ondrej Lexa <lexa.ondrej@gmail.com>
6
-
7
- ## Contributors
8
-
9
- * David Landa <david.landa@natur.cuni.cz>
@@ -1,141 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: apsg
3
- Version: 1.3.0
4
- Summary: APSG - The package for structural geologists
5
- Home-page: https://github.com/ondrolexa/apsg
6
- License: MIT
7
- Author: Ondrej Lexa
8
- Author-email: lexa.ondrej@gmail.com
9
- Requires-Python: >=3.10,<4.0
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Intended Audience :: Science/Research
12
- Classifier: License :: OSI Approved :: MIT License
13
- Classifier: Operating System :: OS Independent
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.10
16
- Classifier: Programming Language :: Python :: 3.11
17
- Classifier: Programming Language :: Python :: 3.12
18
- Classifier: Programming Language :: Python :: 3.13
19
- Requires-Dist: matplotlib (>=3.9,<4.0)
20
- Requires-Dist: numpy (>=2.1,<3.0)
21
- Requires-Dist: pandas (>=2.1,<3.0)
22
- Requires-Dist: pyqt5 (>=5.15,<6.0)
23
- Requires-Dist: scipy (>=1.14,<2.0)
24
- Requires-Dist: sqlalchemy (>=1.3,<2.0)
25
- Project-URL: Documentation, https://apsg.readthedocs.io
26
- Project-URL: Repository, https://github.com/ondrolexa/apsg
27
- Description-Content-Type: text/markdown
28
-
29
- <img src="https://ondrolexa.github.io/apsg/apsg_banner.svg" alt="APSG logo" width="300px"/>
30
-
31
- [![PyPI - Version](https://img.shields.io/pypi/v/apsg)](https://pypi.org/project/apsg)
32
- [![Conda](https://img.shields.io/conda/v/conda-forge/apsg)](https://anaconda.org/conda-forge/apsg)
33
- [![Documentation Status](https://readthedocs.org/projects/apsg/badge/?version=stable)](https://apsg.readthedocs.io/en/stable/?badge=stable)
34
- [![DOI](https://zenodo.org/badge/24879346.svg)](https://zenodo.org/badge/latestdoi/24879346)
35
-
36
- ## :thinking: What is APSG?
37
-
38
- APSG is the package for structural geologists. It defines several new python classes to easily manage, analyze and visualize orientational structural geology data.
39
-
40
- > [!IMPORTANT]
41
- > APSG has been significantly refactored from version 1.0 and several changes are
42
- > breaking backward compatibility. The main APSG namespace provides often-used
43
- > classes in lowercase names as aliases to `PascalCase` convention used in
44
- > modules to provide a simplified interface for users. The `PascalCase` names of
45
- > classes use longer and plain English names instead acronyms for better readability.
46
- >
47
- > Check [documentation](https://apsg.readthedocs.org) for more details.
48
-
49
- ## :hammer_and_wrench: Requirements
50
-
51
- You need Python 3.9 or later to run APSG. The package requires [NumPy](https://numpy.org/) and [SciPy](https://www.scipy.org/),
52
- [Matplotlib](https://matplotlib.org/), [SciPy](https://scipy.org/), [SQLAlchemy](https://www.sqlalchemy.org/)
53
- and [pandas](https://pandas.pydata.org/).
54
-
55
- ## :rocket: Quick start
56
-
57
- Install the **latest stable** version of APSG from PyPI:
58
- ```bash
59
- pip install apsg
60
- ```
61
-
62
- or install **master** with:
63
- ```bash
64
- pip install git+https://github.com/ondrolexa/apsg.git
65
- ```
66
-
67
- Alternatively, you can cloce the repository and do a local install (recommended for dev):
68
- ```bash
69
- git clone https://github.com/ondrolexa/apsg.git
70
- cd apsg
71
- pip install -e ."
72
- ```
73
-
74
- #### Upgrading via pip
75
-
76
- To upgrade an existing version of APSG from PyPI, execute:
77
- ```bash
78
- pip install apsg --upgrade --no-deps
79
- ```
80
-
81
- #### Comments on system-wide instalations on Debian systems
82
-
83
- Latest Debian-based systems does not allow to install non-debian packages system-wide.
84
- However, installing all requirements allows to force install APSG system-wide without troubles.
85
-
86
- Install requirements using apt:
87
- ```bash
88
- sudo apt install python3-numpy python3-matplotlib python3-scipy python3-sqlalchemy python3-pandas
89
- ```
90
-
91
- and then install apsg using pip:
92
- ```bash
93
- pip install --break-system-packages apsg
94
- ```
95
-
96
- ### Conda/Mamba
97
-
98
- The APSG package is also available on `conda-forge` channel. Installing `apsg`
99
- from the `conda-forge` channel can be achieved by adding `conda-forge` to your
100
- channels:
101
-
102
- ```bash
103
- conda config --add channels conda-forge
104
- ```
105
-
106
- Once the `conda-forge` channel has been enabled, `apsg` can be installed with:
107
-
108
- ```bash
109
- conda install apsg
110
- ```
111
-
112
- It is possible to list all of the versions of `apsg` available on your platform with:
113
-
114
- ```bash
115
- conda search apsg --channel conda-forge
116
- ```
117
-
118
- #### Current release info
119
-
120
- | Name | Downloads | Version | Platforms |
121
- | --- | --- | --- | --- |
122
- | [![Conda Recipe](https://img.shields.io/badge/recipe-apsg-green.svg)](https://anaconda.org/conda-forge/apsg) | [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/apsg.svg)](https://anaconda.org/conda-forge/apsg) | [![Conda Version](https://img.shields.io/conda/vn/conda-forge/apsg.svg)](https://anaconda.org/conda-forge/apsg) | [![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/apsg.svg)](https://anaconda.org/conda-forge/apsg) |
123
-
124
- ## :blue_book: Documentation
125
-
126
- Explore all the features of APSG. You can find detailed documentation [here](https://apsg.readthedocs.org).
127
-
128
- ## :computer: Contributing
129
-
130
- Most discussion happens on [Github](https://github.com/ondrolexa/apsg). Feel free to open [an issue](https://github.com/ondrolexa/apsg/issues/new) or comment on any open issue or pull request. Check ``CONTRIBUTING.md`` for more details.
131
-
132
- ## :coin: Donate
133
-
134
- APSG is an open-source project, available for you for free. It took a lot of time and resources to build this software. If you find this software useful and want to support its future development please consider donating me.
135
-
136
- [![Donate via PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=QTYZWVUNDUAH8&item_name=APSG+development+donation&currency_code=EUR&source=url)
137
-
138
- ## License
139
-
140
- APSG is free software: you can redistribute it and/or modify it under the terms of the MIT License. A copy of this license is provided in ``LICENSE`` file.
141
-
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- iapsg=apsg.shell:main
3
-