afscgap.flat_model

Model implementation for prejoined Avro flat files.

(c) 2025 Regents of University of California / The Eric and Wendy Schmidt Center for Data Science and the Environment at UC Berkeley.

This file is part of afscgap released under the BSD 3-Clause License. See LICENSE.md.

  1"""
  2Model implementation for prejoined Avro flat files.
  3
  4(c) 2025 Regents of University of California / The Eric and Wendy Schmidt Center
  5for Data Science and the Environment at UC Berkeley.
  6
  7This file is part of afscgap released under the BSD 3-Clause License. See
  8LICENSE.md.
  9"""
 10import typing
 11
 12import afscgap.convert
 13import afscgap.model
 14import afscgap.param
 15
 16from afscgap.typesdef import OPT_FLOAT
 17from afscgap.typesdef import OPT_REQUESTOR
 18from afscgap.typesdef import OPT_INT
 19from afscgap.typesdef import OPT_STR
 20
 21PARAMS_DICT = typing.Dict[str, afscgap.param.Param]
 22RECORDS = typing.Iterable[afscgap.model.Record]
 23WARN_FUNCTION = typing.Optional[typing.Callable[[str], None]]
 24
 25RECORD_REQUIRED_FIELDS = [
 26    'area_swept_km2',
 27    'bottom_temperature_c',
 28    'common_name',
 29    'complete',
 30    'count',
 31    'cpue_kgkm2',
 32    'cpue_nokm2',
 33    'curise',
 34    'date_time',
 35    'depth_m',
 36    'distance_fished_km',
 37    'duration_hr',
 38    'haul',
 39    'latitude_dd_end',
 40    'latitude_dd_start',
 41    'longitude_dd_end',
 42    'longitude_dd_start',
 43    'net_height_m',
 44    'net_width_m',
 45    'scientific_name',
 46    'species_code',
 47    'srvy',
 48    'station',
 49    'stratum',
 50    'surface_temperature_c',
 51    'survey',
 52    'survey_definition_id',
 53    'taxon_confidence',
 54    'vessel_id',
 55    'vessel_name',
 56    'weight_kg',
 57    'year'
 58]
 59
 60
 61class ExecuteMetaParams:
 62    """Description of how to execute requests for prejoined Avro flat files.
 63
 64    Collection of configuration parameters of how to execute requests for pre-joined Avro flat files
 65    such as changing the server from which to request those files.
 66    """
 67
 68    def __init__(self, base_url: str, requestor: OPT_REQUESTOR, limit: OPT_INT,
 69        filter_incomplete: bool, presence_only: bool, suppress_large_warning: bool,
 70        warn_func: WARN_FUNCTION):
 71        """Create a new set of configuration values.
 72
 73        Args:
 74            base_url: The URL at which the flat files can be found over HTTPS.
 75            requestor: A requests-like requestor object to use in executing GET requests or None if
 76                to use a default.
 77            limit: The maximum number of records to return or None if all matching records should be
 78                returned.
 79            filter_incomplete: Indicate if incomplete records should be filtered out from the
 80                results set.
 81            presence_only: Indicate if only presence values are required such that zero catch
 82                inference records can be ignored.
 83            suppress_large_warning: Indiciate if the large results set warning should be suppressed,
 84                False if the user should be warned about downloading a very large dataset or True
 85                otherwise.
 86            warn_func: Function to call with a string to emit a warning.
 87        """
 88        self._base_url = base_url
 89        self._requestor = requestor
 90        self._limit = limit
 91        self._filter_incomplete = filter_incomplete
 92        self._presence_only = presence_only
 93        self._suppress_large_warning = suppress_large_warning
 94        self._warn_func = warn_func
 95
 96    def get_base_url(self) -> str:
 97        """Get the URL at which prejoined flat files can be found.
 98
 99        Returns:
100            The URL at which the flat files can be found over HTTPS.
101        """
102        return self._base_url
103
104    def get_requestor(self) -> OPT_REQUESTOR:
105        """Get the requests-like requestor object with which to retrieve records.
106
107        Returns:
108            A requests-like requestor object to use in executing GET requests or None if to use a
109            default.
110        """
111        return self._requestor
112
113    def get_limit(self) -> OPT_INT:
114        """Get the maximum number of matching records to return.
115
116        Returns:
117            The maximum number of records to return or None if all matching records should be
118            returned.
119        """
120        return self._limit
121
122    def get_filter_incomplete(self) -> bool:
123        """Get if "incomplete" records should be filtered out.
124
125        Returns:
126            Flag indicating if incomplete records should be filtered out from the results set.
127        """
128        return self._filter_incomplete
129
130    def get_presence_only(self) -> bool:
131        """Determine if zero catch inference records should be included.
132
133        Returns:
134            Indicate if only presence values are required such that zero catch inference records can
135            be ignored.
136        """
137        return self._presence_only
138
139    def get_suppress_large_warning(self) -> bool:
140        """Determine if the user should see large dataset warnings.
141
142        Returns:
143            Indiciate if the large results set warning should be suppressed, False if the user
144            should be warned about downloading a very large dataset or True otherwise.
145        """
146        return self._suppress_large_warning
147
148    def get_warn_func(self) -> WARN_FUNCTION:
149        """Get the function with which warnings may be emitted.
150
151        Returns:
152            Function to call with a string to emit a warning.
153        """
154        return self._warn_func
155
156
157class HaulKey:
158    """Record describing the key for a flat file haul.
159
160    Record describing the key for a haul within prejoined flat files which can be used in referring
161    to sets of records from a haul (catches) prior to retrieving the collection in its entirety.
162    """
163
164    def __init__(self, year: int, survey: str, haul: int):
165        """Create a new haul key record.
166
167        Args:
168            year: The year of the haul.
169            survey: The name of the survey for which the haul was conducted. This should be the full
170                name like Gulf of Alaska.
171            haul: The haul ID.
172        """
173        self._year = year
174        self._survey = survey
175        self._haul = haul
176
177    def get_year(self) -> int:
178        """Get the year in which the haul was conducted.
179
180        Returns:
181            The year of the haul.
182        """
183        return self._year
184
185    def get_survey(self) -> str:
186        """Get the name of the survey for which this haul was conducted.
187
188        Returns:
189            The name of the survey for which the haul was conducted. This should be the full name
190            like Gulf of Alaska.
191        """
192        return self._survey
193
194    def get_haul(self) -> int:
195        """Get the ID of the haul.
196
197        Returns:
198            The haul ID.
199        """
200        return self._haul
201
202    def get_key(self) -> str:
203        """Get a string uniquely identifying a haul.
204
205        Returns:
206            Unique string describing this haul.
207        """
208        return '%d_%s_%d' % (self._year, self._survey, self._haul)
209
210    def get_path(self) -> str:
211        """Get the path at which the flat file for this haul is expected.
212
213        Returns:
214            Get the URL at which the joined Avro flat file is expected to be found at the flat file
215            server.
216        """
217        return '/joined/%s.avro' % self.get_key()
218
219    def __hash__(self):
220        return hash(self.__repr__())
221
222    def __repr__(self):
223        return self.get_key()
224
225    def __eq__(self, other):
226        if isinstance(other, HaulKey):
227            return self.get_key() == other.get_key()
228        else:
229            return False
230
231    def __ne__(self, other):
232        return (not self.__eq__(other))
233
234
235HAUL_KEYS = typing.Iterable[HaulKey]
236
237
238class FlatRecord(afscgap.model.Record):
239    """Object describing the contents of a pre-joined flat Avro file."""
240
241    def __init__(self, inner):
242        """Create a new object decorating a raw parsed Avro record.
243
244        Args:
245            inner: The Avro record to decorate into a FlatRecord object, conforming to the interface
246                put forward by afscgap.model.Record.
247        """
248        self._inner = inner
249
250    def get_year(self) -> float:
251        """Get the field labeled as year in the API.
252
253        Returns:
254            Year for the survey in which this observation was made or for which
255            an inferred zero catch record was generated.
256        """
257        return self._assert_float(self._inner['year'])
258
259    def get_srvy(self) -> str:
260        """Get the field labeled as srvy in the API.
261
262        Returns:
263            The name of the survey in which this observation or inference was
264            made. NBS (N Bearing Sea), EBS (SE Bearing Sea), BSS (Bearing Sea
265            Slope), or GOA (Gulf of Alaska)
266        """
267        return self._assert_str(self._inner['srvy'])
268
269    def get_survey(self) -> str:
270        """Get the field labeled as survey in the API.
271
272        Returns:
273            Long form description of the survey in which the observation was
274            made or for which an inferred zero catch record was made.
275        """
276        return self._assert_str(self._inner['survey'])
277
278    def get_survey_id(self) -> float:
279        """Get the field labeled as survey_id in the API.
280
281        Returns:
282            Unique numeric ID for the survey.
283        """
284        return self._assert_int(self._inner['survey_definition_id'])
285
286    def get_cruise(self) -> float:
287        """Get the field labeled as cruise in the API.
288
289        Returns:
290            An ID uniquely identifying the cruise in which the observation or
291            inferrence was made. Multiple cruises in a survey.
292        """
293        return self._assert_int(self._inner['cruise'])
294
295    def get_haul(self) -> float:
296        """Get the field labeled as haul in the API.
297
298        Returns:
299            An ID uniquely identifying the haul in which this observation or
300            inference was made. Multiple hauls per cruises.
301        """
302        return self._assert_int(self._inner['haul'])
303
304    def get_stratum(self) -> float:
305        """Get the field labeled as stratum in the API.
306
307        Returns:
308            Unique ID for statistical area / survey combination as described in
309            the metadata or 0 if an experimental tow.
310        """
311        return self._assert_int(self._inner['stratum'])
312
313    def get_station(self) -> str:
314        """Get the field labeled as station in the API.
315
316        Returns:
317            Station associated with the survey.
318        """
319        return self._assert_str(self._inner['station'])
320
321    def get_vessel_name(self) -> str:
322        """Get the field labeled as vessel_name in the API.
323
324        Returns:
325            Unique ID describing the vessel that made this observation or
326            inference.
327        """
328        return self._assert_str(self._inner['vessel_name'])
329
330    def get_vessel_id(self) -> float:
331        """Get the field labeled as vessel_id in the API.
332
333        Returns:
334            Name of the vessel at the time the observation was made with
335            multiple names potentially associated with a vessel ID. May be
336            emulated in the case of inferred records
337        """
338        return self._assert_int(self._inner['vessel_id'])
339
340    def get_date_time(self) -> str:
341        """Get the field labeled as date_time in the API.
342
343        Returns:
344            The date and time of the haul which has been attempted to be
345            transformed to an ISO 8601 string without timezone info. If it
346            couldn’t be transformed, the original string is reported.
347        """
348        return self._assert_str(self._inner['date_time'])
349
350    def get_latitude_start(self, units: str = 'dd') -> float:
351        """Get the field labeled as latitude_dd_start in the API.
352
353        Args:
354            units: The units to return this value in. Only supported is dd for
355                degrees. Deafults to dd.
356
357        Returns:
358            Latitude in decimal degrees associated with the haul.
359        """
360        value = self._assert_float(self._inner['latitude_dd_start'])
361        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
362
363    def get_longitude_start(self, units: str = 'dd') -> float:
364        """Get the field labeled as longitude_dd_start in the API.
365
366        Args:
367            units: The units to return this value in. Only supported is dd for
368                degrees. Deafults to dd.
369
370        Returns:
371            Longitude in decimal degrees associated with the haul.
372        """
373        value = self._assert_float(self._inner['longitude_dd_start'])
374        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
375
376    def get_latitude(self, units: str = 'dd') -> float:
377        """Get midpoint of the haul, approximating deprecated latitude_dd field in the API.
378
379        Args:
380            units: The units to return this value in. Only supported is dd for
381                degrees. Deafults to dd.
382
383        Returns:
384            Latitude in decimal degrees associated with the haul.
385        """
386        start = self.get_latitude_start()
387        end = self.get_latitude_end()
388        mid = (start + end) / 2
389        return self._assert_float(afscgap.convert.convert(mid, 'dd', units))
390
391    def get_longitude(self, units: str = 'dd') -> float:
392        """Get midpoint of the haul, approximating deprecated longitude_dd field in the API.
393
394        Args:
395            units: The units to return this value in. Only supported is dd for
396                degrees. Deafults to dd.
397
398        Returns:
399            Longitude in decimal degrees associated with the haul.
400        """
401        start = self.get_longitude_start()
402        end = self.get_longitude_end()
403        mid = (start + end) / 2
404        return self._assert_float(afscgap.convert.convert(mid, 'dd', units))
405
406    def get_latitude_end(self, units: str = 'dd') -> float:
407        """Get the field labeled as latitude_dd_end in the API.
408
409        Args:
410            units: The units to return this value in. Only supported is dd for
411                degrees. Deafults to dd.
412
413        Returns:
414            Latitude in decimal degrees associated with the haul.
415        """
416        value = self._assert_float(self._inner['latitude_dd_end'])
417        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
418
419    def get_longitude_end(self, units: str = 'dd') -> float:
420        """Get the field labeled as longitude_dd_end in the API.
421
422        Args:
423            units: The units to return this value in. Only supported is dd for
424                degrees. Deafults to dd.
425
426        Returns:
427            Longitude in decimal degrees associated with the haul.
428        """
429        value = self._assert_float(self._inner['longitude_dd_end'])
430        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
431
432    def get_species_code(self) -> OPT_FLOAT:
433        """Get the field labeled as species_code in the API.
434
435        Returns:
436            Unique ID associated with the species observed or for which a zero
437            catch record was inferred.
438        """
439        return self._assert_int_maybe(self._inner['species_code'])
440
441    def get_common_name(self) -> OPT_STR:
442        """Get the field labeled as common_name in the API.
443
444        Returns:
445            The “common name” associated with the species observed or for which
446            a zero catch record was inferred. Example: Pacific glass shrimp.
447        """
448        return self._assert_str_maybe(self._inner['common_name'])
449
450    def get_scientific_name(self) -> OPT_STR:
451        """Get the field labeled as scientific_name in the API.
452
453        Returns:
454            The “scientific name” associated with the species observed or for
455            which a zero catch record was inferred. Example: Pasiphaea pacifica.
456        """
457        value = self._inner['scientific_name']
458        return self._assert_str_maybe(value)
459
460    def get_taxon_confidence(self) -> OPT_STR:
461        """Get the field labeled as taxon_confidence in the API.
462
463        Returns:
464            Confidence flag regarding ability to identify species (High,
465            Moderate, Low). In practice, this can also be Unassessed.
466        """
467        return self._assert_str_maybe(self._inner['taxon_confidence'])
468
469    def get_cpue_weight_maybe(self, units: str = 'kg/ha') -> OPT_FLOAT:
470        """Get a field labeled as cpue_* in the API.
471
472        Args:
473            units: The desired units for the catch per unit effort. Options:
474                kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
475
476        Returns:
477            Catch weight divided by net area (in given units) if available. See
478            metadata. None if could not interpret as a float. If an inferred
479            zero catch record, will be zero.
480        """
481        value = self._inner['cpue_kgkm2']
482
483        if value is None:
484            return None
485
486        return afscgap.convert.convert(value, 'kg/km2', units)
487
488    def get_cpue_count_maybe(self, units: str = 'count/ha') -> OPT_FLOAT:
489        """Get the field labeled as cpue_* in the API.
490
491        Get the catch per unit effort from the record with one of the following
492        units: kg/ha, kg/km2, kg1000/km2.
493
494        Args:
495            units: The desired units for the catch per unit effort. Options:
496                count/ha, count/km2, and count1000/km2. Defaults to count/ha.
497
498        Returns:
499            Catch weight divided by net area (in given units) if available. See
500            metadata. None if could not interpret as a float. If an inferred
501            zero catch record, will be zero.
502        """
503        value = self._inner['cpue_nokm2']
504
505        if value is None:
506            return None
507
508        return afscgap.convert.convert(value, 'no/km2', units)
509
510    def get_weight_maybe(self, units: str = 'kg') -> OPT_FLOAT:
511        """Get the field labeled as weight_kg in the API.
512
513        Args:
514            units: The units in which the weight should be returned. Options are
515                g, kg for grams and kilograms respectively. Deafults to kg.
516
517        Returns:
518            Taxon weight if available. See metadata. None if could not
519            interpret as a float. If an inferred zero catch record, will be
520            zero.
521        """
522        value = self._inner['weight_kg']
523
524        if value is None:
525            return None
526
527        return afscgap.convert.convert(value, 'kg', units)
528
529    def get_count_maybe(self) -> OPT_FLOAT:
530        """Get the field labeled as count in the API.
531
532        Returns:
533            Total number of organism individuals in haul. None if could not
534            interpret as a float. If an inferred zero catch record, will be
535            zero.
536        """
537        return self._inner['count']
538
539    def get_bottom_temperature_maybe(self, units: str = 'c') -> OPT_FLOAT:
540        """Get the field labeled as bottom_temperature_c in the API.
541
542        Args:
543            units: The units in which the temperature should be returned.
544                Options: c or f for Celcius and Fahrenheit respectively.
545                Defaults to c.
546
547        Returns:
548            Bottom temperature associated with observation / inferrence if
549            available in desired units. None if not given or could not interpret
550            as a float.
551        """
552        value = self._inner['bottom_temperature_c']
553
554        if value is None:
555            return None
556
557        return afscgap.convert.convert(value, 'c', units)
558
559    def get_surface_temperature_maybe(self, units: str = 'c') -> OPT_FLOAT:
560        """Get the field labeled as surface_temperature_c in the API.
561
562        Args:
563            units: The units in which the temperature should be returned.
564                Options: c or f for Celcius and Fahrenheit respectively.
565                Defaults to c.
566
567        Returns:
568            Surface temperature associated with observation / inferrence if
569            available. None if not given or could not interpret as a float.
570        """
571        value = self._inner['surface_temperature_c']
572
573        if value is None:
574            return None
575
576        return afscgap.convert.convert(value, 'c', units)
577
578    def get_depth(self, units: str = 'm') -> float:
579        """Get the field labeled as depth_m in the API.
580
581        Args:
582            units: The units in which the distance should be returned. Options:
583                m or km for meters and kilometers respectively. Defaults to m.
584
585        Returns:
586            Depth of the bottom.
587        """
588        value = self._assert_float(self._inner['depth_m'])
589        return self._assert_float(afscgap.convert.convert(value, 'm', units))
590
591    def get_distance_fished(self, units: str = 'm') -> float:
592        """Get the field labeled as distance_fished_km in the API.
593
594        Args:
595            units: The units in which the distance should be returned. Options:
596                m or km for meters and kilometers respectively. Defaults to m.
597
598        Returns:
599            Distance of the net fished.
600        """
601        value = self._assert_float(self._inner['distance_fished_km'])
602        return self._assert_float(afscgap.convert.convert(value, 'km', units))
603
604    def get_net_width(self, units: str = 'm') -> float:
605        """Get the field labeled as net_width_m in the API.
606
607        Args:
608            units: The units in which the distance should be returned. Options:
609                m or km for meters and kilometers respectively. Defaults to m.
610
611        Returns:
612            Distance of the net fished after asserting it is given.
613        """
614        value = self._assert_float(self._inner['net_width_m'])
615        return self._assert_float(afscgap.convert.convert(value, 'm', units))
616
617    def get_net_height(self, units: str = 'm') -> float:
618        """Get the field labeled as net_height_m in the API.
619
620        Args:
621            units: The units in which the distance should be returned. Options:
622                m or km for meters and kilometers respectively. Defaults to m.
623
624        Returns:
625            Height of the net fished after asserting it is given.
626        """
627        value = self._assert_float(self._inner['net_height_m'])
628        return self._assert_float(afscgap.convert.convert(value, 'm', units))
629
630    def get_net_width_maybe(self, units: str = 'm') -> OPT_FLOAT:
631        """Get the field labeled as net_width_m in the API.
632
633        Args:
634            units: The units in which the distance should be returned. Options:
635                m or km for meters and kilometers respectively. Defaults to m.
636
637        Returns:
638            Distance of the net fished or None if not given.
639        """
640        value = self._inner['net_width_m']
641
642        if value is None:
643            return None
644
645        return afscgap.convert.convert(value, 'm', units)
646
647    def get_net_height_maybe(self, units: str = 'm') -> OPT_FLOAT:
648        """Get the field labeled as net_height_m in the API.
649
650        Args:
651            units: The units in which the distance should be returned. Options:
652                m or km for meters and kilometers respectively. Defaults to m.
653
654        Returns:
655            Height of the net fished or None if not given.
656        """
657        value = self._inner['net_height_m']
658
659        if value is None:
660            return None
661
662        return afscgap.convert.convert(value, 'm', units)
663
664    def get_area_swept(self, units: str = 'ha') -> float:
665        """Get the field labeled as area_swept_ha in the API.
666
667        Args:
668            units: The units in which the area should be returned. Options:
669                ha, m2, km2. Defaults to ha.
670
671        Returns:
672            Area covered by the net while fishing in desired units.
673        """
674        value = self._assert_float(self._inner['area_swept_km2'])
675        return self._assert_float(afscgap.convert.convert(value, 'km2', units))
676
677    def get_duration(self, units: str = 'hr') -> float:
678        """Get the field labeled as duration_hr in the API.
679
680        Args:
681            units: The units in which the duration should be returned. Options:
682                day, hr, min. Defaults to hr.
683
684        Returns:
685            Duration of the haul.
686        """
687        value = self._assert_float(self._inner['duration_hr'])
688        return self._assert_float(afscgap.convert.convert(value, 'hr', units))
689
690    def get_cpue_weight(self, units: str = 'kg/ha') -> float:
691        """Get the value of field cpue_kgha with validity assert.
692
693        Args:
694            units: The desired units for the catch per unit effort. Options:
695                kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
696
697        Raises:
698            AssertionError: Raised if this field was not given by the API or
699            could not be parsed as expected.
700
701        Returns:
702            Catch weight divided by net area (kg / hectares) if available. See
703            metadata. Will be zero if a zero catch record.
704        """
705        value = self._assert_float(self._inner['cpue_kgkm2'])
706        return self._assert_float(afscgap.convert.convert(value, 'kg/km2', units))
707
708    def get_cpue_count(self, units: str = 'count/ha') -> float:
709        """Get the value of field cpue_noha with validity assert.
710
711        Args:
712            units: The desired units for the catch per unit effort. Options:
713                count/ha, count/km2, and count1000/km2. Defaults to count/ha.
714
715        Raises:
716            AssertionError: Raised if this field was not given by the API or
717            could not be parsed as expected.
718
719        Returns:
720            Catch number divided by net sweep area if available (count /
721            hectares). See metadata. Will be zero if a zero catch record.
722        """
723        value = self._assert_float(self._inner['cpue_nokm2'])
724        return self._assert_float(afscgap.convert.convert(value, 'no/km2', units))
725
726    def get_weight(self, units: str = 'kg') -> float:
727        """Get the value of field weight_kg with validity assert.
728
729        Args:
730            units: The units in which the weight should be returned. Options are
731                g, kg for grams and kilograms respectively. Deafults to kg.
732
733        Raises:
734            AssertionError: Raised if this field was not given by the API or
735            could not be parsed as expected.
736
737        Returns:
738            Taxon weight (kg) if available. See metadata. Will be zero if a zero
739            catch record.
740        """
741        value = self._assert_float(self._inner['weight_kg'])
742        return self._assert_float(afscgap.convert.convert(value, 'kg', units))
743
744    def get_count(self) -> float:
745        """Get the value of field count with validity assert.
746
747        Raises:
748            AssertionError: Raised if this field was not given by the API or
749            could not be parsed as expected.
750
751        Returns:
752            Total number of organism individuals in haul. Will be zero if a zero
753            catch record.
754        """
755        return self._assert_int(self._inner['count'])
756
757    def get_bottom_temperature(self, units='c') -> float:
758        """Get the value of field bottom_temperature_c with validity assert.
759
760        Args:
761            units: The units in which the temperature should be returned.
762                Options: c or f for Celcius and Fahrenheit respectively.
763                Defaults to c.
764
765        Raises:
766            AssertionError: Raised if this field was not given by the API or
767            could not be parsed as expected.
768
769        Returns:
770            Bottom temperature associated with observation / inferrence if
771            available.
772        """
773        value = self._assert_float(self._inner['bottom_temperature_c'])
774        return self._assert_float(afscgap.convert.convert(value, 'c', units))
775
776    def get_surface_temperature(self, units='c') -> float:
777        """Get the value of field surface_temperature_c with validity assert.
778
779        Args:
780            units: The units in which the temperature should be returned.
781                Options: c or f for Celcius and Fahrenheit respectively.
782                Defaults to c.
783
784        Raises:
785            AssertionError: Raised if this field was not given by the API or
786            could not be parsed as expected.
787
788        Returns:
789            Surface temperature associated with observation / inferrence if
790            available.
791        """
792        value = self._assert_float(self._inner['surface_temperature_c'])
793        return self._assert_float(afscgap.convert.convert(value, 'c', units))
794
795    def is_complete(self) -> bool:
796        """Determine if this record has all of its values filled in.
797
798        Returns:
799            True if all optional fields have a parsed value with the expected
800            type and false otherwise.
801        """
802        if not self._inner['complete']:
803            return False
804
805        fields_missing = filter(lambda x: self._inner.get(x, None) is None, RECORD_REQUIRED_FIELDS)
806        num_missing = sum(map(lambda x: 1, fields_missing))
807        return num_missing == 0
808
809    def get_inner(self):
810        """Get the raw parsed Avro payload.
811
812        Returns:
813            The raw parsed Avro payload.
814        """
815        return self._inner
816
817    def _assert_float(self, target) -> float:
818        assert target is not None
819        return float(target)
820
821    def _assert_float_maybe(self, target) -> OPT_FLOAT:
822        return None if target is None else float(target)
823
824    def _assert_str(self, target) -> str:
825        assert target is not None
826        return str(target)
827
828    def _assert_str_maybe(self, target) -> OPT_STR:
829        return None if target is None else str(target)
830
831    def _assert_int(self, target) -> int:
832        assert target is not None
833        return int(target)
834
835    def _assert_int_maybe(self, target) -> OPT_INT:
836        return None if target is None else int(target)
PARAMS_DICT = typing.Dict[str, afscgap.param.Param]
RECORDS = typing.Iterable[afscgap.model.Record]
WARN_FUNCTION = typing.Optional[typing.Callable[[str], NoneType]]
RECORD_REQUIRED_FIELDS = ['area_swept_km2', 'bottom_temperature_c', 'common_name', 'complete', 'count', 'cpue_kgkm2', 'cpue_nokm2', 'curise', 'date_time', 'depth_m', 'distance_fished_km', 'duration_hr', 'haul', 'latitude_dd_end', 'latitude_dd_start', 'longitude_dd_end', 'longitude_dd_start', 'net_height_m', 'net_width_m', 'scientific_name', 'species_code', 'srvy', 'station', 'stratum', 'surface_temperature_c', 'survey', 'survey_definition_id', 'taxon_confidence', 'vessel_id', 'vessel_name', 'weight_kg', 'year']
class ExecuteMetaParams:
 62class ExecuteMetaParams:
 63    """Description of how to execute requests for prejoined Avro flat files.
 64
 65    Collection of configuration parameters of how to execute requests for pre-joined Avro flat files
 66    such as changing the server from which to request those files.
 67    """
 68
 69    def __init__(self, base_url: str, requestor: OPT_REQUESTOR, limit: OPT_INT,
 70        filter_incomplete: bool, presence_only: bool, suppress_large_warning: bool,
 71        warn_func: WARN_FUNCTION):
 72        """Create a new set of configuration values.
 73
 74        Args:
 75            base_url: The URL at which the flat files can be found over HTTPS.
 76            requestor: A requests-like requestor object to use in executing GET requests or None if
 77                to use a default.
 78            limit: The maximum number of records to return or None if all matching records should be
 79                returned.
 80            filter_incomplete: Indicate if incomplete records should be filtered out from the
 81                results set.
 82            presence_only: Indicate if only presence values are required such that zero catch
 83                inference records can be ignored.
 84            suppress_large_warning: Indiciate if the large results set warning should be suppressed,
 85                False if the user should be warned about downloading a very large dataset or True
 86                otherwise.
 87            warn_func: Function to call with a string to emit a warning.
 88        """
 89        self._base_url = base_url
 90        self._requestor = requestor
 91        self._limit = limit
 92        self._filter_incomplete = filter_incomplete
 93        self._presence_only = presence_only
 94        self._suppress_large_warning = suppress_large_warning
 95        self._warn_func = warn_func
 96
 97    def get_base_url(self) -> str:
 98        """Get the URL at which prejoined flat files can be found.
 99
100        Returns:
101            The URL at which the flat files can be found over HTTPS.
102        """
103        return self._base_url
104
105    def get_requestor(self) -> OPT_REQUESTOR:
106        """Get the requests-like requestor object with which to retrieve records.
107
108        Returns:
109            A requests-like requestor object to use in executing GET requests or None if to use a
110            default.
111        """
112        return self._requestor
113
114    def get_limit(self) -> OPT_INT:
115        """Get the maximum number of matching records to return.
116
117        Returns:
118            The maximum number of records to return or None if all matching records should be
119            returned.
120        """
121        return self._limit
122
123    def get_filter_incomplete(self) -> bool:
124        """Get if "incomplete" records should be filtered out.
125
126        Returns:
127            Flag indicating if incomplete records should be filtered out from the results set.
128        """
129        return self._filter_incomplete
130
131    def get_presence_only(self) -> bool:
132        """Determine if zero catch inference records should be included.
133
134        Returns:
135            Indicate if only presence values are required such that zero catch inference records can
136            be ignored.
137        """
138        return self._presence_only
139
140    def get_suppress_large_warning(self) -> bool:
141        """Determine if the user should see large dataset warnings.
142
143        Returns:
144            Indiciate if the large results set warning should be suppressed, False if the user
145            should be warned about downloading a very large dataset or True otherwise.
146        """
147        return self._suppress_large_warning
148
149    def get_warn_func(self) -> WARN_FUNCTION:
150        """Get the function with which warnings may be emitted.
151
152        Returns:
153            Function to call with a string to emit a warning.
154        """
155        return self._warn_func

