pingmapper 5.2.1__tar.gz → 5.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. {pingmapper-5.2.1 → pingmapper-5.3.0}/PKG-INFO +47 -20
  2. {pingmapper-5.2.1 → pingmapper-5.3.0}/README.md +28 -0
  3. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/class_mapSubstrateObj.py +1 -1
  4. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/funcs_common.py +9 -1
  5. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/gui_main.py +8 -7
  6. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/main_mapSubstrate.py +13 -1
  7. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/main_readFiles.py +22 -0
  8. pingmapper-5.3.0/pingmapper/processing_scripts/main_batchDirectory_2024-01-18_0926.py +314 -0
  9. pingmapper-5.3.0/pingmapper/processing_scripts/main_batchDirectory_2024-01-18_0929.py +314 -0
  10. pingmapper-5.3.0/pingmapper/scratch/funcs_pyhum_correct.py +188 -0
  11. pingmapper-5.3.0/pingmapper/scratch/main.py +289 -0
  12. pingmapper-5.3.0/pingmapper/scratch/main_batchDirectory.py +320 -0
  13. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/test_PINGMapper.py +16 -1
  14. pingmapper-5.3.0/pingmapper/utils/DRAFT_Workflows/avg_predictions_Mussel_WBL.py +454 -0
  15. pingmapper-5.3.0/pingmapper/utils/DRAFT_Workflows/gen_centerline.py +136 -0
  16. pingmapper-5.3.0/pingmapper/utils/DRAFT_Workflows/gen_centerline_from_bankline.py +204 -0
  17. pingmapper-5.3.0/pingmapper/utils/DRAFT_Workflows/gen_centerline_trkpnts_fitspline_DRAFT.py +89 -0
  18. pingmapper-5.3.0/pingmapper/utils/DRAFT_Workflows/testEXAMPLE_mosaic_logit.py +152 -0
  19. pingmapper-5.3.0/pingmapper/utils/RawEGN_avg_predictions.py +444 -0
  20. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/00_substrate_logits_mosaic_transects.py +433 -0
  21. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/00_substrate_shps_mosaic_transects.py +278 -0
  22. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/01_gen_centerline_from_coverage.py +333 -0
  23. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/02_gen_summary_stamp_shps.py +330 -0
  24. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/03_gen_summary_shp.py +367 -0
  25. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/04_combine_summary_shp_csv.py +74 -0
  26. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/05_gen_summary_shp_plots.py +548 -0
  27. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/06_compare_raw-egn_volume.py +196 -0
  28. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/08_raw-egn_hardReacheFreq_hist.py +240 -0
  29. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/09_raw-egn_PatchSize_density.py +209 -0
  30. pingmapper-5.3.0/pingmapper/utils/Substrate_Summaries/summarize_project_substrate.py +599 -0
  31. pingmapper-5.3.0/pingmapper/utils/export_coverage.py +155 -0
  32. pingmapper-5.3.0/pingmapper/utils/main_mosaic_transects.py +828 -0
  33. pingmapper-5.3.0/pingmapper/version.py +1 -0
  34. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper.egg-info/PKG-INFO +47 -20
  35. pingmapper-5.3.0/pingmapper.egg-info/SOURCES.txt +51 -0
  36. pingmapper-5.3.0/pingmapper.egg-info/requires.txt +13 -0
  37. pingmapper-5.3.0/pyproject.toml +108 -0
  38. pingmapper-5.2.1/pingmapper/version.py +0 -1
  39. pingmapper-5.2.1/pingmapper.egg-info/SOURCES.txt +0 -27
  40. pingmapper-5.2.1/pingmapper.egg-info/requires.txt +0 -3
  41. pingmapper-5.2.1/setup.py +0 -50
  42. {pingmapper-5.2.1 → pingmapper-5.3.0}/LICENSE +0 -0
  43. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/__init__.py +0 -0
  44. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/__main__.py +0 -0
  45. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/class_portstarObj.py +0 -0
  46. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/class_rectObj.py +0 -0
  47. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/class_sonObj.py +0 -0
  48. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/class_sonObj_nadirgaptest.py +0 -0
  49. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/default_params.json +0 -0
  50. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/doWork.py +0 -0
  51. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/funcs_model.py +0 -0
  52. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/funcs_rectify.py +0 -0
  53. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/main_rectify.py +0 -0
  54. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper/test_time.py +0 -0
  55. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper.egg-info/dependency_links.txt +0 -0
  56. {pingmapper-5.2.1 → pingmapper-5.3.0}/pingmapper.egg-info/top_level.txt +0 -0
  57. {pingmapper-5.2.1 → pingmapper-5.3.0}/setup.cfg +0 -0
