Source code for palangre_syc.json_construction

""" 

Module de fonctions qui permettent la construction du json 
palangre, tel qu'il est envoyé à Observe

"""

# import json
from multiprocessing import context
import pandas as pd
import palangre_syc.api
import palangre_syc.views
import palangre_syc.excel_extractions
import api_traitement.common_functions
from datetime import timedelta

[docs] def get_captain_topiaid(df_donnees_p1, allData, context): """ Fonction qui propose le topiaID associé au capitaine du logbook (ou inconnu is non présent dans les données de référence) Args: df_donnees_p1 (dataframe): page 1 du doc excel allData (json): Données de références Returns: _type_: topiaID du capitaine présenté dans le logbook """ for captain in allData['Person']: captain_logbook = palangre_syc.excel_extractions.extract_cruise_info(df_donnees_p1, context['version']).loc[palangre_syc.excel_extractions.extract_cruise_info(df_donnees_p1, context['version'])['Logbook_name'] == 'Captain', 'Value'].values[0] captain_json = captain['firstName'] + ' ' + captain['lastName'] if captain_logbook == captain_json: return captain['topiaId'] else: captain_logbook = '[inconnu] [inconnu]' if captain_logbook == captain_json: return captain['topiaId'] return None
[docs] def get_operator_topiaid(df_donnees_p1, allData, context): """ Fonction qui propose le topiaID de la personne qui a saisi les données du logbook (ou inconnu is non présent dans les données de référence) Args: df_donnees_p1 (dataframe): page 1 du doc excel allData (json): Données de références Returns: _type_: topiaID de l'opérateur """ for person in allData['Person']: reported_logbook = palangre_syc.excel_extractions.extract_report_info(df_donnees_p1, context['version']).loc[palangre_syc.excel_extractions.extract_report_info( df_donnees_p1, context['version'])['Logbook_name'] == 'Person reported', 'Value'].values[0] reported_json = person['firstName'] + ' ' + person['lastName'] if not pd.isna(reported_logbook) and reported_logbook == reported_json: return person['topiaId'] else: reported_logbook = '[inconnu] [inconnu]' if reported_logbook == reported_json: return person['topiaId'] return None
[docs] def get_vessel_topiaid(df_donnees_p1, allData): """ Fonction qui propose le topiaId du navire cité dans le logbook à partir de son 'nationlId' s'il existe Args: df_donnees_p1 (dataframe): page 1 du doc excel allData (json): Données de références Returns: _type_: topiaID du navire (vessel) """ vessel_logbook = palangre_syc.excel_extractions.extract_vessel_info(df_donnees_p1).loc[palangre_syc.excel_extractions.extract_vessel_info(df_donnees_p1)['Logbook_name'] == 'Official Number', 'Value'].values[0] enabled_topiaids = [ vessel["topiaId"] for vessel in allData["Vessel"] if 'nationalId' in vessel and vessel["nationalId"] == vessel_logbook and vessel["status"] == "enabled" # and vessel["flagCountry"] == "fr.ird.referential.common.Country#1239832675593#0.3601938043845213" ] if len(enabled_topiaids) > 0: return enabled_topiaids[0] else : return None
[docs] def get_baittype_topiaid(row, allData, version): """ Fonction qui propose le topiaId de l'appat coché dans le logbook Args: row (dataframe): nom de l'appât allData (json): Données de références Returns: str: topiaID de l'appât utilisé """ baittypes = allData["BaitType"] if version == "ll_17.6": colnames = "Logbook_name" join_on_colnames = "label1" elif version == "ll_26": colnames = 'Bait' join_on_colnames = 'code' bait_logbook = row[colnames] if bait_logbook == None : return None else : for baittype in baittypes: if baittype.get(join_on_colnames)[:len(bait_logbook)] == bait_logbook: return baittype["topiaId"]
[docs] def get_species_topiaid(fao_code_logbook, allData): """ Fonction qui propose le topiaId pour une espèce à partir de son code FAO (saisi manuellement dans la trascription du excel) Args: FAO_code_logbook (_type_): Code FAO (3 caractères) extrait du datatable de prises créé depuis la page 1 et 2 allData (json): Données de références Returns: str: topiaID de l'espèce demandée """ species = allData["Species"] for specie in species: if fao_code_logbook == specie.get("faoCode"): return specie["topiaId"] # On part du principe que si le code fao n'est pas exactement trouvé, c'est qu'il s'agit d'une espèce non identifié return "fr.ird.referential.common.Species#1433499266610#0.696541526820511"
[docs] def get_catchfate_topiaid(catchfate_code, allData): """ Fonction qui propose le topiaId du devenir de l'espèce (associé manuellement à l'espèce dans la trascription du excel) Args: catchFate_logbook (str): Code catchFate (3 caractères) extrait du datatable de prises créé depuis la page 1 et 2 allData (json): Données de références Returns: str: topiaID du devenir de l'espèce demandée """ fates = allData["CatchFate"] for catchfate in fates: if 'code' in catchfate: if catchfate.get("code") == catchfate_code: return catchfate["topiaId"] else : return None
[docs] def get_discardHealthStatus_topiaid(discardHealthStatus_code, allData): """ Fonction qui propose le topiaId du statut de santé des déchets (associé manuellement à l'espèce dans la trascription du excel) Args: discardHealthStatus_logbook (str): Code discardHealthStatus (3 caractères) extrait du datatable de prises créé depuis la page 1 et 2 allData (json): Données de références Returns: str: topiaID du statut de santé des discards demandé """ HealthStatus = allData["HealthStatus"] for health in HealthStatus: if 'code' in health: if health.get("code") == discardHealthStatus_code: return health["topiaId"] else : return None
# Opimisation éventuelle : ajouter unparamètre qui permettrait de distinguer les fish des bycatch # notamment si les by catch son relachées A alive ou D dead
[docs] def get_processing_topiaid_from_faocode(fao_code, allData): """ Fonction qui associe un process on board à une espèce de poisson Args: fao_code (str): espèce de poisson allData (json): Données de références Returns: topiaid: OnBoardProcess """ if fao_code == 'SBF' or fao_code == 'BET' or fao_code == 'YFT': processing_code = "GG" elif fao_code == 'SWO' or fao_code == 'MLS' or fao_code == 'BUM' or fao_code == 'BLM' or fao_code == 'SFA' or fao_code == 'SSP': processing_code = "HG" elif fao_code == 'ALB' or fao_code == 'OIL' or fao_code == 'MZZ': processing_code = "WL" else : processing_code = "UNK" processings = allData["OnBoardProcessing"] for processing in processings: if 'code' in processing: if processing.get("code") == processing_code: return processing["topiaId"] else : return None
[docs] def get_processing_topiaid(processing_code, allData): """ Fonction qui associe un process on board à une espèce de poisson Args: fao_code (str): espèce de poisson allData (json): Données de références Returns: topiaid: OnBoardProcess """ # if fao_code == 'SBF' or fao_code == 'BET' or fao_code == 'YFT': # processing_code = "GG" # elif fao_code == 'SWO' or fao_code == 'MLS' or fao_code == 'BUM' or fao_code == 'BLM' or fao_code == 'SFA' or fao_code == 'SSP': # processing_code = "HG" # elif fao_code == 'ALB' or fao_code == 'OIL' or fao_code == 'MZZ': # processing_code = "WL" # else : # processing_code = "UNK" processings = allData["OnBoardProcessing"] for processing in processings: if 'code' in processing: if processing.get("code") == processing_code: return processing["topiaId"] else : return None
[docs] def get_target_species_topiaid(df_donnees_p1, allData, context): """ Fonction qui va récupérer les topiaid de chacune des espèces visées dans une liste Args: df_donnees_p1 (dataframe): page 1 du doc excel allData (json): Données de références Returns: list de topiaid """ data = palangre_syc.excel_extractions.extract_target_species(df_donnees_p1, context['version']) list_target_topiaid = [] for target in data['Logbook_name']: if 'Tropical Tuna' in target: # list_target_topiaid.loc[len(list_target_topiaid)] = get_species_topiaid("YFT", data_common) list_target_topiaid.append(get_species_topiaid("YFT", allData)) list_target_topiaid.append(get_species_topiaid("BET", allData)) elif 'Albacore Tuna' in target: list_target_topiaid.append(get_species_topiaid("ALB", allData)) elif 'Swordfish' in target: list_target_topiaid.append(get_species_topiaid("SWO", allData)) else: list_target_topiaid.append(get_species_topiaid("MZZ", allData)) return list_target_topiaid
[docs] def construction_catch_table(fish_file): """ Args: fish_file (dataframe): Issu des fonction d'extraction propre à chaque espèce ou groupe d'espèce Returns: dataframe: Construction d'un df avec chaque code FAO et le catchfate associée en lignes """ df_catches = pd.DataFrame(columns=['fao_code', 'catch_fate', 'count', 'totalWeight']) # On récupère les données des colonnes de FAO et catchFate for col in fish_file.columns: fao_code = col[-3:] catchfate = col[-7:-4] df_catches.loc[len(df_catches)] = {'fao_code': fao_code, 'catch_fate': catchfate} # On supprime les doublons df_catches = df_catches.drop_duplicates() df_catches.reset_index(drop=True, inplace=True) return df_catches
# a voir si c'est pertinent en terme de gain de temps de découper la fonction ici en 2 # on pourrait avoir une fonctionn qui gère les lignes issues des noms de colonnes # et une seconde fonction qui remplirait les lignes count et totalWeight en allant chercher les infos dans le excel
[docs] def create_catch_table_fish_perday(fish_file, row_number): """ Args: fish_file (datatable): issu des extraction, donc un datatable par groupe d'espèce row_number (int): ligne (ou un jour de pêche) à extraire Returns: dataframe: par type de poisson pêché et par jour de pêche de 4 colonnes Ce dataframe contient les champs obligatoires à remplir dans la table 'catch' de Observe """ df_catches = construction_catch_table(fish_file) # On rempli la suite du dataframe pour count et totalWeight (pour une ligne donnée) for index, row in df_catches.iterrows(): col_end_name = row['catch_fate'] + ' ' + row['fao_code'] for col in fish_file.columns: if col[-7:] == col_end_name: if col[:2] == 'No': fish_file_colname = 'No.' + ' ' + col_end_name count = fish_file.loc[row_number, fish_file_colname] df_catches.loc[index, 'count'] = count # df_catches.loc[index, 'count'] = int(df_catches.loc[index, 'count']) if col[:2] == 'Kg': fish_file_colname = 'Kg' + ' ' + col_end_name total_weight = fish_file.loc[row_number, fish_file_colname] df_catches.loc[index, 'totalWeight'] = total_weight # df_catches.loc[index, 'totalWeight'] = int(df_catches.loc[index, 'totalWeight']) # a voir si on veut des Nan car il n'y a pas de donnée ou des 0 else: df_catches.loc[index, 'totalWeight'] = int(0) return df_catches
[docs] def create_catch_table_fishes(df_donnees_p1, df_donnees_p2, row_number): """ Args: df_donnees_p1 (dataframe): page 1 du doc excel df_donnees_p2 (dataframe): page 2 du doc excel row_number (int): ligne ou jour du set Returns: dataframe: avec les prises réalisées pour une journée de pêche (code FAO, catchFate, nombre de prise et Poids tot) """ liste_fct_extraction = [palangre_syc.excel_extractions.extract_fish_p1_v17(df_donnees_p1), palangre_syc.excel_extractions.extract_bycatch_p2_v17(df_donnees_p2) ] df_catches = pd.DataFrame( columns=['fao_code', 'catch_fate', 'count', 'totalWeight']) for fish_file in liste_fct_extraction: df_per_extraction = create_catch_table_fish_perday( fish_file, row_number) df_catches = pd.concat( [df_catches, df_per_extraction], ignore_index=True) # Tester si les colonnes 'count' et 'totalWeight' contiennent des zéros not_catch = df_catches[(df_catches['count'] == 0) & (df_catches['totalWeight'] == 0)] # Supprimer les lignes qui contiennent des zéros dans ces colonnes df_catches = df_catches.drop(not_catch.index) df_catches.reset_index(drop=True, inplace=True) return df_catches
# TopType et tracelineType sont unknown
[docs] def create_branchline_composition_v17(df_gear): """ Fonction de construction du json pour les branchlineComposition Args: df_donnees_p1 (dataframe): page 1 du doc excel Returns: _type_: le json rempli à partir des infos de mon logbook """ branchlines_composition = [{ 'homeId': None, # 'length': palangre_syc.excel_extractions.extract_gear_info(df_donnees_p1).loc[palangre_syc.excel_extractions.extract_gear_info(df_donnees_p1)['Logbook_name'] == 'Set Line length m', 'Value'].values[0], 'length': df_gear.loc[df_gear['Logbook_name'] == 'Branchline length m', 'Value'].values[0], 'proportion': None, 'tracelineLength': None, 'topType': "fr.ird.referential.ll.common.LineType#1239832686157#0.9", 'tracelineType': "fr.ird.referential.ll.common.LineType#1239832686157#0.9", }] return branchlines_composition
[docs] def create_bait_composition(bait_datatable, allData, version): """ Fonction de construction du json pour les BaitComposition Args: bait_datatable (datatable): datatable non vide 'Baits' construite in views.py allData (json): Données de références Returns: _type_: le json rempli à partir des infos de mon logbook """ MultipleBaits = [] if version == "ll_17.6": total_baits = len(bait_datatable) for index, row in bait_datatable.iterrows(): BaitsComposition = { "homeId": None, "proportion": 100/total_baits, "individualSize": None, "individualWeight": None, "baitSettingStatus": None, "baitType": get_baittype_topiaid(row, allData, version=version), } MultipleBaits.append(BaitsComposition) if version == "ll_26": # wrong name though bc there is only one MultipleBaits = [{ "homeId": None, "proportion": 100, "individualSize": None, "individualWeight": None, "baitSettingStatus": None, "baitType": get_baittype_topiaid(bait_datatable, allData, version=version), }] return MultipleBaits
[docs] def create_floatline_composition_v17(df_gear, df_line): """ Fonction de construction du json pour les FloatlineComposition Args: df_donnees_p1 (dataframe): page 1 du doc excel Returns: _type_: le json rempli à partir des infos de mon logbook """ Multiplefloatlines_composition = [] if (len(df_line) >= 1) : for (row) in df_line.iterrows(): if row[1]["Value"] != "": floatlines_composition = { "homeId": None, "length": df_gear.loc[df_gear['Logbook_name'] == 'Floatline length m', 'Value'].values[0], "proportion": 100/len(df_line), "lineType": create_lineType_v17(row[1]["Logbook_name"]) } Multiplefloatlines_composition.append(floatlines_composition) return Multiplefloatlines_composition else : floatlines_composition = [{ "homeId": None, "length": df_gear.loc[df_gear['Logbook_name'] == 'Floatline length m', 'Value'].values[0], "proportion": 100, "lineType": "fr.ird.referential.ll.common.LineType#1239832686157#0.9" }] return floatlines_composition
[docs] def create_lineType_v17(logbook_lineType): """ Fonction de recherche de la line type dans le référentiel Args: logbook_lineType: l'élement coché du logbook (e.g. "braided nylon") Returns: lineType: le topiaId de la ligne """ # if (len(df_line) == 1) : # logbook_lineType = df_line.loc[df_line["Value"] != "", "Logbook_name"].values[0] # if contains "thick" == PV if "thick" in logbook_lineType.lower(): lineType = "fr.ird.referential.ll.common.LineType#1707486846969#0.09086405093041561" # # if contains "thin" == PR elif "thin" in logbook_lineType.lower(): lineType = "fr.ird.referential.ll.common.LineType#1707486754220#0.7999222136319315" # # if contains "braid" == BRL elif "braid" in logbook_lineType.lower(): lineType = "fr.ird.referential.ll.common.LineType#1239832686157#0.6" # if contains "mono" == MON elif "mono" in logbook_lineType.lower(): lineType = "fr.ird.referential.ll.common.LineType#1239832686157#0.1" # else == UNK else: lineType = "fr.ird.referential.ll.common.LineType#1239832686157#0.9" # # si on a plusieurs lignes de cochées # else: # lineType = "fr.ird.referential.ll.common.LineType#1239832686157#0.9" return lineType
[docs] def create_lineType_v26(lineType_code, allData): """ Fonction de recherche de la line type dans le référentiel Args: lineType_code: le code de la line type dans le logbook allData: les données de référentiel Returns: lineType: le topiaId de la ligne """ LineTypes = allData["LineType"] for lineType in LineTypes: if 'code' in lineType: if lineType.get("code") == lineType_code: return lineType["topiaId"] # else: # lineType["topiaId"] = "fr.ird.referential.ll.common.LineType#1239832686157#0.9" # return lineType["topiaId"] else : return None return lineType
# peut etre ajouter le healthStatus
[docs] def create_catches(datatable, allData): """ Fonction de construction du json pour les catches Args: datatable (datatable): datatable créé pour une journée / un set allData (json): Données de références Returns: _type_: le json rempli à partir des infos de mon logbook """ MultipleCatches = [] for n_ligne_datatable in range(len(datatable)): catches = {"homeId": None, } if get_species_topiaid(datatable.loc[n_ligne_datatable, 'fao_code'], allData) == 'fr.ird.referential.common.Species#1433499266610#0.696541526820511' or get_species_topiaid(datatable.loc[n_ligne_datatable, 'fao_code'], allData) == 'fr.ird.referential.common.Species#1239832685020#0.7691470969492022': catches.update({"comment": "Other fish non specified", }) else: catches.update({"comment": None, }) catches.update({"count": datatable.loc[n_ligne_datatable, 'count'], "totalWeight": datatable.loc[n_ligne_datatable, 'totalWeight'], "hookWhenDiscarded": None, "depredated": None, "beatDiameter": None, "photoReferences": None, "number": None, "acquisitionMode": 1, "countDepredated": None, "depredatedProportion": None, "tagNumber": None, "catchFate": get_catchfate_topiaid(datatable.loc[n_ligne_datatable, 'catch_fate'], allData), "discardHealthStatus": None, "species": get_species_topiaid(datatable.loc[n_ligne_datatable, 'fao_code'], allData), "predator": [], "catchHealthStatus": None, "onBoardProcessing": get_processing_topiaid_from_faocode(datatable.loc[n_ligne_datatable, 'fao_code'], allData), "weightMeasureMethod": None }) MultipleCatches.append(catches) return MultipleCatches
[docs] def create_catches_dict(dict, allData): """ Fonction de construction du json pour les catches Args: datatable (datatable): datatable créé pour une journée / un set allData (json): Données de références Returns: _type_: le json rempli à partir des infos de mon logbook """ MultipleCatches = [] for fish in dict: species_code = fish["species"] onBoardProcessing = fish['onBoardProcessing'] catchFate = fish['catchFate'] discardHealthStatus = fish['discardHealthStatus'] count = fish["count"] kg = fish["kg"] species_topiaid = get_species_topiaid(species_code, allData) catches = {"homeId": None, "count": count, "totalWeight": kg, "hookWhenDiscarded": None, "depredated": None, "beatDiameter": None, "photoReferences": None, "number": None, "acquisitionMode": 1, "countDepredated": None, "depredatedProportion": None, "tagNumber": None, "catchFate": get_catchfate_topiaid(catchFate, allData), "discardHealthStatus": get_discardHealthStatus_topiaid(discardHealthStatus, allData), "species": species_topiaid, "predator": [], "catchHealthStatus": None, "onBoardProcessing": get_processing_topiaid(onBoardProcessing, allData), "weightMeasureMethod": None } MultipleCatches.append(catches) return MultipleCatches
[docs] def create_starttimestamp(df_donnees_p1, allData, version, index_day, need_hour=bool): """ Fonction qui permet d'avoir le bon format de date-time pour envoyer le json Args: df_donnees_p1 (_type_): ma page excel 1 allData (json): Données de références index_day (int): le numero de la ligne de mon datatable need_hour (bool) : si true - on va chercher l'heure correspondante dans le datatable, si false - on ajoute '00:00:00' cad que le bateau n'est pas en train de pêcher donc il nous faut une horaire juste pour convenir au format demandé Returns: _type_: la datetime au format qui permet l'insersion dans la bdd """ if need_hour is True: time_ = palangre_syc.excel_extractions.extract_time(df_donnees_p1, allData, version).loc[index_day, 'Time'] else: time_ = '00:00:00' date_formated = '{}-{:02}-{:02}T{}.000Z'.format( palangre_syc.excel_extractions.extract_logbook_date(df_donnees = df_donnees_p1, version=version).loc[palangre_syc.excel_extractions.extract_logbook_date( df_donnees_p1, version=version)['Logbook_name'] == 'Year', 'Value'].values[0], palangre_syc.excel_extractions.extract_logbook_date(df_donnees_p1, version=version).loc[palangre_syc.excel_extractions.extract_logbook_date( df_donnees_p1, version=version)['Logbook_name'] == 'Month', 'Value'].values[0], palangre_syc.excel_extractions.extract_time(df_donnees_p1, allData, version=version).loc[index_day, 'Day'], time_) return date_formated
[docs] def create_starttimestamp_from_field_date(date): """ Fonction qui permet d'avoir le bon format de date-time pour envoyer le json Args: date: issue du input Returns: datetime: pour stratDate et endDAte """ date_formated = '{}-{:02}-{:02}T{}.000Z'.format(int(date[:4]), int(date[5:7]), int(date[-2:]), '00:00:00') return date_formated
[docs] def search_date_into_json(json_previoustrip, date_to_look_for): """ Fonction qui cherche une date est présente dans un précédent trip (json file) Args: json_previoustrip (json): du précédent trip qu'on veut continuer date_to_look_for (date): aaaa-mm-jj Returns: bool: True si la date est dans le json, False sinon """ for content in json_previoustrip: for activity in content['activityLogbook'] : start_time = activity.get('startTimeStamp') if start_time and start_time.startswith(date_to_look_for) : return True return False
[docs] def create_activity_and_set(start_extraction, end_extraction, context, allData, df_donnees_p1, df_donnees_p2, df_donnees_p3=None, df_donnees_p4=None): """ Fonction qui créé les activités et les set selon le format json attendu dans la base de données Observe Args: df_donnees_p1 (dataframe): page 1 du logbook excel df_donnees_p2 (dataframe): page 2 du logbook excel allData (json): Données de références start_extraction (int): numéro qui indique la ligne du logbook à partir de laquelle on commence à remplir le json (0 si on commence au 1er jour, 5 si la marée commence au 6 du mois) end_extraction (int): numéro qui indique la ligne du logbook à laquelle on arrête de remplir le json (len(excel_p1) si on considère le logbook entier, 15 si la marée s'arrête au 16 du mois) Returns: json: des activités et set pour la période et le logbook soumis par l'utilisateur """ ############################# # messages d'erreurs if isinstance(palangre_syc.excel_extractions.extract_gear_info(df_donnees_p1, version=context['version']), tuple): df_gear, _ = palangre_syc.excel_extractions.extract_gear_info(df_donnees_p1, version=context['version']) else: df_gear = palangre_syc.excel_extractions.extract_gear_info(df_donnees_p1, version=context['version']) if context['version'] == "ll_17.6": # mais pour l'instant on ne traite pas cette info anyways if isinstance(palangre_syc.excel_extractions.extract_line_material_v17(df_donnees_p1), tuple): df_line, _ = palangre_syc.excel_extractions.extract_line_material_v17(df_donnees_p1) else: df_line = palangre_syc.excel_extractions.extract_line_material_v17(df_donnees_p1) if context['version'] == "ll_26": # mais pour l'instant on ne traite pas cette info anyways if isinstance(palangre_syc.excel_extractions.extract_line_material_v26(df_donnees_p1), tuple): df_line, _ = palangre_syc.excel_extractions.extract_line_material_v26(df_donnees_p1) else: df_line = palangre_syc.excel_extractions.extract_line_material_v26(df_donnees_p1) # df_ref_linematerial = info de référence fournies par le logbook avec le code de ref d'observe df_ref_linematerial = palangre_syc.excel_extractions.extract_material_ref(df_donnees_p4) if 'Name 名稱' in df_ref_linematerial.columns: df_ref_linematerial['Name'] = api_traitement.common_functions.remove_spec_char_from_list(df_ref_linematerial['Name 名稱'].tolist()) else: df_ref_linematerial.columns = df_ref_linematerial.columns.str.strip() df_ref_linematerial['Name'] = df_ref_linematerial['Name'].str.strip() # On associe le code de ref linematerial_datatable = df_line.merge( df_ref_linematerial[['CODE', 'Code_v26', 'Name']], left_on='Value', right_on='CODE', how='left') ############################# # if context['version'] == "ll_17.6": # fishdatatable = create_catch_table_fishes(df_donnees_p1, df_donnees_p2, df_donnees_p3 =None, df_donnees_p4 =None, row_number=i, version=context['version']) if context['version'] == "ll_26": fishdatatable = palangre_syc.excel_extractions.extract_catches_v26(df_donnees_p1, version=context['version']) bycatchdatatable = palangre_syc.excel_extractions.extract_bycatch_page2_v26(df_donnees_p2) bycatchdatatable_bis = palangre_syc.excel_extractions.extract_bycatch_page3_v26(df_donnees_p3, df_ref = df_donnees_p4) combined_catches = [] for f, b, b2 in zip(fishdatatable, bycatchdatatable, bycatchdatatable_bis): combined_catches.append(f + b + b2) MultipleActivity = [] for i in range(start_extraction, end_extraction): set = { 'homeId': None, 'comment': None, 'number': None, 'basketsPerSectionCount': None, 'branchlinesPerBasketCount': palangre_syc.excel_extractions.extract_fishing_effort(df_donnees_p1, version=context['version']).loc[i, 'Hooks per basket'], 'totalSectionsCount': None, 'totalBasketsCount': palangre_syc.excel_extractions.extract_fishing_effort(df_donnees_p1, version=context['version']).loc[i, 'Total hooks / Hooks per basket'], 'totalHooksCount': palangre_syc.excel_extractions.extract_fishing_effort(df_donnees_p1, version=context['version']).loc[i, 'Total hooks'], 'totalLightsticksCount': palangre_syc.excel_extractions.extract_fishing_effort(df_donnees_p1, version=context['version']).loc[i, 'Total lightsticks'], 'weightedSnap': False, 'snapWeight': None, 'weightedSwivel': False, 'swivelWeight': None, 'timeBetweenHooks': None, 'shooterUsed': False, 'shooterSpeed': None, 'maxDepthTargeted': None, } set.update({'settingStartTimeStamp': create_starttimestamp(df_donnees_p1, allData, version=context['version'], index_day=i, need_hour=True)}) set.update({'settingStartLatitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Latitude'], 'settingStartLongitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Longitude'], 'settingEndTimeStamp': None, 'settingEndLatitude': None, 'settingEndLongitude': None, 'settingVesselSpeed': None, 'haulingDirectionSameAsSetting': None, 'haulingStartTimeStamp': None, 'haulingStartLatitude': None, 'haulingStartLongitude': None, 'haulingEndTimeStamp': None, 'haulingEndLatitude': None, 'haulingEndLongitude': None, 'haulingBreaks': None, 'monitored': False,}) # Change of column name if context['version'] == "ll_17.6": totalLineLength_colnames = "Set Line length m" elif context['version'] == "ll_26": totalLineLength_colnames = 'Main Line length m' if palangre_syc.excel_extractions.extract_time(df_donnees_p1, allData, version=context['version']).loc[i, 'VesselActivity_topiaId'] == 'fr.ird.referential.ll.common.VesselActivity#666#04': set.update({ # En fait "totalLineLength" serait de plusierus km, ce qui ne correspond pas avec le champ "Set Line length m" 'totalLineLength' : None, 'basketLineLength': None, 'lengthBetweenBranchlines':None }) else : set.update({ # En fait "totalLineLength" serait de plusierus km, ce qui ne correspond pas avec le champ "Set Line length m" 'totalLineLength' : palangre_syc.excel_extractions.extract_gear_info(df_donnees_p1, version=context['version']).loc[palangre_syc.excel_extractions.extract_gear_info(df_donnees_p1, version=context['version'])['Logbook_name'] == totalLineLength_colnames, 'Value'].values[0], 'basketLineLength': None, 'lengthBetweenBranchlines': df_gear.loc[df_gear['Logbook_name'] == 'Length between branches m', 'Value'].values[0] }) if context['version'] == "ll_17.6": bait_datatable = palangre_syc.excel_extractions.extract_bait_v17(df_donnees_p1) set.update({'baitsComposition': create_bait_composition(bait_datatable, allData, context['version']), 'floatlinesComposition': create_floatline_composition_v17(df_gear, df_line), 'branchlinesComposition': create_branchline_composition_v17(df_gear),}) elif context['version'] == "ll_26": # bait_datatable = info extraites du logbook bait_logbook = palangre_syc.excel_extractions.extract_bait_v26(df_donnees_p1) # df_ref_baits = info de référence fournies par le logbook avec le code de ref d'observe # df_ref_baits = palangre_syc.excel_extractions.extract_baits_ref(df_donnees_p4) # df_ref_baits['Name'] = api_traitement.common_functions.remove_spec_char_from_list(df_ref_baits['Name 名稱'].tolist()) # # On associe le code de ref # bait_datatable = bait_logbook.merge( # df_ref_baits[['CODE', 'Name']], # left_on='Bait', # right_on='Name', # how='left') floatlines_composition = [{ "homeId": None, "length": df_gear.loc[df_gear['Logbook_name'] == 'Floatline length m', 'Value'].values[0], "proportion": 100, "lineType": create_lineType_v26(linematerial_datatable.loc[linematerial_datatable["Logbook_name"] == "Floatline material", "Code_v26"].values[0], allData) }] branchlines_composition = [{ 'homeId': None, 'length': df_gear.loc[df_gear['Logbook_name'] == 'Branchline length m', 'Value'].values[0], 'proportion': 100, 'tracelineLength': None, 'topType': create_lineType_v26(linematerial_datatable.loc[linematerial_datatable["Logbook_name"] == "Branchline topline", "Code_v26"].values[0], allData), 'tracelineType': create_lineType_v26(linematerial_datatable.loc[linematerial_datatable["Logbook_name"] == "Branchline traceline", "Code_v26"].values[0], allData), }] set.update({'baitsComposition': create_bait_composition(bait_logbook.iloc[i][['Bait']], allData, context['version']), # 'baitsComposition': create_bait_composition(bait_datatable.iloc[i][['Bait', 'CODE']], allData, context['version']), 'floatlinesComposition': floatlines_composition, 'branchlinesComposition': branchlines_composition,}) set.update({'hooksComposition': [], 'settingShape': None, }) if context['version'] == "ll_17.6": datatable = create_catch_table_fishes(df_donnees_p1, df_donnees_p2, row_number=i) set.update({'catches': create_catches(datatable, allData),}) elif context['version'] == "ll_26": set.update({'catches': create_catches_dict(combined_catches[i], allData),}) ##### GET DPECIES NOT IN OBSERVE # Observe_species = pd.DataFrame(allData["Species"]) # Ref_species = palangre_syc.excel_extractions.ref_table_bycatch(df_donnees_p4) # Ref_species = Ref_species.rename(columns={'CODE 代碼': 'faoCode', 'NAME_EN 英文名': 'NAME_EN'}) # merged_left = pd.merge(Ref_species, Observe_species, on='faoCode', how='left') # filtered_merged_left = merged_left[ # # (merged_left['topiaId'].isna()) | # (merged_left['status'] == "disabled")] # file_name = 'liste_not_in_observe.xlsx' # filtered_merged_left.to_excel(file_name, index=False) # set.update({'catches': None,}) if context['version'] == "ll_17.6" and (len(df_line) == 1) : set.update({'lineType': create_lineType_v17(df_line.loc[df_line["Value"] != "", "Logbook_name"].values[0]), }) elif context['version'] == "ll_26": set.update({'lineType': create_lineType_v26(linematerial_datatable.loc[linematerial_datatable["Logbook_name"] == "Main line material", "Code_v26"].values[0], allData), }) else: set.update({'lineType': None, }) set.update({ 'lightsticksUsed': False, 'lightsticksType': None, 'lightsticksColor': None, 'mitigationType': [] }) activity = { 'homeId': None, 'comment': None, 'endTimeStamp': None, 'wind': None, 'windDirection': None, 'currentSpeed': None, 'currentDirection': None,} # If Outside EEZ if palangre_syc.excel_extractions.extract_time(df_donnees_p1, allData, version=context['version']).loc[i, 'VesselActivity_topiaId'] == 'fr.ird.referential.ll.common.VesselActivity#666#04': activity.update({'startTimeStamp': create_starttimestamp(df_donnees_p1, allData, version=context['version'], index_day=i, need_hour=False), 'latitude': None, 'longitude': None, 'seaSurfaceTemperature': None,}) # If Fishing operation elif palangre_syc.excel_extractions.extract_time(df_donnees_p1, allData, version=context['version']).loc[i, 'VesselActivity_topiaId'] == 'fr.ird.referential.ll.common.VesselActivity#1239832686138#0.1': activity.update({'startTimeStamp': create_starttimestamp(df_donnees_p1, allData, version=context['version'], index_day=i, need_hour=True), 'latitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Latitude'], 'longitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Longitude'], 'seaSurfaceTemperature': palangre_syc.excel_extractions.extract_temperature(df_donnees_p1, version=context['version']).loc[i, 'Temperature'], }) else: activity.update({'startTimeStamp': create_starttimestamp(df_donnees_p1, allData, version=context['version'], index_day=i, need_hour=False), #'startTimeStamp' : '2022-07-26T00:00:00.000Z' 'latitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Latitude'], 'longitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Longitude'], 'seaSurfaceTemperature': palangre_syc.excel_extractions.extract_temperature(df_donnees_p1, version=context['version']).loc[i, 'Temperature'], }) # activity.update({ # 'latitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Latitude'], # 'longitude': palangre_syc.excel_extractions.extract_positions(df_donnees_p1, version=context['version']).loc[i, 'Longitude'], # 'seaSurfaceTemperature': palangre_syc.excel_extractions.extract_temperature(df_donnees_p1, version=context['version']).loc[i, 'Temperature'], # }) if (context['at_port_checkbox'] == "true"): activity.update({'vesselActivity' : 'fr.ird.referential.ll.common.VesselActivity#666#03',}) elif ((context['continuetrip'] == None) and (i == start_extraction)): activity.update({'vesselActivity' : 'fr.ird.referential.ll.common.VesselActivity#666#03',}) else: activity.update({'vesselActivity': palangre_syc.excel_extractions.extract_time(df_donnees_p1, allData, version=context['version']).loc[i, 'VesselActivity_topiaId'], }) activity.update({'dataQuality': None, 'fpaZone': None, 'relatedObservedActivity': None, }) if activity.get('vesselActivity') == 'fr.ird.referential.ll.common.VesselActivity#1239832686138#0.1': activity.update({'set': set, }) else: activity.update({ 'set': None, 'sample': None }) MultipleActivity.append(activity) return MultipleActivity
[docs] def create_trip(df_donnees_p1, MultipleActivity, allData, context): """ Fonction qui créé un trip selon le format json attendu dans la base de données Observe (avec éventuellement les information d'un précédent trip si l'utilisateur update un trip existant) Args: df_donnees_p1 (dataframe): page 1 du logbook excel MultipleActivity (json): Inofrmations de sortie de la fonction "create_activity_and_set(df_donnees_p1, df_donnees_p2, allData, start_extraction, end_extraction)" allData (json): Données de références context (dict): infrormation concernant startDate, endDate, depPort, endPort saisies par l'utilisateur, mais aussi les information du trip à modifier / continuer si l'utilisateur choisi de continuer un trip existant Returns: json: trip """ # Dans le trip on a fixé : # tripType = Marée de pêche commerciale # observer = unknown car information non présente sur le logbook # species semble être TargetSpecies - a voir si on développe trip = { 'homeId': None, 'startDate': context['startDate'], 'endDate': context['endDate'], 'noOfCrewMembers': palangre_syc.excel_extractions.extract_cruise_info(df_donnees_p1, version=context['version']).loc[palangre_syc.excel_extractions.extract_cruise_info(df_donnees_p1, version=context['version'])['Logbook_name'] == 'No Of Crew', 'Value'].values[0], 'ersId': None, 'gearUseFeatures': None, 'activityObs': None, 'activityLogbook': MultipleActivity, 'landing': None, 'sample': None, 'tripType': 'fr.ird.referential.ll.common.TripType#1464000000000#02', 'observationMethod': None, 'observer': 'fr.ird.referential.common.Person#1254317601353#0.6617065204572095', 'vessel': get_vessel_topiaid(df_donnees_p1, allData), 'observationProgram': None, 'logbookProgram': context['programtopiaid'], 'captain': get_captain_topiaid(df_donnees_p1, allData, context), 'observationsDataEntryOperator': None, 'logbookDataEntryOperator': get_operator_topiaid(df_donnees_p1, allData, context), 'sampleDataEntryOperator': None, 'landingDataEntryOperator': None, 'ocean': context['oceantopiaid'], 'departureHarbour': context['depPort'], 'landingHarbour': context['endPort'], 'observationDataQuality': None, 'logbookDataQuality': None, 'generalComment': None, 'observationComment': None, 'logbookComment': None, 'species': get_target_species_topiaid(df_donnees_p1, allData, context), 'observationsAvailability': False, 'logbookAvailability': True, } return trip
[docs] def remove_keys(obj, keys_to_remove): if isinstance(obj, dict): for key in keys_to_remove: obj.pop(key, None) for value in obj.values(): remove_keys(value, keys_to_remove) elif isinstance(obj, list): for item in obj: remove_keys(item, keys_to_remove) return obj
[docs] def replace_null_false_true(obj): if isinstance(obj, dict): return {key: replace_null_false_true(value) for key, value in obj.items()} elif isinstance(obj, list): return [replace_null_false_true(item) for item in obj] elif obj == "null": return None elif obj == "true": return True elif obj == "false": return False else: return obj