Description of how to execute requests for prejoined Avro flat files.

Collection of configuration parameters of how to execute requests for pre-joined Avro flat files such as changing the server from which to request those files.

ExecuteMetaParams( base_url: str, requestor: Optional[Callable[[str], requests.models.Response]], limit: Optional[int], filter_incomplete: bool, presence_only: bool, suppress_large_warning: bool, warn_func: Optional[Callable[[str], NoneType]])
69    def __init__(self, base_url: str, requestor: OPT_REQUESTOR, limit: OPT_INT,
70        filter_incomplete: bool, presence_only: bool, suppress_large_warning: bool,
71        warn_func: WARN_FUNCTION):
72        """Create a new set of configuration values.
73
74        Args:
75            base_url: The URL at which the flat files can be found over HTTPS.
76            requestor: A requests-like requestor object to use in executing GET requests or None if
77                to use a default.
78            limit: The maximum number of records to return or None if all matching records should be
79                returned.
80            filter_incomplete: Indicate if incomplete records should be filtered out from the
81                results set.
82            presence_only: Indicate if only presence values are required such that zero catch
83                inference records can be ignored.
84            suppress_large_warning: Indiciate if the large results set warning should be suppressed,
85                False if the user should be warned about downloading a very large dataset or True
86                otherwise.
87            warn_func: Function to call with a string to emit a warning.
88        """
89        self._base_url = base_url
90        self._requestor = requestor
91        self._limit = limit
92        self._filter_incomplete = filter_incomplete
93        self._presence_only = presence_only
94        self._suppress_large_warning = suppress_large_warning
95        self._warn_func = warn_func