@@ -1,39 +1,38 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pingmapper
3
- Version: 5.2.1
3
+ Version: 5.3.0
4
4
  Summary: Open-source interface for processing recreation-grade side scan sonar datasets and reproducibly mapping benthic habitat
5
- Author: Cameron Bodine, Daniel Buscombe
6
- Author-email: bodine.cs@gmail.email
7
- Project-URL: Issues, https://github.com/CameronBodine/PINGMapper/issues
8
- Project-URL: GitHub, https://github.com/CameronBodine/PINGMapper
5
+ Author: Daniel Buscombe
6
+ Author-email: Cameron Bodine <bodine.cs@gmail.email>
7
+ License-Expression: MIT
9
8
  Project-URL: Homepage, https://cameronbodine.github.io/PINGMapper/
9
+ Project-URL: GitHub, https://github.com/CameronBodine/PINGMapper
10
+ Project-URL: Issues, https://github.com/CameronBodine/PINGMapper/issues
10
11
  Keywords: pingmapper,sonar,ecology,remotesensing,sidescan,sidescan-sonar,aquatic,humminbird,lowrance,gis,oceanography,limnology
11
12
  Classifier: Development Status :: 5 - Production/Stable
12
13
  Classifier: Programming Language :: Python :: 3
13
- Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Topic :: Scientific/Engineering
16
16
  Classifier: Topic :: Scientific/Engineering :: Visualization
17
17
  Classifier: Topic :: Scientific/Engineering :: Oceanography
18
18
  Classifier: Topic :: Scientific/Engineering :: GIS
19
19
  Classifier: Topic :: Scientific/Engineering :: Hydrology
20
- Requires-Python: >=3.6
20
+ Requires-Python: >=3.10
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
- Requires-Dist: pinginstaller
24
- Requires-Dist: pingwizard
25
- Requires-Dist: pingverter
26
- Dynamic: author
27
- Dynamic: author-email
28
- Dynamic: classifier
29
- Dynamic: description
30
- Dynamic: description-content-type
31
- Dynamic: keywords
23
+ Requires-Dist: pinginstaller<3,>=2
24
+ Requires-Dist: pingwizard<2,>=1
25
+ Requires-Dist: pingverter<3,>=2
26
+ Requires-Dist: psutil<8,>=7
27
+ Requires-Dist: opencv-python<5,>=4.12
28
+ Requires-Dist: rsa<5,>=4.9
29
+ Requires-Dist: FreeSimpleGUI<6,>=5
30
+ Provides-Extra: ml
31
+ Requires-Dist: doodleverse_utils>=0.0.39; extra == "ml"
32
+ Requires-Dist: tensorflow<3,>=2.20; extra == "ml"
33
+ Requires-Dist: tf-keras<3,>=2.20; extra == "ml"
34
+ Requires-Dist: transformers<5,>=4.57; extra == "ml"
32
35
  Dynamic: license-file
33
- Dynamic: project-url
34
- Dynamic: requires-dist
35
- Dynamic: requires-python
36
- Dynamic: summary
37
36
 
38
37
  # PING-Mapper
