This is a multifrequency categorization technique (see Jech and Michaels, 2006) for echosounder data analysis. It implements an algorithm that classifies the Sv responses that register above a threshold, from each frequency. The threshold can be determined by running a sensitivity analysis of historical data recorded for the species of interest.

The algorithm involves assigning an integer to each frequency. These integers are chosen with the property that any combination of them produces a unique sum. Hence, one could determine which integers (and therefore corresponding frequencies) contributed to that sum. The set of these integers is called the *category codes*.

For each ping, each frequency contributes to the sum (via its corresponding category code), if the Sv value for that frequency exceeds a given threshold. Otherwise, it contributes nothing.

An output ping constructed from these sums indicates which unique combination of frequencies contributed to those sums. These output pings can then be combined into an echogram for further analysis.

For example, the category codes [1, 3, 7, 13, 29] produce the following sums: 1, 3, 4, 7, 8, 10, 11, 13, 14, 16, 17, 20, 21, 23, 24, 29, 30, 32, 33, 36, 37, 39, 40, 42, 43, 45, 46, 49, 50, 52, 53. If the Sv value for all five frequencies of a ping sample exceeds the threshold, the sum for that sample is 1+3+7+13+29 = 53.

Jech and Michaels (2006) observe that spatial patterns (like the color of category code combinations) can be associated with species of interest or other acoustic objects. As such, a custom color scheme can help in visualizing the results of this method. Read the About color schemes help page, or contact support@echoview.com for assistance.

Distinct frequency single beam Sv variables.

""" Echoview Code Operator source file ======================================================================== Created by Echoview Software, for Echoview® 11.1.25 on 26 October 2020 See the Echoview help file for Code operator documentation and examples. NumPy User Guide: https://docs.scipy.org/doc/numpy/user/ NumPy Reference: https://docs.scipy.org/doc/numpy/reference/ Echoview® is a registered trademark of Echoview Software Pty Ltd. """ # Authorship information __author__ = "Echoview Software Pty Ltd. 2020." __disclaimer__ = ( "This example code is provided AS IS, without warranty of any " "kind, express or implied, including but not limited to the " "warranties of merchantability, fitness for a particular purpose " "and noninfringement. In no event shall Echoview Software Pty Ltd " "be liable for any claim, damages or other liability, arising " "from, out of or in connection with the use of this example code." ) __version__ = "1.0" # Libraries from echoview import OperatorBase, MeasurementType import numpy as np Threshold = -66.00 # dB CategoryCodes = [1, 3, 7, 13, 29] class Operator(OperatorBase): '''Multifrequency classification ==================================================================== This program generates an echogram based on the method described in Jech & Michaels (2006) for any number of operands. Distinct frequency single beam Sv variables. The length of the list, CategoryCode, determines how many operands will be processed by this Code operator. This should match the number of operands provided on the Operands page of the Variable Properties dialog box. The Code operator referencing this source file replaces 4 operators per frequency (i.e. 20 operators if there are 5 frequencies), thereby simplifying the data flow. ''' def result_type(self, input_types): '''Accepts single beam Sv operands. :param input_types: A list of OperandInput objects, one for each operand. :returns linear acoustic data. ''' for o_type in input_types: if not o_type == MeasurementType.SINGLE_BEAM_SV: raise TypeError("Sv Operands expected.") if len(input_types) > len(CategoryCodes): raise IndexError( f"More operands ({len(input_types)}) than category codes ({len(CategoryCode)}).") return MeasurementType.SINGLE_BEAM_LINEAR def eval(self, inputs): '''Given a number of single beam Sv operands, sum the category codes corresponding to the frequencies that exceeded the threshold. Note: Optimize by using NumPy vectors to process an entire ping at a time. A regular `for` loop, iterating through each datum comprising the ping, can be significantly slower. :param inputs: A list of OperandInput objects, one for each operand. :returns a list of integers, each one is the sum of the category codes of the frequencies that exceeded the threshold. ''' # Create an output ping consisting entirely of zeros to sum # category codes into. Use the first operand's input ping to # determine the size required for the output ping. summedCatCodes = np.zeros_like(inputs[0].measurement.data) # For each frequency, determine where in the input ping the Sv # is greater than or equal the threshold. If it is, accumulate # the CategoryCodes into the output ping (summedCatCodes + # catCode). Otherwise, the contribution of that frequency is 0 # (summedCatCodes). for freq, catCode in zip(inputs, CategoryCodes): summedCatCodes = np.where(freq.measurement.data >= Threshold, summedCatCodes + catCode, summedCatCodes) return summedCatCodes

Code operator

About the Code operator

Using the Code operator