Create a new set of configuration values.

Arguments:
  • base_url: The URL at which the flat files can be found over HTTPS.
  • requestor: A requests-like requestor object to use in executing GET requests or None if to use a default.
  • limit: The maximum number of records to return or None if all matching records should be returned.
  • filter_incomplete: Indicate if incomplete records should be filtered out from the results set.
  • presence_only: Indicate if only presence values are required such that zero catch inference records can be ignored.
  • suppress_large_warning: Indiciate if the large results set warning should be suppressed, False if the user should be warned about downloading a very large dataset or True otherwise.
  • warn_func: Function to call with a string to emit a warning.
def get_base_url(self) -> str:
 97    def get_base_url(self) -> str:
 98        """Get the URL at which prejoined flat files can be found.
 99
100        Returns:
101            The URL at which the flat files can be found over HTTPS.
102        """
103        return self._base_url

Get the URL at which prejoined flat files can be found.

Returns:

The URL at which the flat files can be found over HTTPS.

def get_requestor(self) -> Optional[Callable[[str], requests.models.Response]]:
105    def get_requestor(self) -> OPT_REQUESTOR:
106        """Get the requests-like requestor object with which to retrieve records.
107
108        Returns:
109            A requests-like requestor object to use in executing GET requests or None if to use a
110            default.
111        """
112        return self._requestor

Get the requests-like requestor object with which to retrieve records.

Returns:

A requests-like requestor object to use in executing GET requests or None if to use a default.

def get_limit(self) -> Optional[int]:
114    def get_limit(self) -> OPT_INT:
115        """Get the maximum number of matching records to return.
116
117        Returns:
118            The maximum number of records to return or None if all matching records should be
119            returned.
120        """
121        return self._limit

Get the maximum number of matching records to return.

Returns:

The maximum number of records to return or None if all matching records should be returned.

def get_filter_incomplete(self) -> bool:
123    def get_filter_incomplete(self) -> bool:
124        """Get if "incomplete" records should be filtered out.
125
126        Returns:
127            Flag indicating if incomplete records should be filtered out from the results set.
128        """
129        return self._filter_incomplete

Get if "incomplete" records should be filtered out.

Returns:

Flag indicating if incomplete records should be filtered out from the results set.

def get_presence_only(self) -> bool:
131    def get_presence_only(self) -> bool:
132        """Determine if zero catch inference records should be included.
133
134        Returns:
135            Indicate if only presence values are required such that zero catch inference records can
136            be ignored.
137        """
138        return self._presence_only

Determine if zero catch inference records should be included.

Returns:

Indicate if only presence values are required such that zero catch inference records can be ignored.

def get_suppress_large_warning(self) -> bool:
140    def get_suppress_large_warning(self) -> bool:
141        """Determine if the user should see large dataset warnings.
142
143        Returns:
144            Indiciate if the large results set warning should be suppressed, False if the user
145            should be warned about downloading a very large dataset or True otherwise.
146        """
147        return self._suppress_large_warning

Determine if the user should see large dataset warnings.

Returns:

Indiciate if the large results set warning should be suppressed, False if the user should be warned about downloading a very large dataset or True otherwise.

def get_warn_func(self) -> Optional[Callable[[str], NoneType]]:
149    def get_warn_func(self) -> WARN_FUNCTION:
150        """Get the function with which warnings may be emitted.
151
152        Returns:
153            Function to call with a string to emit a warning.
154        """
155        return self._warn_func

Get the function with which warnings may be emitted.

Returns:

Function to call with a string to emit a warning.

class HaulKey:
158class HaulKey:
159    """Record describing the key for a flat file haul.
160
161    Record describing the key for a haul within prejoined flat files which can be used in referring
162    to sets of records from a haul (catches) prior to retrieving the collection in its entirety.
163    """
164
165    def __init__(self, year: int, survey: str, haul: int):
166        """Create a new haul key record.
167
168        Args:
169            year: The year of the haul.
170            survey: The name of the survey for which the haul was conducted. This should be the full
171                name like Gulf of Alaska.
172            haul: The haul ID.
173        """
174        self._year = year
175        self._survey = survey
176        self._haul = haul
177
178    def get_year(self) -> int:
179        """Get the year in which the haul was conducted.
180
181        Returns:
182            The year of the haul.
183        """
184        return self._year
185
186    def get_survey(self) -> str:
187        """Get the name of the survey for which this haul was conducted.
188
189        Returns:
190            The name of the survey for which the haul was conducted. This should be the full name
191            like Gulf of Alaska.
192        """
193        return self._survey
194
195    def get_haul(self) -> int:
196        """Get the ID of the haul.
197
198        Returns:
199            The haul ID.
200        """
201        return self._haul
202
203    def get_key(self) -> str:
204        """Get a string uniquely identifying a haul.
205
206        Returns:
207            Unique string describing this haul.
208        """
209        return '%d_%s_%d' % (self._year, self._survey, self._haul)
210
211    def get_path(self) -> str:
212        """Get the path at which the flat file for this haul is expected.
213
214        Returns:
215            Get the URL at which the joined Avro flat file is expected to be found at the flat file
216            server.
217        """
218        return '/joined/%s.avro' % self.get_key()
219
220    def __hash__(self):
221        return hash(self.__repr__())
222
223    def __repr__(self):
224        return self.get_key()
225
226    def __eq__(self, other):
227        if isinstance(other, HaulKey):
228            return self.get_key() == other.get_key()
229        else:
230            return False
231
232    def __ne__(self, other):
233        return (not self.__eq__(other))

Record describing the key for a flat file haul.

Record describing the key for a haul within prejoined flat files which can be used in referring to sets of records from a haul (catches) prior to retrieving the collection in its entirety.

HaulKey(year: int, survey: str, haul: int)
165    def __init__(self, year: int, survey: str, haul: int):
166        """Create a new haul key record.
167
168        Args:
169            year: The year of the haul.
170            survey: The name of the survey for which the haul was conducted. This should be the full
171                name like Gulf of Alaska.
172            haul: The haul ID.
173        """
174        self._year = year
175        self._survey = survey
176        self._haul = haul

Create a new haul key record.

Arguments:
  • year: The year of the haul.
  • survey: The name of the survey for which the haul was conducted. This should be the full name like Gulf of Alaska.
  • haul: The haul ID.
def get_year(self) -> int:
178    def get_year(self) -> int:
179        """Get the year in which the haul was conducted.
180
181        Returns:
182            The year of the haul.
183        """
184        return self._year

Get the year in which the haul was conducted.

Returns:

The year of the haul.

def get_survey(self) -> str:
186    def get_survey(self) -> str:
187        """Get the name of the survey for which this haul was conducted.
188
189        Returns:
190            The name of the survey for which the haul was conducted. This should be the full name
191            like Gulf of Alaska.
192        """
193        return self._survey

Get the name of the survey for which this haul was conducted.

Returns:

The name of the survey for which the haul was conducted. This should be the full name like Gulf of Alaska.

def get_haul(self) -> int:
195    def get_haul(self) -> int:
196        """Get the ID of the haul.
197
198        Returns:
199            The haul ID.
200        """
201        return self._haul

Get the ID of the haul.

Returns:

The haul ID.

def get_key(self) -> str:
203    def get_key(self) -> str:
204        """Get a string uniquely identifying a haul.
205
206        Returns:
207            Unique string describing this haul.
208        """
209        return '%d_%s_%d' % (self._year, self._survey, self._haul)

Get a string uniquely identifying a haul.

Returns:

Unique string describing this haul.

def get_path(self) -> str:
211    def get_path(self) -> str:
212        """Get the path at which the flat file for this haul is expected.
213
214        Returns:
215            Get the URL at which the joined Avro flat file is expected to be found at the flat file
216            server.
217        """
218        return '/joined/%s.avro' % self.get_key()

Get the path at which the flat file for this haul is expected.

Returns:

Get the URL at which the joined Avro flat file is expected to be found at the flat file server.