39
38
  [![PyPI - Version](https://img.shields.io/pypi/v/pingmapper?style=flat-square&label=Latest%20Version%20(PyPi))](https://pypi.org/project/pingmapper/)
@@ -139,6 +138,34 @@ Continued support for PINGMapper and tools in the [PING Ecosystem](./docs/PINGEc
139
138
 
140
139
  **Advocates & Mentors**: Vincent Capone - [Black Laser Learning](https://blacklaserlearning.com/)
141
140
 
141
+ ## Quick Start
142
+
143
+ ### Option A: Conda
144
+
145
+ Please see [Getting Started](https://cameronbodine.github.io/PINGMapper/docs/gettingstarted) for full instructions, or simply run:
146
+
147
+ ```bash
148
+ conda env create -f pingmapper/conda/PINGMapper.yml
149
+ conda activate ping
150
+ python -m pingmapper gui
151
+ ```
152
+
153
+ ### Option B: Pixi
154
+
155
+ [Pixi](https://pixi.sh) manages all dependencies (including GDAL) automatically from a single `pyproject.toml`.
156
+
157
+ 1. [Install pixi](https://pixi.sh)
158
+ 2. Clone and run:
159
+ ```bash
160
+ git clone https://github.com/CameronBodine/PINGMapper.git
161
+ cd PINGMapper
162
+ pixi run pingmapper # Launches PINGWizard
163
+ ```
164
+ 3. For machine learning features (substrate mapping):
165
+ ```bash
166
+ pixi run -e full gui # GUI with ML support
167
+ ```
168
+
142
169
  ## Ready to get started?
143
170
 
144
171
  Follow the installation and testing instructions to [Get Started!](https://cameronbodine.github.io/PINGMapper/docs/gettingstarted)
@@ -102,6 +102,34 @@ Continued support for PINGMapper and tools in the [PING Ecosystem](./docs/PINGEc
102
102
 
103
103
  **Advocates & Mentors**: Vincent Capone - [Black Laser Learning](https://blacklaserlearning.com/)
104
104
 
105
+ ## Quick Start
106
+
107
+ ### Option A: Conda
108
+
109
+ Please see [Getting Started](https://cameronbodine.github.io/PINGMapper/docs/gettingstarted) for full instructions, or simply run:
110
+
111
+ ```bash
112
+ conda env create -f pingmapper/conda/PINGMapper.yml
113
+ conda activate ping
114
+ python -m pingmapper gui
115
+ ```
116
+
117
+ ### Option B: Pixi
118
+
119
+ [Pixi](https://pixi.sh) manages all dependencies (including GDAL) automatically from a single `pyproject.toml`.
120
+
121
+ 1. [Install pixi](https://pixi.sh)
122
+ 2. Clone and run:
123
+ ```bash
124
+ git clone https://github.com/CameronBodine/PINGMapper.git
125
+ cd PINGMapper
126
+ pixi run pingmapper # Launches PINGWizard
127
+ ```
128
+ 3. For machine learning features (substrate mapping):
129
+ ```bash
130
+ pixi run -e full gui # GUI with ML support
131
+ ```
132
+
105
133
  ## Ready to get started?
106
134
 
107
135
  Follow the installation and testing instructions to [Get Started!](https://cameronbodine.github.io/PINGMapper/docs/gettingstarted)
@@ -1059,7 +1059,7 @@ class mapSubObj(rectObj):
1059
1059
  c = int(c.split('_')[-1])
1060
1060
  toMap[c] = n
1061
1061
 
1062
- del npzDir, npzs, n, c
1062
+ del npzDir, npzs
1063
1063
  return toMap
1064
1064
 
1065
1065
 
@@ -52,7 +52,15 @@ from osgeo import gdal
52
52
  import pyproj
53
53
 
54
54
  if 'GDAL_DATA' not in os.environ:
55
- os.environ['GDAL_DATA'] = os.path.join(f'{os.sep}'.join(sys.executable.split(os.sep)[:-1]), 'Library', 'share', 'gdal')
55
+ prefix = os.environ.get('CONDA_PREFIX', os.path.dirname(os.path.dirname(sys.executable)))
56
+ candidates = [
57
+ os.path.join(prefix, 'share', 'gdal'), # conda/pixi on Linux/macOS
58
+ os.path.join(prefix, 'Library', 'share', 'gdal'), # conda/pixi on Windows
59
+ ]
60
+ for _candidate in candidates:
61
+ if os.path.isdir(_candidate):
62
+ os.environ['GDAL_DATA'] = _candidate
63
+ break
56
64
 
57
65
  import rasterio
58
66
  import geopandas as gpd
@@ -3,11 +3,10 @@ import sys, os
3
3
  import webbrowser
4
4
 
5
5
  PySimpleGUI_License = 'e3yAJ9MVaOWANplCbmndNNl2VwHvlCwpZTSjIl6DIjkiRGpYc53aRty8aBWpJF1qdwGLlzv9bUiHILs3Inkyxpp5Yq2OVku8cg2ZVrJ7RNCQI66bMcTLcnyKMbTRMK57OCTPMGxGNtS8whirTBGTlLjxZEWg5DzWZdUXRUlLcDGfxnv7eiWB1jlOb6nqR8WTZ2XsJVzbabW19ouWI6j0oXiKN0Si4AwtI7iFw8iGTBmtFftjZEUxZMpYcLncNk0rIJj4oyisQq2uFCtqZnXWJvvqbEiCICsSIbkC5jhKbvWTVqM2YtX6Ni0XIJjloji1QEmU9Ak5ayWp5nlnIwi3wiiOQK279ytqcKGwFGuvepS6IH6iIOiYIGs7I4kYNQ13cY33RkvIbqWkVyypSKUOQoiZO2ijIFzaMNTEAp0bNxyWI1sLIwkRRjhZdNGBVoJkcZ3MNN1yZMWTQtihOiieIYyXMDDIIF0ILaTyAt36LKTREj5JI1iYwcixRgGuFk0BZGU5VZ4dciGUl3ykZ3XtMbilOMiBIhy1M5DtId1mL6T1A935LYTLEN5iI3iJwoirR8Wa12h5a0WtxkBNZdGiRJyYZXX9N5zZI2jSoZizYpmp9YkHaIWz5YluLTmcNXzNQmGZd0twYGW6l3sALZmTNWvubcSEItsPITk6lFQgQUWZRrkfcEmAVxz0c9y7IG6sILjZEYyzO8Cf4c0WLDj3QCwSLwjPEt2BMMi0J69p854e39898f71ea82d3a530f7a6ed8a02a4eea9ffd2c7b1279074b491c71b411f392e6d726a2d2f9dbf63388356cf4e083e358fe428852d676073e128607b9ad194c15e34a4feb463a749fd3295606caa293b823d102e854cd845b79b5ec5eaec0b2ef7f9cf0c87b2dfcad3f14cd0d66a2da97e6b38a535eb8707b4486c9802a4bfeb09703382e157449096f0e3551af9f444197cacb3f3d42187cea97ab61978985ddeecd086b9cb86c4ec1c08082d47b3ed0ae9c044d9aa65e5c9bf6e00238f78ed858cfdaf0021fb95d636e0cce84d84d2c2da7ac57f2e54fe793fce44a8b8abf96ce7c381f4b7eeb55dc4b68768e8172a4dffc1b683e62a108b2dfc2ef340dab058e6ee5c1f525f93e89d39258862f099987a8ec7022db5aecb5a58e81d02370d5717d18498ae58749aa5e463cf757ab7fa84efe49c1b770da397eef22423696ad433e7232646e279906bef084b21714ac5fc2af564a03ebc789123aed44531765b3e72c6165131feab68e35e0276a64760ee9abf043bece1e3cd148bcec97ab835395391387ff9d2b74a835a15ea5bac9c7e1218c217481a3999a91e037a138aaf5dddadb2247141242140b130e273aab5e1e6855fae8b7ee80d64be2d09a46f3d49555f53a7a849138fc3b9d2323658ea7e86a0039c40f3c15fd3647f99ec98232d9734a5933177c48c6575a1415e2808640cfb27773e728fe128b99757'
6
- # try:
7
- # import FreeSimpleGUI as sg
8
- # except ImportError:
9
- # import PySimpleGUI as sg
10
- import PySimpleGUI as sg
6
+ try:
7
+ import FreeSimpleGUI as sg
8
+ except ImportError:
9
+ import PySimpleGUI as sg
11
10
  import matplotlib.pyplot as plt
12
11
 
13
12
  # Add 'pingmapper' to the path, may not need after pypi package...
@@ -51,8 +50,10 @@ def gui(batch: bool):
51
50
  primary_default_params = os.path.join(SCRIPT_DIR, "default_params.json")
52
51
 
53
52
  if not os.path.exists(primary_default_params):
54
- d = os.environ['CONDA_PREFIX']
55
- primary_default_params = os.path.join(d, 'pingmapper_config', 'default_params.json')
53
+ # Fallback: look in environment prefix (works with both conda and pixi)
54
+ prefix = os.environ.get('CONDA_PREFIX', '')
55
+ if prefix:
56
+ primary_default_params = os.path.join(prefix, 'pingmapper_config', 'default_params.json')
56
57
 
57
58
  default_params_file = os.path.join(SCRIPT_DIR, "user_params.json")
58
59
 
@@ -243,6 +243,14 @@ def map_master_func(logfilename='',
243
243
  # For Substrate Prediction #
244
244
  ############################################################################
245
245
 
246
+ if pred_sub > 0 and not DEPTH_DETECTION_AVAILABLE:
247
+ print('\n\nCannot predict substrate automatically:')
248
+ print('TensorFlow, Transformers, and/or Doodleverse Utils are not installed.')
249
+ print('These packages are required for substrate prediction.')
250
+ print('Please install them using: pip install tensorflow transformers doodleverse-utils')
251
+ print('Skipping substrate prediction...\n')
252
+ pred_sub = 0
253
+
246
254
  if pred_sub > 0:
247
255
  start_time = time.time()
248
256
 
@@ -294,7 +302,11 @@ def map_master_func(logfilename='',
294
302
  # Fot Substrate Plotting #
295
303
  ############################################################################
296
304
 
297
- print(pltSubClass)
305
+ if pltSubClass and not DEPTH_DETECTION_AVAILABLE:
306
+ print('\n\nCannot export substrate plots:')
307
+ print('TensorFlow, Transformers, and/or Doodleverse Utils are not installed.')
308
+ print('Skipping substrate plot export...\n')
309
+ pltSubClass = False
298
310
 
299
311
  if pltSubClass:
300
312
  start_time = time.time()
@@ -1136,6 +1136,8 @@ def read_master_func(logfilename='',
1136
1136
  print('Please install them using: pip install tensorflow transformers doodleverse-utils')
1137
1137
  print('Skipping automatic depth estimation...\n')
1138
1138
  detectDep = 0
1139
+ autoBed = False
1140
+ saveDepth = True
1139
1141
  else:
1140
1142
  print('\n\nAutomatically estimating depth for', len(chunks), 'chunks:')
1141
1143
 
@@ -1306,6 +1308,26 @@ def read_master_func(logfilename='',
1306
1308
  else:
1307
1309
  keepShadow = False
1308
1310
 
1311
+ if remShadow > 0 and not DEPTH_DETECTION_AVAILABLE:
1312
+ print('\n\nCannot detect shadows automatically:')
1313
+ print('TensorFlow, Transformers, and/or Doodleverse Utils are not installed.')
1314
+ print('These packages are required for automatic shadow detection.')
1315
+ print('Please install them using: pip install tensorflow transformers doodleverse-utils')
1316
+ print('Skipping automatic shadow detection...\n')
1317
+ remShadow = 0
1318
+ keepShadow = True
1319
+ for son in sonObjs:
1320
+ son.remShadow = 0
1321
+
1322
+ if pred_sub and not DEPTH_DETECTION_AVAILABLE:
1323
+ print('\n\nCannot map substrate automatically:')
1324
+ print('TensorFlow, Transformers, and/or Doodleverse Utils are not installed.')
1325
+ print('These packages are required for substrate mapping.')
1326
+ print('Please install them using: pip install tensorflow transformers doodleverse-utils')
1327
+ print('Skipping substrate mapping...\n')
1328
+ pred_sub = 0
1329
+ map_sub = 0
1330
+
1309
1331
  if remShadow > 0:
1310
1332
  start_time = time.time()
1311
1333
  print('\n\nAutomatically detecting shadows for', len(chunks), 'chunks:')
@@ -0,0 +1,314 @@
1
+ # Part of PING-Mapper software
2
+ #
3
+ # Co-Developed by Cameron S. Bodine and Dr. Daniel Buscombe
4
+ #
5
+ # Inspired by PyHum: https://github.com/dbuscombe-usgs/PyHum
6
+ #
7
+ # MIT License
8
+ #
9
+ # Copyright (c) 2022-23 Cameron S. Bodine
10
+ #
11
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ # of this software and associated documentation files (the "Software"), to deal
13
+ # in the Software without restriction, including without limitation the rights
14
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ # copies of the Software, and to permit persons to whom the Software is
16
+ # furnished to do so, subject to the following conditions:
17
+ #
18
+ # The above copyright notice and this permission notice shall be included in all
19
+ # copies or substantial portions of the Software.
20
+ #
21
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ # SOFTWARE.
28
+
29
+ import sys
30
+ sys.path.insert(0, 'src')
31
+
32
+ from funcs_common import *
33
+ from main_readFiles import read_master_func
34
+ from main_rectify import rectify_master_func
35
+ from main_mapSubstrate import map_master_func
36
+
37
+ import time
38
+ import datetime
39
+
40
+ # Get processing script's dir so we can save it to file
41
+ scriptDir = os.getcwd()
42
+
43
+ # For the logfile
44
+ oldOutput = sys.stdout
45
+
46
+ #============================================
47
+
48
+ #######################
49
+ # Start User Parameters
50
+ #######################
51
+
52
+ # Path to data/output
53
+ inDir = r'./exampleData/' # Parent folder of sonar recordings
54
+ outDir = r'./procData' # Parent folder for export files
55
+
56
+ # *** IMPORTANT ****
57
+ # Export Mode: project_mode
58
+ ## 0==NEW PROJECT: Create a new project. [DEFAULT]
59
+ ## If project already exists, program will exit without any project changes.
60
+ ##
61
+ ## 1==OVERWRITE MODE: Create new project, regardless of previous project state.
62
+ ## If project exists, it will be DELETED and reprocessed.
63
+ ## If project does not exist, a new project will be created.
64
+ project_mode = 1
65
+
66
+
67
+ # General Parameters
68
+ tempC = 10 #Temperature in Celsius
69
+ nchunk = 500 #Number of pings per chunk
70
+ cropRange = 0.0 #Crop imagery to specified range [in meters]; 0.0==No Cropping
71
+ exportUnknown = False #Option to export Unknown ping metadata
72
+ fixNoDat = True # Locate and flag missing pings; add NoData to exported imagery.
73
+ threadCnt = 0 #Number of compute threads to use; 0==All threads; <0==(Total threads + threadCnt); >0==Threads to use up to total threads
74
+
75
+
76
+ # Output Pixel Resolution [meters]
77
+ pix_res_son = 0.05 # 0 = Default (~0.02 m)
78
+ pix_res_map = 0.25 # 0 = Default (~0.02 m)
79
+
80
+
81
+ # Position Corrections
82
+ ## Provide an x and y offset to account for position offset between
83
+ ## control head (or external GPS) and transducer.
84
+ ## Origin (0,0) is the location of control head (or external GPS)
85
+ ## X-axis runs from bow (fore, or front) to stern (aft, or rear) with positive offset towards the bow, negative towards stern
86
+ ## Y-axis runs from portside (left) to starboard (right), with negative values towards the portside, positive towards starboard
87
+ ## Z-offsets can be provided with `adjDep` below.
88
+ x_offset = 0.0 # [meters]
89
+ y_offset = 0.0 # [meters]
90
+
91
+
92
+ # Sonar Intensity Corrections
93
+ egn = True
94
+ egn_stretch = 1 # 0==Min-Max; 1==% Clip
95
+ egn_stretch_factor = 0.5 # If % Clip, the percent of histogram tails to clip (1.0 == 1%)
96
+
97
+
98
+ # Sonogram Exports
99
+ tileFile = '.jpg' # Img format for plots and sonogram exports
100
+ wcp = True #Export tiles with water column present: 0==False; 1==True, side scan channels only; 2==True, all available channels.
101
+ wcr = True #Export Tiles with water column removed (and slant range corrected): 0==False; 1==True, side scan channels only; 2==True, all available channels.
102
+
103
+
104
+ # Speed corrected sonogram Exports
105
+ lbl_set = 2 # Export images for labeling: 0==False; 1==True, keep water column & shadows; 2==True, remove water column & shadows
106
+ spdCor = 1 # Speed correction: 0==No Speed Correction; 1==Stretch by GPS distance; !=1 or !=0 == Stretch factor.
107
+ maxCrop = False # True==Ping-wise crop; False==Crop tile to max range.
108
+
109
+
110
+ # Depth Detection and Shadow Removal Parameters
111
+ remShadow = 2 # 0==Leave Shadows; 1==Remove all shadows; 2==Remove only bank shadows
112
+ detectDep = 1 #0==Use Humminbird depth; 1==Auto detect depth w/ Zheng et al. 2021;
113
+ ## 2==Auto detect depth w/ Thresholding
114
+
115
+ smthDep = True #Smooth depth before water column removal
116
+ adjDep = 0 #Aditional depth adjustment (in pixels) for water column removaL
117
+ pltBedPick = True #Plot bedpick on sonogram
118
+
119
+
120
+ # Rectification Parameters
121
+ rect_wcp = True #Export rectified tiles with water column present
122
+ rect_wcr = True #Export rectified tiles with water column removed/slant range corrected
123
+ son_colorMap = 'Greys_r' # Specify colorramp for rectified imagery. '_r'==reverse the ramp: https://matplotlib.org/stable/tutorials/colors/colormaps.html
124
+
125
+
126
+ # Substrate Mapping
127
+ pred_sub = 1 # Automatically predict substrates and save to npz: 0==False; 1==True, SegFormer Model
128
+ pltSubClass = True # Export plots of substrate classification and predictions
129
+ map_sub = 1 # Export substrate maps (as rasters): 0==False; 1==True. Requires substrate predictions saved to npz.
130
+ export_poly = True # Convert substrate maps to shapefile: map_sub must be > 0 or raster maps previously exported
131
+ map_predict = 0 #Export rectified tiles of the model predictions: 0==False; 1==Probabilities; 2==Logits. Requires substrate predictions saved to npz.
132
+ map_class_method = 'max' # 'max' only current option. Take argmax of substrate predictions to get final classification.
133
+
134
+
135
+ # Mosaic Exports
136
+ mosaic_nchunk = 0 # Number of chunks per mosaic: 0=All chunks. Specifying a value >0 generates multiple mosaics if number of chunks exceeds mosaic_nchunk.
137
+ mosaic = 1 #Export sonar mosaic; 0==Don't Mosaic; 1==Do Mosaic - GTiff; 2==Do Mosaic - VRT
138
+ map_mosaic = 1 #Export substrate mosaic; 0==Don't Mosaic; 1==Do Mosaic - GTiff; 2==Do Mosaic - VRT
139
+
140
+
141
+ # Miscellaneous Exports
142
+ banklines = True # Export banklines from sonar imagery
143
+
144
+
145
+ #####################
146
+ # End User Parameters
147
+ #####################
148
+
149
+ #============================================
150
+ # Normalize paths
151
+ inDir = os.path.normpath(inDir)
152
+ outDir = os.path.normpath(outDir)
153
+
154
+ # Find all DAT and SON files in all subdirectories of inDir
155
+ inFiles=[]
156
+ for root, dirs, files in os.walk(inDir):
157
+ for file in files:
158
+ if file.endswith('.DAT'):
159
+ inFiles.append(os.path.join(root, file))
160
+
161
+ inFiles = sorted(inFiles)
162
+
163
+ for i, f in enumerate(inFiles):
164
+ print(i, ":", f)
165
+
166
+ errorRecording = []
167
+ for datFile in inFiles:
168
+ try:
169
+ copied_script_name = os.path.basename(__file__).split('.')[0]+'_'+time.strftime("%Y-%m-%d_%H%M")+'.py'
170
+ script = os.path.join(scriptDir, os.path.basename(__file__))
171
+
172
+ logfilename = 'log_'+time.strftime("%Y-%m-%d_%H%M")+'.txt'
173
+
174
+ start_time = time.time()
175
+
176
+ inPath = os.path.dirname(datFile)
177
+ humFile = datFile
178
+ recName = os.path.basename(humFile).split('.')[0]
179
+ sonPath = humFile.split('.DAT')[0]
180
+ sonFiles = sorted(glob(sonPath+os.sep+'*.SON'))
181
+
182
+ projDir = os.path.join(outDir, recName)
183
+
184
+ params = {
185
+ 'logfilename':logfilename,
186
+ 'project_mode':project_mode,
187
+ 'script':[script, copied_script_name],
188
+ 'humFile':humFile,
189
+ 'sonFiles':sonFiles,
190
+ 'projDir':projDir,
191
+ 'tempC':tempC,
192
+ 'nchunk':nchunk,
193
+ 'exportUnknown':exportUnknown,
194
+ 'fixNoDat':fixNoDat,
195
+ 'threadCnt':threadCnt,
196
+ 'pix_res_son': pix_res_son,
197
+ 'pix_res_map': pix_res_map,
198
+ 'x_offset':x_offset,
199
+ 'y_offset':y_offset,
200
+ 'egn':egn,
201
+ 'egn_stretch':egn_stretch,
202
+ 'egn_stretch_factor':egn_stretch_factor,
203
+ 'tileFile':tileFile,
204
+ 'wcp':wcp,
205
+ 'wcr':wcr,
206
+ 'lbl_set':lbl_set,
207
+ 'spdCor':spdCor,
208
+ 'maxCrop':maxCrop,
209
+ 'USE_GPU':False,
210
+ 'remShadow':remShadow,
211
+ 'detectDep':detectDep,
212
+ 'smthDep':smthDep,
213
+ 'adjDep':adjDep,
214
+ 'pltBedPick':pltBedPick,
215
+ 'rect_wcp':rect_wcp,
216
+ 'rect_wcr':rect_wcr,
217
+ 'son_colorMap':son_colorMap,
218
+ 'pred_sub':pred_sub,
219
+ 'map_sub':map_sub,
220
+ 'export_poly':export_poly,
221
+ 'map_predict':map_predict,
222
+ 'pltSubClass':pltSubClass,
223
+ 'map_class_method':map_class_method,
224
+ 'mosaic_nchunk':mosaic_nchunk,
225
+ 'mosaic':mosaic,
226
+ 'map_mosaic':map_mosaic,
227
+ 'banklines':banklines,
228
+ }
229
+
230
+ globals().update(params)
231
+
232
+ # =========================================================
233
+ # Determine project_mode
234
+ print(project_mode)
235
+ if project_mode == 0:
236
+ # Create new project
237
+ if not os.path.exists(projDir):
238
+ os.mkdir(projDir)
239
+ else:
240
+ projectMode_1_inval()
241
+
242
+ elif project_mode == 1:
243
+ # Overwrite existing project
244
+ if os.path.exists(projDir):
245
+ shutil.rmtree(projDir)
246
+
247
+ os.mkdir(projDir)
248
+
249
+ elif project_mode == 2:
250
+ # Update project
251
+ # Make sure project exists, exit if not.
252
+
253
+ if not os.path.exists(projDir):
254
+ projectMode_2_inval()
255
+
256
+ # =========================================================
257
+ # For logging the console output
258
+
259
+ logdir = os.path.join(projDir, 'logs')
260
+ if not os.path.exists(logdir):
261
+ os.makedirs(logdir)
262
+
263
+ logfilename = os.path.join(logdir, logfilename)
264
+
265
+ sys.stdout = Logger(logfilename)
266
+
267
+ print('\n\n', '***User Parameters***')
268
+ for k,v in params.items():
269
+ print("| {:<20s} : {:<10s} |".format(k, str(v)))
270
+
271
+ print('sonPath',sonPath)
272
+ print('\n\n\n+++++++++++++++++++++++++++++++++++++++++++')
273
+ print('+++++++++++++++++++++++++++++++++++++++++++')
274
+ print('***** Working On *****')
275
+ print(humFile)
276
+ print('Start Time: ', datetime.datetime.now().strftime('%Y-%m-%d %H:%M'))
277
+
278
+ print('\n===========================================')
279
+ print('===========================================')
280
+ print('***** READING *****')
281
+ read_master_func(**params)
282
+ # read_master_func(sonFiles, humFile, projDir, t, nchunk, exportUnknown, wcp, wcr, detectDepth, smthDep, adjDep, pltBedPick, threadCnt)
283
+
284
+ if rect_wcp or rect_wcr or banklines:
285
+ print('\n===========================================')
286
+ print('===========================================')
287
+ print('***** RECTIFYING *****')
288
+ rectify_master_func(**params)
289
+ # rectify_master_func(sonFiles, humFile, projDir, nchunk, rect_wcp, rect_wcr, mosaic, threadCnt)
290
+
291
+ #==================================================
292
+ #==================================================
293
+ if pred_sub or map_sub or export_poly or pltSubClass:
294
+ print('\n===========================================')
295
+ print('===========================================')
296
+ print('***** MAPPING SUBSTRATE *****')
297
+ print("working on "+projDir)
298
+ map_master_func(**params)
299
+
300
+ sys.stdout.log.close()
301
+
302
+ except Exception as Argument:
303
+ unableToProcessError(logfilename)
304
+ print('\n\nCould not process:', datFile)
305
+
306
+ sys.stdout = oldOutput
307
+
308
+ gc.collect()
309
+ print("\n\nTotal Processing Time: ",datetime.timedelta(seconds = round(time.time() - start_time, ndigits=0)))
310
+
311
+ if len(errorRecording) > 0:
312
+ print('\n\nUnable to process the following:')
313
+ for d in errorRecording:
314
+ print('\n',d)