megadetector 10.0.4__py3-none-any.whl → 10.0.5__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.
Potentially problematic release.
This version of megadetector might be problematic. Click here for more details.
- megadetector/data_management/cct_json_utils.py +1 -0
- megadetector/data_management/speciesnet_to_md.py +2 -2
- megadetector/postprocessing/classification_postprocessing.py +26 -10
- megadetector/postprocessing/generate_csv_report.py +1 -1
- megadetector/postprocessing/load_api_results.py +1 -1
- megadetector/postprocessing/md_to_wi.py +1 -1
- megadetector/postprocessing/postprocess_batch_results.py +1 -1
- megadetector/postprocessing/repeat_detection_elimination/repeat_detections_core.py +1 -1
- megadetector/utils/ct_utils.py +18 -0
- megadetector/utils/wi_platform_utils.py +824 -0
- megadetector/utils/wi_taxonomy_utils.py +1711 -0
- megadetector/visualization/visualize_detector_output.py +1 -1
- megadetector/visualization/visualize_video_output.py +1 -1
- {megadetector-10.0.4.dist-info → megadetector-10.0.5.dist-info}/METADATA +2 -2
- {megadetector-10.0.4.dist-info → megadetector-10.0.5.dist-info}/RECORD +18 -17
- megadetector/utils/wi_utils.py +0 -2674
- {megadetector-10.0.4.dist-info → megadetector-10.0.5.dist-info}/WHEEL +0 -0
- {megadetector-10.0.4.dist-info → megadetector-10.0.5.dist-info}/licenses/LICENSE +0 -0
- {megadetector-10.0.4.dist-info → megadetector-10.0.5.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
speciesnet_to_md.py
|
|
4
4
|
|
|
5
5
|
Converts the WI (SpeciesNet) predictions.json format to MD .json format. This is just a
|
|
6
|
-
command-line wrapper around utils.
|
|
6
|
+
command-line wrapper around utils.wi_taxonomy_utils.generate_md_results_from_predictions_json.
|
|
7
7
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ command-line wrapper around utils.wi_utils.generate_md_results_from_predictions_
|
|
|
11
11
|
|
|
12
12
|
import sys
|
|
13
13
|
import argparse
|
|
14
|
-
from megadetector.utils.
|
|
14
|
+
from megadetector.utils.wi_taxonomy_utils import generate_md_results_from_predictions_json
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
#%% Command-line driver
|
|
@@ -25,14 +25,14 @@ from megadetector.utils.ct_utils import sort_dictionary_by_value
|
|
|
25
25
|
from megadetector.utils.ct_utils import sort_dictionary_by_key
|
|
26
26
|
from megadetector.utils.ct_utils import invert_dictionary
|
|
27
27
|
|
|
28
|
-
from megadetector.utils.
|
|
29
|
-
from megadetector.utils.
|
|
30
|
-
from megadetector.utils.
|
|
28
|
+
from megadetector.utils.wi_taxonomy_utils import clean_taxonomy_string
|
|
29
|
+
from megadetector.utils.wi_taxonomy_utils import taxonomy_level_index
|
|
30
|
+
from megadetector.utils.wi_taxonomy_utils import taxonomy_level_string_to_index
|
|
31
31
|
|
|
32
|
-
from megadetector.utils.
|
|
33
|
-
from megadetector.utils.
|
|
34
|
-
from megadetector.utils.
|
|
35
|
-
from megadetector.utils.
|
|
32
|
+
from megadetector.utils.wi_taxonomy_utils import non_taxonomic_prediction_strings
|
|
33
|
+
from megadetector.utils.wi_taxonomy_utils import human_prediction_string
|
|
34
|
+
from megadetector.utils.wi_taxonomy_utils import animal_prediction_string
|
|
35
|
+
from megadetector.utils.wi_taxonomy_utils import blank_prediction_string # noqa
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
#%% Options classes
|
|
@@ -1100,7 +1100,8 @@ def restrict_to_taxa_list(taxa_list,
|
|
|
1100
1100
|
input_file,
|
|
1101
1101
|
output_file,
|
|
1102
1102
|
allow_walk_down=False,
|
|
1103
|
-
add_pre_filtering_description=True
|
|
1103
|
+
add_pre_filtering_description=True,
|
|
1104
|
+
allow_redundant_latin_names=False):
|
|
1104
1105
|
"""
|
|
1105
1106
|
Given a prediction file in MD .json format, likely without having had
|
|
1106
1107
|
a geofence applied, apply a custom taxa list.
|
|
@@ -1123,6 +1124,10 @@ def restrict_to_taxa_list(taxa_list,
|
|
|
1123
1124
|
add_pre_filtering_description (bool, optional): should we add a new metadata
|
|
1124
1125
|
field that summarizes each image's classifications prior to taxonomic
|
|
1125
1126
|
restriction?
|
|
1127
|
+
allow_redundant_latin_names (bool, optional): if False, we'll raise an Exception
|
|
1128
|
+
if the same latin name appears twice in the taxonomy list; if True, we'll
|
|
1129
|
+
just print a warning and ignore all entries other than the first for this
|
|
1130
|
+
latin name
|
|
1126
1131
|
"""
|
|
1127
1132
|
|
|
1128
1133
|
##%% Read target taxa list
|
|
@@ -1137,11 +1142,14 @@ def restrict_to_taxa_list(taxa_list,
|
|
|
1137
1142
|
taxa_list = [s for s in taxa_list if len(s) > 0]
|
|
1138
1143
|
|
|
1139
1144
|
target_latin_to_common = {}
|
|
1145
|
+
|
|
1140
1146
|
for s in taxa_list:
|
|
1147
|
+
|
|
1141
1148
|
if s.strip().startswith('#'):
|
|
1142
1149
|
continue
|
|
1143
1150
|
tokens = s.split(',')
|
|
1144
|
-
|
|
1151
|
+
# We allow additional columns now
|
|
1152
|
+
# assert len(tokens) <= 2
|
|
1145
1153
|
binomial_name = tokens[0]
|
|
1146
1154
|
assert len(binomial_name.split(' ')) in (1,2,3), \
|
|
1147
1155
|
'Illegal binomial name in species list: {}'.format(binomial_name)
|
|
@@ -1149,9 +1157,17 @@ def restrict_to_taxa_list(taxa_list,
|
|
|
1149
1157
|
common_name = tokens[1].strip().lower()
|
|
1150
1158
|
else:
|
|
1151
1159
|
common_name = None
|
|
1152
|
-
|
|
1160
|
+
if binomial_name in target_latin_to_common:
|
|
1161
|
+
error_string = 'scientific name {} appears multiple times in the taxonomy list'.format(
|
|
1162
|
+
binomial_name)
|
|
1163
|
+
if allow_redundant_latin_names:
|
|
1164
|
+
print('Warning: {}'.format(error_string))
|
|
1165
|
+
else:
|
|
1166
|
+
raise ValueError(error_string)
|
|
1153
1167
|
target_latin_to_common[binomial_name] = common_name
|
|
1154
1168
|
|
|
1169
|
+
# ...for each line in the taxonomy file
|
|
1170
|
+
|
|
1155
1171
|
|
|
1156
1172
|
##%% Read taxonomy file
|
|
1157
1173
|
|
|
@@ -42,7 +42,7 @@ import pandas as pd
|
|
|
42
42
|
|
|
43
43
|
from copy import deepcopy
|
|
44
44
|
|
|
45
|
-
from megadetector.utils.
|
|
45
|
+
from megadetector.utils.wi_taxonomy_utils import load_md_or_speciesnet_file
|
|
46
46
|
from megadetector.utils.ct_utils import get_max_conf
|
|
47
47
|
from megadetector.utils.ct_utils import is_list_sorted
|
|
48
48
|
from megadetector.detection.run_detector import \
|
|
@@ -24,7 +24,7 @@ from collections.abc import Mapping
|
|
|
24
24
|
import pandas as pd
|
|
25
25
|
|
|
26
26
|
from megadetector.utils import ct_utils
|
|
27
|
-
from megadetector.utils.
|
|
27
|
+
from megadetector.utils.wi_taxonomy_utils import load_md_or_speciesnet_file
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
#%% Functions for loading .json results into a Pandas DataFrame, and writing back to .json
|
|
@@ -10,7 +10,7 @@ Converts the MD .json format to the WI predictions.json format.
|
|
|
10
10
|
|
|
11
11
|
import sys
|
|
12
12
|
import argparse
|
|
13
|
-
from megadetector.utils.
|
|
13
|
+
from megadetector.utils.wi_taxonomy_utils import generate_predictions_json_from_md_results
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
#%% Command-line driver
|
|
@@ -47,7 +47,7 @@ from tqdm import tqdm
|
|
|
47
47
|
from megadetector.visualization import visualization_utils as vis_utils
|
|
48
48
|
from megadetector.visualization import plot_utils
|
|
49
49
|
from megadetector.utils.write_html_image_list import write_html_image_list
|
|
50
|
-
from megadetector.utils.
|
|
50
|
+
from megadetector.utils.wi_taxonomy_utils import load_md_or_speciesnet_file
|
|
51
51
|
from megadetector.utils import path_utils
|
|
52
52
|
from megadetector.utils.ct_utils import args_to_object
|
|
53
53
|
from megadetector.utils.ct_utils import sets_overlap
|
|
@@ -637,7 +637,7 @@ def _find_matches_in_directory(dir_name_and_rows, options):
|
|
|
637
637
|
|
|
638
638
|
if 'max_detection_conf' not in row or 'detections' not in row or \
|
|
639
639
|
row['detections'] is None:
|
|
640
|
-
print('Skipping row {}'.format(i_directory_row))
|
|
640
|
+
# print('Skipping row {}'.format(i_directory_row))
|
|
641
641
|
continue
|
|
642
642
|
|
|
643
643
|
# Don't bother checking images with no detections above threshold
|
megadetector/utils/ct_utils.py
CHANGED
|
@@ -850,6 +850,24 @@ def isnan(v):
|
|
|
850
850
|
return False
|
|
851
851
|
|
|
852
852
|
|
|
853
|
+
def compare_values_nan_equal(v0,v1):
|
|
854
|
+
"""
|
|
855
|
+
Utility function for comparing two values when we want to return True if both
|
|
856
|
+
values are NaN.
|
|
857
|
+
|
|
858
|
+
Args:
|
|
859
|
+
v0 (object): the first value to compare
|
|
860
|
+
v1 (object): the second value to compare
|
|
861
|
+
|
|
862
|
+
Returns:
|
|
863
|
+
bool: True if v0 == v1, or if both v0 and v1 are NaN
|
|
864
|
+
"""
|
|
865
|
+
|
|
866
|
+
if isinstance(v0,float) and isinstance(v1,float) and np.isnan(v0) and np.isnan(v1):
|
|
867
|
+
return True
|
|
868
|
+
return v0 == v1
|
|
869
|
+
|
|
870
|
+
|
|
853
871
|
def sets_overlap(set1, set2):
|
|
854
872
|
"""
|
|
855
873
|
Determines whether two sets overlap.
|