HAUL_KEYS = typing.Iterable[HaulKey]
class FlatRecord(afscgap.model.Record):
239class FlatRecord(afscgap.model.Record):
240    """Object describing the contents of a pre-joined flat Avro file."""
241
242    def __init__(self, inner):
243        """Create a new object decorating a raw parsed Avro record.
244
245        Args:
246            inner: The Avro record to decorate into a FlatRecord object, conforming to the interface
247                put forward by afscgap.model.Record.
248        """
249        self._inner = inner
250
251    def get_year(self) -> float:
252        """Get the field labeled as year in the API.
253
254        Returns:
255            Year for the survey in which this observation was made or for which
256            an inferred zero catch record was generated.
257        """
258        return self._assert_float(self._inner['year'])
259
260    def get_srvy(self) -> str:
261        """Get the field labeled as srvy in the API.
262
263        Returns:
264            The name of the survey in which this observation or inference was
265            made. NBS (N Bearing Sea), EBS (SE Bearing Sea), BSS (Bearing Sea
266            Slope), or GOA (Gulf of Alaska)
267        """
268        return self._assert_str(self._inner['srvy'])
269
270    def get_survey(self) -> str:
271        """Get the field labeled as survey in the API.
272
273        Returns:
274            Long form description of the survey in which the observation was
275            made or for which an inferred zero catch record was made.
276        """
277        return self._assert_str(self._inner['survey'])
278
279    def get_survey_id(self) -> float:
280        """Get the field labeled as survey_id in the API.
281
282        Returns:
283            Unique numeric ID for the survey.
284        """
285        return self._assert_int(self._inner['survey_definition_id'])
286
287    def get_cruise(self) -> float:
288        """Get the field labeled as cruise in the API.
289
290        Returns:
291            An ID uniquely identifying the cruise in which the observation or
292            inferrence was made. Multiple cruises in a survey.
293        """
294        return self._assert_int(self._inner['cruise'])
295
296    def get_haul(self) -> float:
297        """Get the field labeled as haul in the API.
298
299        Returns:
300            An ID uniquely identifying the haul in which this observation or
301            inference was made. Multiple hauls per cruises.
302        """
303        return self._assert_int(self._inner['haul'])
304
305    def get_stratum(self) -> float:
306        """Get the field labeled as stratum in the API.
307
308        Returns:
309            Unique ID for statistical area / survey combination as described in
310            the metadata or 0 if an experimental tow.
311        """
312        return self._assert_int(self._inner['stratum'])
313
314    def get_station(self) -> str:
315        """Get the field labeled as station in the API.
316
317        Returns:
318            Station associated with the survey.
319        """
320        return self._assert_str(self._inner['station'])
321
322    def get_vessel_name(self) -> str:
323        """Get the field labeled as vessel_name in the API.
324
325        Returns:
326            Unique ID describing the vessel that made this observation or
327            inference.
328        """
329        return self._assert_str(self._inner['vessel_name'])
330
331    def get_vessel_id(self) -> float:
332        """Get the field labeled as vessel_id in the API.
333
334        Returns:
335            Name of the vessel at the time the observation was made with
336            multiple names potentially associated with a vessel ID. May be
337            emulated in the case of inferred records
338        """
339        return self._assert_int(self._inner['vessel_id'])
340
341    def get_date_time(self) -> str:
342        """Get the field labeled as date_time in the API.
343
344        Returns:
345            The date and time of the haul which has been attempted to be
346            transformed to an ISO 8601 string without timezone info. If it
347            couldn’t be transformed, the original string is reported.
348        """
349        return self._assert_str(self._inner['date_time'])
350
351    def get_latitude_start(self, units: str = 'dd') -> float:
352        """Get the field labeled as latitude_dd_start in the API.
353
354        Args:
355            units: The units to return this value in. Only supported is dd for
356                degrees. Deafults to dd.
357
358        Returns:
359            Latitude in decimal degrees associated with the haul.
360        """
361        value = self._assert_float(self._inner['latitude_dd_start'])
362        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
363
364    def get_longitude_start(self, units: str = 'dd') -> float:
365        """Get the field labeled as longitude_dd_start in the API.
366
367        Args:
368            units: The units to return this value in. Only supported is dd for
369                degrees. Deafults to dd.
370
371        Returns:
372            Longitude in decimal degrees associated with the haul.
373        """
374        value = self._assert_float(self._inner['longitude_dd_start'])
375        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
376
377    def get_latitude(self, units: str = 'dd') -> float:
378        """Get midpoint of the haul, approximating deprecated latitude_dd field in the API.
379
380        Args:
381            units: The units to return this value in. Only supported is dd for
382                degrees. Deafults to dd.
383
384        Returns:
385            Latitude in decimal degrees associated with the haul.
386        """
387        start = self.get_latitude_start()
388        end = self.get_latitude_end()
389        mid = (start + end) / 2
390        return self._assert_float(afscgap.convert.convert(mid, 'dd', units))
391
392    def get_longitude(self, units: str = 'dd') -> float:
393        """Get midpoint of the haul, approximating deprecated longitude_dd field in the API.
394
395        Args:
396            units: The units to return this value in. Only supported is dd for
397                degrees. Deafults to dd.
398
399        Returns:
400            Longitude in decimal degrees associated with the haul.
401        """
402        start = self.get_longitude_start()
403        end = self.get_longitude_end()
404        mid = (start + end) / 2
405        return self._assert_float(afscgap.convert.convert(mid, 'dd', units))
406
407    def get_latitude_end(self, units: str = 'dd') -> float:
408        """Get the field labeled as latitude_dd_end in the API.
409
410        Args:
411            units: The units to return this value in. Only supported is dd for
412                degrees. Deafults to dd.
413
414        Returns:
415            Latitude in decimal degrees associated with the haul.
416        """
417        value = self._assert_float(self._inner['latitude_dd_end'])
418        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
419
420    def get_longitude_end(self, units: str = 'dd') -> float:
421        """Get the field labeled as longitude_dd_end in the API.
422
423        Args:
424            units: The units to return this value in. Only supported is dd for
425                degrees. Deafults to dd.
426
427        Returns:
428            Longitude in decimal degrees associated with the haul.
429        """
430        value = self._assert_float(self._inner['longitude_dd_end'])
431        return self._assert_float(afscgap.convert.convert(value, 'dd', units))
432
433    def get_species_code(self) -> OPT_FLOAT:
434        """Get the field labeled as species_code in the API.
435
436        Returns:
437            Unique ID associated with the species observed or for which a zero
438            catch record was inferred.
439        """
440        return self._assert_int_maybe(self._inner['species_code'])
441
442    def get_common_name(self) -> OPT_STR:
443        """Get the field labeled as common_name in the API.
444
445        Returns:
446            The “common name” associated with the species observed or for which
447            a zero catch record was inferred. Example: Pacific glass shrimp.
448        """
449        return self._assert_str_maybe(self._inner['common_name'])
450
451    def get_scientific_name(self) -> OPT_STR:
452        """Get the field labeled as scientific_name in the API.
453
454        Returns:
455            The “scientific name” associated with the species observed or for
456            which a zero catch record was inferred. Example: Pasiphaea pacifica.
457        """
458        value = self._inner['scientific_name']
459        return self._assert_str_maybe(value)
460
461    def get_taxon_confidence(self) -> OPT_STR:
462        """Get the field labeled as taxon_confidence in the API.
463
464        Returns:
465            Confidence flag regarding ability to identify species (High,
466            Moderate, Low). In practice, this can also be Unassessed.
467        """
468        return self._assert_str_maybe(self._inner['taxon_confidence'])
469
470    def get_cpue_weight_maybe(self, units: str = 'kg/ha') -> OPT_FLOAT:
471        """Get a field labeled as cpue_* in the API.
472
473        Args:
474            units: The desired units for the catch per unit effort. Options:
475                kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
476
477        Returns:
478            Catch weight divided by net area (in given units) if available. See
479            metadata. None if could not interpret as a float. If an inferred
480            zero catch record, will be zero.
481        """
482        value = self._inner['cpue_kgkm2']
483
484        if value is None:
485            return None
486
487        return afscgap.convert.convert(value, 'kg/km2', units)
488
489    def get_cpue_count_maybe(self, units: str = 'count/ha') -> OPT_FLOAT:
490        """Get the field labeled as cpue_* in the API.
491
492        Get the catch per unit effort from the record with one of the following
493        units: kg/ha, kg/km2, kg1000/km2.
494
495        Args:
496            units: The desired units for the catch per unit effort. Options:
497                count/ha, count/km2, and count1000/km2. Defaults to count/ha.
498
499        Returns:
500            Catch weight divided by net area (in given units) if available. See
501            metadata. None if could not interpret as a float. If an inferred
502            zero catch record, will be zero.
503        """
504        value = self._inner['cpue_nokm2']
505
506        if value is None:
507            return None
508
509        return afscgap.convert.convert(value, 'no/km2', units)
510
511    def get_weight_maybe(self, units: str = 'kg') -> OPT_FLOAT:
512        """Get the field labeled as weight_kg in the API.
513
514        Args:
515            units: The units in which the weight should be returned. Options are
516                g, kg for grams and kilograms respectively. Deafults to kg.
517
518        Returns:
519            Taxon weight if available. See metadata. None if could not
520            interpret as a float. If an inferred zero catch record, will be
521            zero.
522        """
523        value = self._inner['weight_kg']
524
525        if value is None:
526            return None
527
528        return afscgap.convert.convert(value, 'kg', units)
529
530    def get_count_maybe(self) -> OPT_FLOAT:
531        """Get the field labeled as count in the API.
532
533        Returns:
534            Total number of organism individuals in haul. None if could not
535            interpret as a float. If an inferred zero catch record, will be
536            zero.
537        """
538        return self._inner['count']
539
540    def get_bottom_temperature_maybe(self, units: str = 'c') -> OPT_FLOAT:
541        """Get the field labeled as bottom_temperature_c in the API.
542
543        Args:
544            units: The units in which the temperature should be returned.
545                Options: c or f for Celcius and Fahrenheit respectively.
546                Defaults to c.
547
548        Returns:
549            Bottom temperature associated with observation / inferrence if
550            available in desired units. None if not given or could not interpret
551            as a float.
552        """
553        value = self._inner['bottom_temperature_c']
554
555        if value is None:
556            return None
557
558        return afscgap.convert.convert(value, 'c', units)
559
560    def get_surface_temperature_maybe(self, units: str = 'c') -> OPT_FLOAT:
561        """Get the field labeled as surface_temperature_c in the API.
562
563        Args:
564            units: The units in which the temperature should be returned.
565                Options: c or f for Celcius and Fahrenheit respectively.
566                Defaults to c.
567
568        Returns:
569            Surface temperature associated with observation / inferrence if
570            available. None if not given or could not interpret as a float.
571        """
572        value = self._inner['surface_temperature_c']
573
574        if value is None:
575            return None
576
577        return afscgap.convert.convert(value, 'c', units)
578
579    def get_depth(self, units: str = 'm') -> float:
580        """Get the field labeled as depth_m in the API.
581
582        Args:
583            units: The units in which the distance should be returned. Options:
584                m or km for meters and kilometers respectively. Defaults to m.
585
586        Returns:
587            Depth of the bottom.
588        """
589        value = self._assert_float(self._inner['depth_m'])
590        return self._assert_float(afscgap.convert.convert(value, 'm', units))
591
592    def get_distance_fished(self, units: str = 'm') -> float:
593        """Get the field labeled as distance_fished_km in the API.
594
595        Args:
596            units: The units in which the distance should be returned. Options:
597                m or km for meters and kilometers respectively. Defaults to m.
598
599        Returns:
600            Distance of the net fished.
601        """
602        value = self._assert_float(self._inner['distance_fished_km'])
603        return self._assert_float(afscgap.convert.convert(value, 'km', units))
604
605    def get_net_width(self, units: str = 'm') -> float:
606        """Get the field labeled as net_width_m in the API.
607
608        Args:
609            units: The units in which the distance should be returned. Options:
610                m or km for meters and kilometers respectively. Defaults to m.
611
612        Returns:
613            Distance of the net fished after asserting it is given.
614        """
615        value = self._assert_float(self._inner['net_width_m'])
616        return self._assert_float(afscgap.convert.convert(value, 'm', units))
617
618    def get_net_height(self, units: str = 'm') -> float:
619        """Get the field labeled as net_height_m in the API.
620
621        Args:
622            units: The units in which the distance should be returned. Options:
623                m or km for meters and kilometers respectively. Defaults to m.
624
625        Returns:
626            Height of the net fished after asserting it is given.
627        """
628        value = self._assert_float(self._inner['net_height_m'])
629        return self._assert_float(afscgap.convert.convert(value, 'm', units))
630
631    def get_net_width_maybe(self, units: str = 'm') -> OPT_FLOAT:
632        """Get the field labeled as net_width_m in the API.
633
634        Args:
635            units: The units in which the distance should be returned. Options:
636                m or km for meters and kilometers respectively. Defaults to m.
637
638        Returns:
639            Distance of the net fished or None if not given.
640        """
641        value = self._inner['net_width_m']
642
643        if value is None:
644            return None
645
646        return afscgap.convert.convert(value, 'm', units)
647
648    def get_net_height_maybe(self, units: str = 'm') -> OPT_FLOAT:
649        """Get the field labeled as net_height_m in the API.
650
651        Args:
652            units: The units in which the distance should be returned. Options:
653                m or km for meters and kilometers respectively. Defaults to m.
654
655        Returns:
656            Height of the net fished or None if not given.
657        """
658        value = self._inner['net_height_m']
659
660        if value is None:
661            return None
662
663        return afscgap.convert.convert(value, 'm', units)
664
665    def get_area_swept(self, units: str = 'ha') -> float:
666        """Get the field labeled as area_swept_ha in the API.
667
668        Args:
669            units: The units in which the area should be returned. Options:
670                ha, m2, km2. Defaults to ha.
671
672        Returns:
673            Area covered by the net while fishing in desired units.
674        """
675        value = self._assert_float(self._inner['area_swept_km2'])
676        return self._assert_float(afscgap.convert.convert(value, 'km2', units))
677
678    def get_duration(self, units: str = 'hr') -> float:
679        """Get the field labeled as duration_hr in the API.
680
681        Args:
682            units: The units in which the duration should be returned. Options:
683                day, hr, min. Defaults to hr.
684
685        Returns:
686            Duration of the haul.
687        """
688        value = self._assert_float(self._inner['duration_hr'])
689        return self._assert_float(afscgap.convert.convert(value, 'hr', units))
690
691    def get_cpue_weight(self, units: str = 'kg/ha') -> float:
692        """Get the value of field cpue_kgha with validity assert.
693
694        Args:
695            units: The desired units for the catch per unit effort. Options:
696                kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
697
698        Raises:
699            AssertionError: Raised if this field was not given by the API or
700            could not be parsed as expected.
701
702        Returns:
703            Catch weight divided by net area (kg / hectares) if available. See
704            metadata. Will be zero if a zero catch record.
705        """
706        value = self._assert_float(self._inner['cpue_kgkm2'])
707        return self._assert_float(afscgap.convert.convert(value, 'kg/km2', units))
708
709    def get_cpue_count(self, units: str = 'count/ha') -> float:
710        """Get the value of field cpue_noha with validity assert.
711
712        Args:
713            units: The desired units for the catch per unit effort. Options:
714                count/ha, count/km2, and count1000/km2. Defaults to count/ha.
715
716        Raises:
717            AssertionError: Raised if this field was not given by the API or
718            could not be parsed as expected.
719
720        Returns:
721            Catch number divided by net sweep area if available (count /
722            hectares). See metadata. Will be zero if a zero catch record.
723        """
724        value = self._assert_float(self._inner['cpue_nokm2'])
725        return self._assert_float(afscgap.convert.convert(value, 'no/km2', units))
726
727    def get_weight(self, units: str = 'kg') -> float:
728        """Get the value of field weight_kg with validity assert.
729
730        Args:
731            units: The units in which the weight should be returned. Options are
732                g, kg for grams and kilograms respectively. Deafults to kg.
733
734        Raises:
735            AssertionError: Raised if this field was not given by the API or
736            could not be parsed as expected.
737
738        Returns:
739            Taxon weight (kg) if available. See metadata. Will be zero if a zero
740            catch record.
741        """
742        value = self._assert_float(self._inner['weight_kg'])
743        return self._assert_float(afscgap.convert.convert(value, 'kg', units))
744
745    def get_count(self) -> float:
746        """Get the value of field count with validity assert.
747
748        Raises:
749            AssertionError: Raised if this field was not given by the API or
750            could not be parsed as expected.
751
752        Returns:
753            Total number of organism individuals in haul. Will be zero if a zero
754            catch record.
755        """
756        return self._assert_int(self._inner['count'])
757
758    def get_bottom_temperature(self, units='c') -> float:
759        """Get the value of field bottom_temperature_c with validity assert.
760
761        Args:
762            units: The units in which the temperature should be returned.
763                Options: c or f for Celcius and Fahrenheit respectively.
764                Defaults to c.
765
766        Raises:
767            AssertionError: Raised if this field was not given by the API or
768            could not be parsed as expected.
769
770        Returns:
771            Bottom temperature associated with observation / inferrence if
772            available.
773        """
774        value = self._assert_float(self._inner['bottom_temperature_c'])
775        return self._assert_float(afscgap.convert.convert(value, 'c', units))
776
777    def get_surface_temperature(self, units='c') -> float:
778        """Get the value of field surface_temperature_c with validity assert.
779
780        Args:
781            units: The units in which the temperature should be returned.
782                Options: c or f for Celcius and Fahrenheit respectively.
783                Defaults to c.
784
785        Raises:
786            AssertionError: Raised if this field was not given by the API or
787            could not be parsed as expected.
788
789        Returns:
790            Surface temperature associated with observation / inferrence if
791            available.
792        """
793        value = self._assert_float(self._inner['surface_temperature_c'])
794        return self._assert_float(afscgap.convert.convert(value, 'c', units))
795
796    def is_complete(self) -> bool:
797        """Determine if this record has all of its values filled in.
798
799        Returns:
800            True if all optional fields have a parsed value with the expected
801            type and false otherwise.
802        """
803        if not self._inner['complete']:
804            return False
805
806        fields_missing = filter(lambda x: self._inner.get(x, None) is None, RECORD_REQUIRED_FIELDS)
807        num_missing = sum(map(lambda x: 1, fields_missing))
808        return num_missing == 0
809
810    def get_inner(self):
811        """Get the raw parsed Avro payload.
812
813        Returns:
814            The raw parsed Avro payload.
815        """
816        return self._inner
817
818    def _assert_float(self, target) -> float:
819        assert target is not None
820        return float(target)
821
822    def _assert_float_maybe(self, target) -> OPT_FLOAT:
823        return None if target is None else float(target)
824
825    def _assert_str(self, target) -> str:
826        assert target is not None
827        return str(target)
828
829    def _assert_str_maybe(self, target) -> OPT_STR:
830        return None if target is None else str(target)
831
832    def _assert_int(self, target) -> int:
833        assert target is not None
834        return int(target)
835
836    def _assert_int_maybe(self, target) -> OPT_INT:
837        return None if target is None else int(target)

Object describing the contents of a pre-joined flat Avro file.

FlatRecord(inner)
242    def __init__(self, inner):
243        """Create a new object decorating a raw parsed Avro record.
244
245        Args:
246            inner: The Avro record to decorate into a FlatRecord object, conforming to the interface
247                put forward by afscgap.model.Record.
248        """
249        self._inner = inner

Create a new object decorating a raw parsed Avro record.

Arguments:
  • inner: The Avro record to decorate into a FlatRecord object, conforming to the interface put forward by afscgap.model.Record.
def get_year(self) -> float:
251    def get_year(self) -> float:
252        """Get the field labeled as year in the API.
253
254        Returns:
255            Year for the survey in which this observation was made or for which
256            an inferred zero catch record was generated.
257        """
258        return self._assert_float(self._inner['year'])

Get the field labeled as year in the API.

Returns:

Year for the survey in which this observation was made or for which an inferred zero catch record was generated.

def get_srvy(self) -> str:
260    def get_srvy(self) -> str:
261        """Get the field labeled as srvy in the API.
262
263        Returns:
264            The name of the survey in which this observation or inference was
265            made. NBS (N Bearing Sea), EBS (SE Bearing Sea), BSS (Bearing Sea
266            Slope), or GOA (Gulf of Alaska)
267        """
268        return self._assert_str(self._inner['srvy'])

Get the field labeled as srvy in the API.

Returns:

The name of the survey in which this observation or inference was made. NBS (N Bearing Sea), EBS (SE Bearing Sea), BSS (Bearing Sea Slope), or GOA (Gulf of Alaska)

def get_survey(self) -> str:
270    def get_survey(self) -> str:
271        """Get the field labeled as survey in the API.
272
273        Returns:
274            Long form description of the survey in which the observation was
275            made or for which an inferred zero catch record was made.
276        """
277        return self._assert_str(self._inner['survey'])

Get the field labeled as survey in the API.

Returns:

Long form description of the survey in which the observation was made or for which an inferred zero catch record was made.

def get_survey_id(self) -> float:
279    def get_survey_id(self) -> float:
280        """Get the field labeled as survey_id in the API.
281
282        Returns:
283            Unique numeric ID for the survey.
284        """
285        return self._assert_int(self._inner['survey_definition_id'])

Get the field labeled as survey_id in the API.

Returns:

Unique numeric ID for the survey.

def get_cruise(self) -> float:
287    def get_cruise(self) -> float:
288        """Get the field labeled as cruise in the API.
289
290        Returns:
291            An ID uniquely identifying the cruise in which the observation or
292            inferrence was made. Multiple cruises in a survey.
293        """
294        return self._assert_int(self._inner['cruise'])

Get the field labeled as cruise in the API.

Returns:

An ID uniquely identifying the cruise in which the observation or inferrence was made. Multiple cruises in a survey.

def get_haul(self) -> float:
296    def get_haul(self) -> float:
297        """Get the field labeled as haul in the API.
298
299        Returns:
300            An ID uniquely identifying the haul in which this observation or
301            inference was made. Multiple hauls per cruises.
302        """
303        return self._assert_int(self._inner['haul'])

Get the field labeled as haul in the API.

Returns:

An ID uniquely identifying the haul in which this observation or inference was made. Multiple hauls per cruises.

def get_stratum(self) -> float:
305    def get_stratum(self) -> float:
306        """Get the field labeled as stratum in the API.
307
308        Returns:
309            Unique ID for statistical area / survey combination as described in
310            the metadata or 0 if an experimental tow.
311        """
312        return self._assert_int(self._inner['stratum'])

Get the field labeled as stratum in the API.

Returns:

Unique ID for statistical area / survey combination as described in the metadata or 0 if an experimental tow.

def get_station(self) -> str:
314    def get_station(self) -> str:
315        """Get the field labeled as station in the API.
316
317        Returns:
318            Station associated with the survey.
319        """
320        return self._assert_str(self._inner['station'])

Get the field labeled as station in the API.

Returns:

Station associated with the survey.

def get_vessel_name(self) -> str:
322    def get_vessel_name(self) -> str:
323        """Get the field labeled as vessel_name in the API.
324
325        Returns:
326            Unique ID describing the vessel that made this observation or
327            inference.
328        """
329        return self._assert_str(self._inner['vessel_name'])

Get the field labeled as vessel_name in the API.

Returns:

Unique ID describing the vessel that made this observation or inference.

def get_vessel_id(self) -> float:
331    def get_vessel_id(self) -> float:
332        """Get the field labeled as vessel_id in the API.
333
334        Returns:
335            Name of the vessel at the time the observation was made with
336            multiple names potentially associated with a vessel ID. May be
337            emulated in the case of inferred records
338        """
339        return self._assert_int(self._inner['vessel_id'])

Get the field labeled as vessel_id in the API.

Returns:

Name of the vessel at the time the observation was made with multiple names potentially associated with a vessel ID. May be emulated in the case of inferred records

def get_date_time(self) -> str:
341    def get_date_time(self) -> str:
342        """Get the field labeled as date_time in the API.
343
344        Returns:
345            The date and time of the haul which has been attempted to be
346            transformed to an ISO 8601 string without timezone info. If it
347            couldn’t be transformed, the original string is reported.
348        """
349        return self._assert_str(self._inner['date_time'])

Get the field labeled as date_time in the API.

Returns:

The date and time of the haul which has been attempted to be transformed to an ISO 8601 string without timezone info. If it couldn’t be transformed, the original string is reported.

def get_latitude_start(self, units: str = 'dd') -> float:
351    def get_latitude_start(self, units: str = 'dd') -> float:
352        """Get the field labeled as latitude_dd_start in the API.
353
354        Args:
355            units: The units to return this value in. Only supported is dd for
356                degrees. Deafults to dd.
357
358        Returns:
359            Latitude in decimal degrees associated with the haul.
360        """
361        value = self._assert_float(self._inner['latitude_dd_start'])
362        return self._assert_float(afscgap.convert.convert(value, 'dd', units))

Get the field labeled as latitude_dd_start in the API.

Arguments:
  • units: The units to return this value in. Only supported is dd for degrees. Deafults to dd.
Returns:

Latitude in decimal degrees associated with the haul.

def get_longitude_start(self, units: str = 'dd') -> float:
364    def get_longitude_start(self, units: str = 'dd') -> float:
365        """Get the field labeled as longitude_dd_start in the API.
366
367        Args:
368            units: The units to return this value in. Only supported is dd for
369                degrees. Deafults to dd.
370
371        Returns:
372            Longitude in decimal degrees associated with the haul.
373        """
374        value = self._assert_float(self._inner['longitude_dd_start'])
375        return self._assert_float(afscgap.convert.convert(value, 'dd', units))

Get the field labeled as longitude_dd_start in the API.

Arguments:
  • units: The units to return this value in. Only supported is dd for degrees. Deafults to dd.
Returns:

Longitude in decimal degrees associated with the haul.

def get_latitude(self, units: str = 'dd') -> float:
377    def get_latitude(self, units: str = 'dd') -> float:
378        """Get midpoint of the haul, approximating deprecated latitude_dd field in the API.
379
380        Args:
381            units: The units to return this value in. Only supported is dd for
382                degrees. Deafults to dd.
383
384        Returns:
385            Latitude in decimal degrees associated with the haul.
386        """
387        start = self.get_latitude_start()
388        end = self.get_latitude_end()
389        mid = (start + end) / 2
390        return self._assert_float(afscgap.convert.convert(mid, 'dd', units))

Get midpoint of the haul, approximating deprecated latitude_dd field in the API.

Arguments:
  • units: The units to return this value in. Only supported is dd for degrees. Deafults to dd.
Returns:

Latitude in decimal degrees associated with the haul.

def get_longitude(self, units: str = 'dd') -> float:
392    def get_longitude(self, units: str = 'dd') -> float:
393        """Get midpoint of the haul, approximating deprecated longitude_dd field in the API.
394
395        Args:
396            units: The units to return this value in. Only supported is dd for
397                degrees. Deafults to dd.
398
399        Returns:
400            Longitude in decimal degrees associated with the haul.
401        """
402        start = self.get_longitude_start()
403        end = self.get_longitude_end()
404        mid = (start + end) / 2
405        return self._assert_float(afscgap.convert.convert(mid, 'dd', units))

Get midpoint of the haul, approximating deprecated longitude_dd field in the API.

Arguments:
  • units: The units to return this value in. Only supported is dd for degrees. Deafults to dd.
Returns:

Longitude in decimal degrees associated with the haul.

def get_latitude_end(self, units: str = 'dd') -> float:
407    def get_latitude_end(self, units: str = 'dd') -> float:
408        """Get the field labeled as latitude_dd_end in the API.
409
410        Args:
411            units: The units to return this value in. Only supported is dd for
412                degrees. Deafults to dd.
413
414        Returns:
415            Latitude in decimal degrees associated with the haul.
416        """
417        value = self._assert_float(self._inner['latitude_dd_end'])
418        return self._assert_float(afscgap.convert.convert(value, 'dd', units))

Get the field labeled as latitude_dd_end in the API.

Arguments:
  • units: The units to return this value in. Only supported is dd for degrees. Deafults to dd.
Returns:

Latitude in decimal degrees associated with the haul.

def get_longitude_end(self, units: str = 'dd') -> float:
420    def get_longitude_end(self, units: str = 'dd') -> float:
421        """Get the field labeled as longitude_dd_end in the API.
422
423        Args:
424            units: The units to return this value in. Only supported is dd for
425                degrees. Deafults to dd.
426
427        Returns:
428            Longitude in decimal degrees associated with the haul.
429        """
430        value = self._assert_float(self._inner['longitude_dd_end'])
431        return self._assert_float(afscgap.convert.convert(value, 'dd', units))

Get the field labeled as longitude_dd_end in the API.

Arguments:
  • units: The units to return this value in. Only supported is dd for degrees. Deafults to dd.
Returns:

Longitude in decimal degrees associated with the haul.

def get_species_code(self) -> Optional[float]:
433    def get_species_code(self) -> OPT_FLOAT:
434        """Get the field labeled as species_code in the API.
435
436        Returns:
437            Unique ID associated with the species observed or for which a zero
438            catch record was inferred.
439        """
440        return self._assert_int_maybe(self._inner['species_code'])

Get the field labeled as species_code in the API.

Returns:

Unique ID associated with the species observed or for which a zero catch record was inferred.

def get_common_name(self) -> Optional[str]:
442    def get_common_name(self) -> OPT_STR:
443        """Get the field labeled as common_name in the API.
444
445        Returns:
446            The “common name” associated with the species observed or for which
447            a zero catch record was inferred. Example: Pacific glass shrimp.
448        """
449        return self._assert_str_maybe(self._inner['common_name'])

Get the field labeled as common_name in the API.

Returns:

The “common name” associated with the species observed or for which a zero catch record was inferred. Example: Pacific glass shrimp.

def get_scientific_name(self) -> Optional[str]:
451    def get_scientific_name(self) -> OPT_STR:
452        """Get the field labeled as scientific_name in the API.
453
454        Returns:
455            The “scientific name” associated with the species observed or for
456            which a zero catch record was inferred. Example: Pasiphaea pacifica.
457        """
458        value = self._inner['scientific_name']
459        return self._assert_str_maybe(value)

Get the field labeled as scientific_name in the API.

Returns:

The “scientific name” associated with the species observed or for which a zero catch record was inferred. Example: Pasiphaea pacifica.

def get_taxon_confidence(self) -> Optional[str]:
461    def get_taxon_confidence(self) -> OPT_STR:
462        """Get the field labeled as taxon_confidence in the API.
463
464        Returns:
465            Confidence flag regarding ability to identify species (High,
466            Moderate, Low). In practice, this can also be Unassessed.
467        """
468        return self._assert_str_maybe(self._inner['taxon_confidence'])

Get the field labeled as taxon_confidence in the API.

Returns:

Confidence flag regarding ability to identify species (High, Moderate, Low). In practice, this can also be Unassessed.

def get_cpue_weight_maybe(self, units: str = 'kg/ha') -> Optional[float]:
470    def get_cpue_weight_maybe(self, units: str = 'kg/ha') -> OPT_FLOAT:
471        """Get a field labeled as cpue_* in the API.
472
473        Args:
474            units: The desired units for the catch per unit effort. Options:
475                kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
476
477        Returns:
478            Catch weight divided by net area (in given units) if available. See
479            metadata. None if could not interpret as a float. If an inferred
480            zero catch record, will be zero.
481        """
482        value = self._inner['cpue_kgkm2']
483
484        if value is None:
485            return None
486
487        return afscgap.convert.convert(value, 'kg/km2', units)

Get a field labeled as cpue_* in the API.

Arguments:
  • units: The desired units for the catch per unit effort. Options: kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
Returns:

Catch weight divided by net area (in given units) if available. See metadata. None if could not interpret as a float. If an inferred zero catch record, will be zero.

def get_cpue_count_maybe(self, units: str = 'count/ha') -> Optional[float]:
489    def get_cpue_count_maybe(self, units: str = 'count/ha') -> OPT_FLOAT:
490        """Get the field labeled as cpue_* in the API.
491
492        Get the catch per unit effort from the record with one of the following
493        units: kg/ha, kg/km2, kg1000/km2.
494
495        Args:
496            units: The desired units for the catch per unit effort. Options:
497                count/ha, count/km2, and count1000/km2. Defaults to count/ha.
498
499        Returns:
500            Catch weight divided by net area (in given units) if available. See
501            metadata. None if could not interpret as a float. If an inferred
502            zero catch record, will be zero.
503        """
504        value = self._inner['cpue_nokm2']
505
506        if value is None:
507            return None
508
509        return afscgap.convert.convert(value, 'no/km2', units)

Get the field labeled as cpue_* in the API.

Get the catch per unit effort from the record with one of the following units: kg/ha, kg/km2, kg1000/km2.

Arguments:
  • units: The desired units for the catch per unit effort. Options: count/ha, count/km2, and count1000/km2. Defaults to count/ha.
Returns:

Catch weight divided by net area (in given units) if available. See metadata. None if could not interpret as a float. If an inferred zero catch record, will be zero.

def get_weight_maybe(self, units: str = 'kg') -> Optional[float]:
511    def get_weight_maybe(self, units: str = 'kg') -> OPT_FLOAT:
512        """Get the field labeled as weight_kg in the API.
513
514        Args:
515            units: The units in which the weight should be returned. Options are
516                g, kg for grams and kilograms respectively. Deafults to kg.
517
518        Returns:
519            Taxon weight if available. See metadata. None if could not
520            interpret as a float. If an inferred zero catch record, will be
521            zero.
522        """
523        value = self._inner['weight_kg']
524
525        if value is None:
526            return None
527
528        return afscgap.convert.convert(value, 'kg', units)

Get the field labeled as weight_kg in the API.

Arguments:
  • units: The units in which the weight should be returned. Options are g, kg for grams and kilograms respectively. Deafults to kg.
Returns:

Taxon weight if available. See metadata. None if could not interpret as a float. If an inferred zero catch record, will be zero.

def get_count_maybe(self) -> Optional[float]:
530    def get_count_maybe(self) -> OPT_FLOAT:
531        """Get the field labeled as count in the API.
532
533        Returns:
534            Total number of organism individuals in haul. None if could not
535            interpret as a float. If an inferred zero catch record, will be
536            zero.
537        """
538        return self._inner['count']

Get the field labeled as count in the API.

Returns:

Total number of organism individuals in haul. None if could not interpret as a float. If an inferred zero catch record, will be zero.

def get_bottom_temperature_maybe(self, units: str = 'c') -> Optional[float]:
540    def get_bottom_temperature_maybe(self, units: str = 'c') -> OPT_FLOAT:
541        """Get the field labeled as bottom_temperature_c in the API.
542
543        Args:
544            units: The units in which the temperature should be returned.
545                Options: c or f for Celcius and Fahrenheit respectively.
546                Defaults to c.
547
548        Returns:
549            Bottom temperature associated with observation / inferrence if
550            available in desired units. None if not given or could not interpret
551            as a float.
552        """
553        value = self._inner['bottom_temperature_c']
554
555        if value is None:
556            return None
557
558        return afscgap.convert.convert(value, 'c', units)

Get the field labeled as bottom_temperature_c in the API.

Arguments:
  • units: The units in which the temperature should be returned. Options: c or f for Celcius and Fahrenheit respectively. Defaults to c.
Returns:

Bottom temperature associated with observation / inferrence if available in desired units. None if not given or could not interpret as a float.

def get_surface_temperature_maybe(self, units: str = 'c') -> Optional[float]:
560    def get_surface_temperature_maybe(self, units: str = 'c') -> OPT_FLOAT:
561        """Get the field labeled as surface_temperature_c in the API.
562
563        Args:
564            units: The units in which the temperature should be returned.
565                Options: c or f for Celcius and Fahrenheit respectively.
566                Defaults to c.
567
568        Returns:
569            Surface temperature associated with observation / inferrence if
570            available. None if not given or could not interpret as a float.
571        """
572        value = self._inner['surface_temperature_c']
573
574        if value is None:
575            return None
576
577        return afscgap.convert.convert(value, 'c', units)

Get the field labeled as surface_temperature_c in the API.

Arguments:
  • units: The units in which the temperature should be returned. Options: c or f for Celcius and Fahrenheit respectively. Defaults to c.
Returns:

Surface temperature associated with observation / inferrence if available. None if not given or could not interpret as a float.

def get_depth(self, units: str = 'm') -> float:
579    def get_depth(self, units: str = 'm') -> float:
580        """Get the field labeled as depth_m in the API.
581
582        Args:
583            units: The units in which the distance should be returned. Options:
584                m or km for meters and kilometers respectively. Defaults to m.
585
586        Returns:
587            Depth of the bottom.
588        """
589        value = self._assert_float(self._inner['depth_m'])
590        return self._assert_float(afscgap.convert.convert(value, 'm', units))

Get the field labeled as depth_m in the API.

Arguments:
  • units: The units in which the distance should be returned. Options: m or km for meters and kilometers respectively. Defaults to m.
Returns:

Depth of the bottom.

def get_distance_fished(self, units: str = 'm') -> float:
592    def get_distance_fished(self, units: str = 'm') -> float:
593        """Get the field labeled as distance_fished_km in the API.
594
595        Args:
596            units: The units in which the distance should be returned. Options:
597                m or km for meters and kilometers respectively. Defaults to m.
598
599        Returns:
600            Distance of the net fished.
601        """
602        value = self._assert_float(self._inner['distance_fished_km'])
603        return self._assert_float(afscgap.convert.convert(value, 'km', units))

Get the field labeled as distance_fished_km in the API.

Arguments:
  • units: The units in which the distance should be returned. Options: m or km for meters and kilometers respectively. Defaults to m.
Returns:

Distance of the net fished.

def get_net_width(self, units: str = 'm') -> float:
605    def get_net_width(self, units: str = 'm') -> float:
606        """Get the field labeled as net_width_m in the API.
607
608        Args:
609            units: The units in which the distance should be returned. Options:
610                m or km for meters and kilometers respectively. Defaults to m.
611
612        Returns:
613            Distance of the net fished after asserting it is given.
614        """
615        value = self._assert_float(self._inner['net_width_m'])
616        return self._assert_float(afscgap.convert.convert(value, 'm', units))

Get the field labeled as net_width_m in the API.

Arguments:
  • units: The units in which the distance should be returned. Options: m or km for meters and kilometers respectively. Defaults to m.
Returns:

Distance of the net fished after asserting it is given.

def get_net_height(self, units: str = 'm') -> float:
618    def get_net_height(self, units: str = 'm') -> float:
619        """Get the field labeled as net_height_m in the API.
620
621        Args:
622            units: The units in which the distance should be returned. Options:
623                m or km for meters and kilometers respectively. Defaults to m.
624
625        Returns:
626            Height of the net fished after asserting it is given.
627        """
628        value = self._assert_float(self._inner['net_height_m'])
629        return self._assert_float(afscgap.convert.convert(value, 'm', units))

Get the field labeled as net_height_m in the API.

Arguments:
  • units: The units in which the distance should be returned. Options: m or km for meters and kilometers respectively. Defaults to m.
Returns:

Height of the net fished after asserting it is given.

def get_net_width_maybe(self, units: str = 'm') -> Optional[float]:
631    def get_net_width_maybe(self, units: str = 'm') -> OPT_FLOAT:
632        """Get the field labeled as net_width_m in the API.
633
634        Args:
635            units: The units in which the distance should be returned. Options:
636                m or km for meters and kilometers respectively. Defaults to m.
637
638        Returns:
639            Distance of the net fished or None if not given.
640        """
641        value = self._inner['net_width_m']
642
643        if value is None:
644            return None
645
646        return afscgap.convert.convert(value, 'm', units)

Get the field labeled as net_width_m in the API.

Arguments:
  • units: The units in which the distance should be returned. Options: m or km for meters and kilometers respectively. Defaults to m.
Returns:

Distance of the net fished or None if not given.

def get_net_height_maybe(self, units: str = 'm') -> Optional[float]:
648    def get_net_height_maybe(self, units: str = 'm') -> OPT_FLOAT:
649        """Get the field labeled as net_height_m in the API.
650
651        Args:
652            units: The units in which the distance should be returned. Options:
653                m or km for meters and kilometers respectively. Defaults to m.
654
655        Returns:
656            Height of the net fished or None if not given.
657        """
658        value = self._inner['net_height_m']
659
660        if value is None:
661            return None
662
663        return afscgap.convert.convert(value, 'm', units)

Get the field labeled as net_height_m in the API.

Arguments:
  • units: The units in which the distance should be returned. Options: m or km for meters and kilometers respectively. Defaults to m.
Returns:

Height of the net fished or None if not given.

def get_area_swept(self, units: str = 'ha') -> float:
665    def get_area_swept(self, units: str = 'ha') -> float:
666        """Get the field labeled as area_swept_ha in the API.
667
668        Args:
669            units: The units in which the area should be returned. Options:
670                ha, m2, km2. Defaults to ha.
671
672        Returns:
673            Area covered by the net while fishing in desired units.
674        """
675        value = self._assert_float(self._inner['area_swept_km2'])
676        return self._assert_float(afscgap.convert.convert(value, 'km2', units))

Get the field labeled as area_swept_ha in the API.

Arguments:
  • units: The units in which the area should be returned. Options: ha, m2, km2. Defaults to ha.
Returns:

Area covered by the net while fishing in desired units.

def get_duration(self, units: str = 'hr') -> float:
678    def get_duration(self, units: str = 'hr') -> float:
679        """Get the field labeled as duration_hr in the API.
680
681        Args:
682            units: The units in which the duration should be returned. Options:
683                day, hr, min. Defaults to hr.
684
685        Returns:
686            Duration of the haul.
687        """
688        value = self._assert_float(self._inner['duration_hr'])
689        return self._assert_float(afscgap.convert.convert(value, 'hr', units))

Get the field labeled as duration_hr in the API.

Arguments:
  • units: The units in which the duration should be returned. Options: day, hr, min. Defaults to hr.
Returns:

Duration of the haul.

def get_cpue_weight(self, units: str = 'kg/ha') -> float:
691    def get_cpue_weight(self, units: str = 'kg/ha') -> float:
692        """Get the value of field cpue_kgha with validity assert.
693
694        Args:
695            units: The desired units for the catch per unit effort. Options:
696                kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
697
698        Raises:
699            AssertionError: Raised if this field was not given by the API or
700            could not be parsed as expected.
701
702        Returns:
703            Catch weight divided by net area (kg / hectares) if available. See
704            metadata. Will be zero if a zero catch record.
705        """
706        value = self._assert_float(self._inner['cpue_kgkm2'])
707        return self._assert_float(afscgap.convert.convert(value, 'kg/km2', units))

Get the value of field cpue_kgha with validity assert.

Arguments:
  • units: The desired units for the catch per unit effort. Options: kg/ha, kg/km2, kg1000/km2. Defaults to kg/ha.
Raises:
  • AssertionError: Raised if this field was not given by the API or
  • could not be parsed as expected.
Returns:

Catch weight divided by net area (kg / hectares) if available. See metadata. Will be zero if a zero catch record.

def get_cpue_count(self, units: str = 'count/ha') -> float:
709    def get_cpue_count(self, units: str = 'count/ha') -> float:
710        """Get the value of field cpue_noha with validity assert.
711
712        Args:
713            units: The desired units for the catch per unit effort. Options:
714                count/ha, count/km2, and count1000/km2. Defaults to count/ha.
715
716        Raises:
717            AssertionError: Raised if this field was not given by the API or
718            could not be parsed as expected.
719
720        Returns:
721            Catch number divided by net sweep area if available (count /
722            hectares). See metadata. Will be zero if a zero catch record.
723        """
724        value = self._assert_float(self._inner['cpue_nokm2'])
725        return self._assert_float(afscgap.convert.convert(value, 'no/km2', units))

Get the value of field cpue_noha with validity assert.

Arguments:
  • units: The desired units for the catch per unit effort. Options: count/ha, count/km2, and count1000/km2. Defaults to count/ha.
Raises:
  • AssertionError: Raised if this field was not given by the API or
  • could not be parsed as expected.
Returns:

Catch number divided by net sweep area if available (count / hectares). See metadata. Will be zero if a zero catch record.

def get_weight(self, units: str = 'kg') -> float:
727    def get_weight(self, units: str = 'kg') -> float:
728        """Get the value of field weight_kg with validity assert.
729
730        Args:
731            units: The units in which the weight should be returned. Options are
732                g, kg for grams and kilograms respectively. Deafults to kg.
733
734        Raises:
735            AssertionError: Raised if this field was not given by the API or
736            could not be parsed as expected.
737
738        Returns:
739            Taxon weight (kg) if available. See metadata. Will be zero if a zero
740            catch record.
741        """
742        value = self._assert_float(self._inner['weight_kg'])
743        return self._assert_float(afscgap.convert.convert(value, 'kg', units))

Get the value of field weight_kg with validity assert.

Arguments:
  • units: The units in which the weight should be returned. Options are g, kg for grams and kilograms respectively. Deafults to kg.
Raises:
  • AssertionError: Raised if this field was not given by the API or
  • could not be parsed as expected.
Returns:

Taxon weight (kg) if available. See metadata. Will be zero if a zero catch record.

def get_count(self) -> float:
745    def get_count(self) -> float:
746        """Get the value of field count with validity assert.
747
748        Raises:
749            AssertionError: Raised if this field was not given by the API or
750            could not be parsed as expected.
751
752        Returns:
753            Total number of organism individuals in haul. Will be zero if a zero
754            catch record.
755        """
756        return self._assert_int(self._inner['count'])

Get the value of field count with validity assert.

Raises:
  • AssertionError: Raised if this field was not given by the API or
  • could not be parsed as expected.
Returns:

Total number of organism individuals in haul. Will be zero if a zero catch record.

def get_bottom_temperature(self, units='c') -> float:
758    def get_bottom_temperature(self, units='c') -> float:
759        """Get the value of field bottom_temperature_c with validity assert.
760
761        Args:
762            units: The units in which the temperature should be returned.
763                Options: c or f for Celcius and Fahrenheit respectively.
764                Defaults to c.
765
766        Raises:
767            AssertionError: Raised if this field was not given by the API or
768            could not be parsed as expected.
769
770        Returns:
771            Bottom temperature associated with observation / inferrence if
772            available.
773        """
774        value = self._assert_float(self._inner['bottom_temperature_c'])
775        return self._assert_float(afscgap.convert.convert(value, 'c', units))

Get the value of field bottom_temperature_c with validity assert.

Arguments:
  • units: The units in which the temperature should be returned. Options: c or f for Celcius and Fahrenheit respectively. Defaults to c.
Raises:
  • AssertionError: Raised if this field was not given by the API or
  • could not be parsed as expected.
Returns:

Bottom temperature associated with observation / inferrence if available.

def get_surface_temperature(self, units='c') -> float:
777    def get_surface_temperature(self, units='c') -> float:
778        """Get the value of field surface_temperature_c with validity assert.
779
780        Args:
781            units: The units in which the temperature should be returned.
782                Options: c or f for Celcius and Fahrenheit respectively.
783                Defaults to c.
784
785        Raises:
786            AssertionError: Raised if this field was not given by the API or
787            could not be parsed as expected.
788
789        Returns:
790            Surface temperature associated with observation / inferrence if
791            available.
792        """
793        value = self._assert_float(self._inner['surface_temperature_c'])
794        return self._assert_float(afscgap.convert.convert(value, 'c', units))

Get the value of field surface_temperature_c with validity assert.

Arguments:
  • units: The units in which the temperature should be returned. Options: c or f for Celcius and Fahrenheit respectively. Defaults to c.
Raises:
  • AssertionError: Raised if this field was not given by the API or
  • could not be parsed as expected.
Returns:

Surface temperature associated with observation / inferrence if available.

def is_complete(self) -> bool:
796    def is_complete(self) -> bool:
797        """Determine if this record has all of its values filled in.
798
799        Returns:
800            True if all optional fields have a parsed value with the expected
801            type and false otherwise.
802        """
803        if not self._inner['complete']:
804            return False
805
806        fields_missing = filter(lambda x: self._inner.get(x, None) is None, RECORD_REQUIRED_FIELDS)
807        num_missing = sum(map(lambda x: 1, fields_missing))
808        return num_missing == 0

Determine if this record has all of its values filled in.

Returns:

True if all optional fields have a parsed value with the expected type and false otherwise.

def get_inner(self):
810    def get_inner(self):
811        """Get the raw parsed Avro payload.
812
813        Returns:
814            The raw parsed Avro payload.
815        """
816        return self._inner

Get the raw parsed Avro payload.

Returns:

The raw parsed Avro payload.

Inherited Members
afscgap.model.Record
to_dict