vancauwe commited on
Commit
3f7aaf0
·
unverified ·
2 Parent(s): 819809c cfc4b71

Merge pull request #43 from sdsc-ordes/feat/hugging-face-dataset

Browse files
.github/workflows/sync_dataset_hf.yml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Sync Hugging Face Dataset
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 * * * *' # Runs every hour
6
+
7
+ jobs:
8
+ sync_dataset:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Checkout repository
12
+ uses: actions/checkout@v2
13
+
14
+ - name: Set up Python
15
+ uses: actions/setup-python@v2
16
+ with:
17
+ python-version: '3.x'
18
+
19
+ - name: Install dependencies
20
+ run: |
21
+ python -m pip install --upgrade pip
22
+ pip install -r requirements.txt
23
+
24
+ - name: Sync Datasets
25
+ env:
26
+ HF_TOKEN: ${{ secrets.HF_TOKEN }}
27
+ run: python sync_dataset_hf.py
app/behavior/behavior_checkbox.py CHANGED
@@ -2,11 +2,11 @@ import gradio as gr
2
  from utils.utils_config import get_custom_config_dropdowns
3
  from utils.utils_checkbox import create_checkbox
4
  from utils.utils_visible import set_visible
5
- from validation_submission.add_json import add_data_tmp
6
 
7
  def on_select_behavior(behavior_checkbox, individual):
8
  behavior_checkbox = [behavior.lower() for behavior in behavior_checkbox]
9
- individual = add_data_tmp("wounded_dead", "behaviors_type", behavior_checkbox)
10
  return individual
11
 
12
  def retrieve_behavior_options_description():
@@ -27,5 +27,5 @@ def create_behavior_checkbox(section: str, visible):
27
  def show_behavior(choice, section: str, individual):
28
  visible = set_visible(choice)
29
  checkbox, text = create_behavior_checkbox(section, visible)
30
- individual = add_data_tmp("wounded_dead", "behaviors_radio", choice, individual)
31
  return checkbox, text, individual
 
2
  from utils.utils_config import get_custom_config_dropdowns
3
  from utils.utils_checkbox import create_checkbox
4
  from utils.utils_visible import set_visible
5
+ from validation_submission.utils_individual import add_data_to_individual
6
 
7
  def on_select_behavior(behavior_checkbox, individual):
8
  behavior_checkbox = [behavior.lower() for behavior in behavior_checkbox]
9
+ individual = add_data_to_individual("behaviors_type", behavior_checkbox, individual)
10
  return individual
11
 
12
  def retrieve_behavior_options_description():
 
27
  def show_behavior(choice, section: str, individual):
28
  visible = set_visible(choice)
29
  checkbox, text = create_behavior_checkbox(section, visible)
30
+ individual = add_data_to_individual("behaviors_radio", choice, individual)
31
  return checkbox, text, individual
app/circumstances/circumstances.py CHANGED
@@ -3,7 +3,7 @@ import os
3
  from dotenv import load_dotenv
4
 
5
  from utils.utils_visible import set_visible
6
- from validation_submission.add_json import add_data_tmp
7
 
8
  load_dotenv()
9
  PATH = os.getcwd() + "/"
@@ -15,7 +15,7 @@ CAUSE_COL_WIDTH = "50px"
15
 
16
  def show_circumstances(choice, individual):
17
  visible = set_visible(choice)
18
- individual = add_data_tmp("wounded_dead",
19
  "circumstance_radio",
20
  choice, individual)
21
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible)
 
3
  from dotenv import load_dotenv
4
 
5
  from utils.utils_visible import set_visible
6
+ from validation_submission.utils_individual import add_data_to_individual
7
 
8
  load_dotenv()
9
  PATH = os.getcwd() + "/"
 
15
 
16
  def show_circumstances(choice, individual):
17
  visible = set_visible(choice)
18
+ individual = add_data_to_individual("wounded_dead",
19
  "circumstance_radio",
20
  choice, individual)
21
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible)
app/circumstances/circumstances_dropdowns.py CHANGED
@@ -1,6 +1,6 @@
1
  import gradio as gr
2
  from utils.utils_config import get_custom_config_dropdowns
3
- from validation_submission.add_json import add_data_tmp
4
 
5
  #--------------------------------------------------------- LEVEL 1 DROPDOWNS
6
  def retrieve_config_options(label, dropdown_config):
@@ -23,22 +23,22 @@ def create_dropdown_level1(label, individual):
23
 
24
  def dropdown_collision(individual):
25
  label = "Collision with a means of transport"
26
- individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
27
  return create_dropdown_level1(label, individual)
28
 
29
  def dropdown_deliberate_destruction(individual):
30
  label = "Destruction / Deliberatly removed"
31
- individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
32
  return create_dropdown_level1(label, individual)
33
 
34
  def dropdown_indirect_destruction(individual):
35
  label = "Indirect destruction"
36
- individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
37
  return create_dropdown_level1(label, individual)
38
 
39
  def dropdown_natural_cause(individual):
40
  label = "Natural cause"
41
- individual = add_data_tmp("wounded_dead", "circumstance", label.lower(), individual)
42
  return create_dropdown_level1(label, individual)
43
 
44
 
@@ -72,7 +72,7 @@ def get_options(value):
72
 
73
  def on_select(evt: gr.SelectData, individual): # SelectData is a subclass of EventData
74
  options_label, options_dropdown, open_field, extras, extras_label = get_options(evt.value)
75
- individual = add_data_tmp("wounded_dead",
76
  "circumstance_type",
77
  {"type": (evt.value).lower(),
78
  "option_dropdown_label" : options_label.lower() if options_label is not None else 'NA',
@@ -96,20 +96,20 @@ def on_select(evt: gr.SelectData, individual): # SelectData is a subclass of Ev
96
  return dropdown_level2, openfield_level2, dropdown_extra_level2, individual
97
 
98
  def on_select_dropdown_level2(evt: gr.SelectData, individual):
99
- individual = add_data_tmp("wounded_dead",
100
  "circumstance_option_dropdown",
101
  evt.value.lower(), individual)
102
  return individual
103
 
104
  def on_select_dropdown_extra_level2(evt: gr.SelectData, individual):
105
- individual = add_data_tmp("wounded_dead",
106
  "circumstance_extra",
107
  evt.value.lower(), individual)
108
  return individual
109
 
110
  def on_change_openfield_level2(openfield_level2_dead, individual):
111
  print("Saving open field")
112
- individual = add_data_tmp("wounded_dead",
113
  "circumstance_open_field",
114
  str(openfield_level2_dead).lower(), individual)
115
  return individual
 
1
  import gradio as gr
2
  from utils.utils_config import get_custom_config_dropdowns
3
+ from validation_submission.utils_individual import add_data_to_individual
4
 
5
  #--------------------------------------------------------- LEVEL 1 DROPDOWNS
6
  def retrieve_config_options(label, dropdown_config):
 
23
 
24
  def dropdown_collision(individual):
25
  label = "Collision with a means of transport"
26
+ individual = add_data_to_individual("wounded_dead", "circumstance", label.lower(), individual)
27
  return create_dropdown_level1(label, individual)
28
 
29
  def dropdown_deliberate_destruction(individual):
30
  label = "Destruction / Deliberatly removed"
31
+ individual = add_data_to_individual("wounded_dead", "circumstance", label.lower(), individual)
32
  return create_dropdown_level1(label, individual)
33
 
34
  def dropdown_indirect_destruction(individual):
35
  label = "Indirect destruction"
36
+ individual = add_data_to_individual("wounded_dead", "circumstance", label.lower(), individual)
37
  return create_dropdown_level1(label, individual)
38
 
39
  def dropdown_natural_cause(individual):
40
  label = "Natural cause"
41
+ individual = add_data_to_individual("wounded_dead", "circumstance", label.lower(), individual)
42
  return create_dropdown_level1(label, individual)
43
 
44
 
 
72
 
73
  def on_select(evt: gr.SelectData, individual): # SelectData is a subclass of EventData
74
  options_label, options_dropdown, open_field, extras, extras_label = get_options(evt.value)
75
+ individual = add_data_to_individual("wounded_dead",
76
  "circumstance_type",
77
  {"type": (evt.value).lower(),
78
  "option_dropdown_label" : options_label.lower() if options_label is not None else 'NA',
 
96
  return dropdown_level2, openfield_level2, dropdown_extra_level2, individual
97
 
98
  def on_select_dropdown_level2(evt: gr.SelectData, individual):
99
+ individual = add_data_to_individual("wounded_dead",
100
  "circumstance_option_dropdown",
101
  evt.value.lower(), individual)
102
  return individual
103
 
104
  def on_select_dropdown_extra_level2(evt: gr.SelectData, individual):
105
+ individual = add_data_to_individual("wounded_dead",
106
  "circumstance_extra",
107
  evt.value.lower(), individual)
108
  return individual
109
 
110
  def on_change_openfield_level2(openfield_level2_dead, individual):
111
  print("Saving open field")
112
+ individual = add_data_to_individual("wounded_dead",
113
  "circumstance_open_field",
114
  str(openfield_level2_dead).lower(), individual)
115
  return individual
app/classes.py CHANGED
@@ -39,6 +39,7 @@ class ImageBase64(BaseModel):
39
  class Report(BaseModel):
40
  identifier: str
41
  image: ImageBase64
 
42
  geolocalisation: Geolocalisation
43
  wounded_state: str
44
  wounded: Optional[Wounded] = None
 
39
  class Report(BaseModel):
40
  identifier: str
41
  image: ImageBase64
42
+ image_md5: str
43
  geolocalisation: Geolocalisation
44
  wounded_state: str
45
  wounded: Optional[Wounded] = None
app/dead.py CHANGED
@@ -3,7 +3,7 @@ from circumstances.circumstances import create_circumstances
3
  from physical.physical_select_animal import create_bird_anatomy
4
  from physical.physical_checkbox import process_body_parts
5
  from follow_up.followup_events import create_followup_dropdowns, create_followup_open
6
- from validation_submission.add_json import add_data_to_individual
7
 
8
  from dotenv import load_dotenv
9
  import os
@@ -18,7 +18,7 @@ def show_section_dead(visible, individual):
18
  individual = add_data_to_individual("dead_state", "Yes", individual)
19
 
20
  with gr.Column(visible=visible, elem_id="dead") as section_dead:
21
- gr.Markdown("# Dead Animal")
22
  gr.Button("Do you know what conditions caused this?",
23
  icon=PATH_ICONS + "eye.png",
24
  variant= "primary")
@@ -26,7 +26,7 @@ def show_section_dead(visible, individual):
26
  radio_cause = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
27
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible=False)
28
 
29
- gr.Button("Are there physical changes on the bird?",
30
  icon=PATH_ICONS + "cardiogram.png",
31
  variant= "primary")
32
  radio_physical = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
 
3
  from physical.physical_select_animal import create_bird_anatomy
4
  from physical.physical_checkbox import process_body_parts
5
  from follow_up.followup_events import create_followup_dropdowns, create_followup_open
6
+ from validation_submission.utils_individual import add_data_to_individual
7
 
8
  from dotenv import load_dotenv
9
  import os
 
18
  individual = add_data_to_individual("dead_state", "Yes", individual)
19
 
20
  with gr.Column(visible=visible, elem_id="dead") as section_dead:
21
+ gr.Markdown("## The animal is dead.")
22
  gr.Button("Do you know what conditions caused this?",
23
  icon=PATH_ICONS + "eye.png",
24
  variant= "primary")
 
26
  radio_cause = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
27
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible=False)
28
 
29
+ gr.Button("Are there physical changes on the animal?",
30
  icon=PATH_ICONS + "cardiogram.png",
31
  variant= "primary")
32
  radio_physical = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
app/display.py DELETED
@@ -1,121 +0,0 @@
1
- import gradio as gr
2
- import pandas as pd
3
- from gradio_modal import Modal
4
- from PIL import Image
5
- from io import BytesIO
6
- import base64
7
-
8
- from validation_submission.submission import validate_save_individual
9
- from validation_submission.get_json import get_json_all_individuals
10
-
11
- HEADERS = ["Identifier", "Location", "Wounded", "Dead"]
12
-
13
-
14
- def save_display_individual(gallery, df, error_box, data):
15
- #print(data)
16
- individual, error_box, data = validate_save_individual(data, error_box)
17
- if individual:
18
- all_animals = get_json_all_individuals()
19
- gallery_animals = process_animals_for_gallery(all_animals)
20
- gallery = make_gallery(gallery_animals)
21
- df_animals = process_animals_for_df(all_animals)
22
- df = make_df(df_animals)
23
- return gallery, df, error_box, data
24
-
25
- # ----------------------------------
26
- # GALLERY
27
-
28
- def convert_image(image_base64_str):
29
- im = Image.open(BytesIO(base64.b64decode(image_base64_str)))
30
- return im
31
-
32
- def set_gallery_size(len_animals):
33
- if len_animals < 10:
34
- num_cols=5
35
- num_rows=2
36
- else:
37
- num_cols = len_animals/2
38
- num_rows = len_animals/(num_cols)
39
- return num_cols, num_rows
40
-
41
- def process_animals_for_gallery(all_animals):
42
- gallery_animals = []
43
- for _, animal in all_animals.items():
44
- image = convert_image(animal["image"]["image"])
45
- caption = animal["identifier"]
46
- animal = (image, caption)
47
- gallery_animals.append(animal)
48
- return gallery_animals
49
-
50
- def make_gallery(gallery_animals):
51
- num_cols, num_rows = set_gallery_size(len(gallery_animals))
52
- gallery = gr.Gallery(
53
- label="Gallery of Records", elem_id="gallery",
54
- columns=[num_cols], rows=[num_rows],
55
- value=gallery_animals,
56
- object_fit="contain", height="auto", interactive=False)
57
- return gallery
58
-
59
- def keep_only_values(dict_to_filter):
60
- info_text = ""
61
- values_to_ignore = ["Yes", "No", "NA"]
62
- if dict_to_filter:
63
- for key, val in dict_to_filter.items():
64
- if type(val) is dict:
65
- subset_text = keep_only_values(val)
66
- info_text += f"{subset_text}"
67
- elif type(val) is list:
68
- for item in val:
69
- if type(item) is dict:
70
- subset_text = keep_only_values(item)
71
- info_text += f"{subset_text}"
72
- elif (val is not None) and (type(val) is not bool) and (val not in values_to_ignore):
73
- info_text += f" {key} : {val} |"
74
- else:
75
- print("Ignoring value: ", val)
76
- print("Associated key: ", key)
77
- else:
78
- info_text = "NaN"
79
- return info_text
80
-
81
- # ----------------------------------
82
- # DATAFRAME
83
-
84
- def process_animals_for_df(all_animals):
85
- df_animals = {}
86
- identifiers =[]
87
- geo =[]
88
- wounded =[]
89
- dead =[]
90
- for _, animal in all_animals.items():
91
- identifier_value = animal["identifier"]
92
- identifiers.append(identifier_value)
93
- geo_dict = animal["geolocalisation"]
94
- geo_values = keep_only_values(geo_dict)
95
- geo.append(geo_values)
96
- wounded_dict = animal["wounded"]
97
- wounded_values = keep_only_values(wounded_dict)
98
- wounded.append(wounded_values)
99
- dead_dict = animal["dead"]
100
- dead_values = keep_only_values(dead_dict)
101
- dead.append(dead_values)
102
- df_animals["Identifier"] = identifiers
103
- df_animals["Location"] = geo
104
- df_animals["Wounded"] = wounded
105
- df_animals["Dead"] = dead
106
- return df_animals
107
-
108
-
109
- def make_df(df_animals):
110
- df = pd.DataFrame.from_dict(df_animals)
111
- styled_df = df.style.set_properties(**{
112
- 'min-width': '25px',
113
- 'max-width': '50px', # Adjust width as needed
114
- 'white-space': 'normal', # Allows text to wrap to the next line
115
- 'word-wrap': 'break-word' # Breaks long words to fit within the width
116
- })
117
- df_gradio = gr.DataFrame(visible=True,
118
- value=styled_df,
119
- headers=HEADERS, interactive=False)
120
- return df_gradio
121
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/follow_up/followup_events.py CHANGED
@@ -1,6 +1,6 @@
1
  import gradio as gr
2
  from utils.utils_config import get_custom_config_dropdowns
3
- from validation_submission.add_json import add_data_tmp
4
 
5
  def create_followup_dropdowns(visible, elem_id):
6
  followup_config = get_custom_config_dropdowns("config_followup.json")
@@ -40,7 +40,7 @@ def create_fe_answer_dropdown(followup_config, visible, elem_id):
40
  return fe_answer_dropdown
41
 
42
  def save_fe(value, key, individual):
43
- individual = add_data_tmp("wounded_dead", "followup " + key.lower(), value.lower())
44
  return individual
45
 
46
 
 
1
  import gradio as gr
2
  from utils.utils_config import get_custom_config_dropdowns
3
+ from validation_submission.utils_individual import add_data_to_individual
4
 
5
  def create_followup_dropdowns(visible, elem_id):
6
  followup_config = get_custom_config_dropdowns("config_followup.json")
 
40
  return fe_answer_dropdown
41
 
42
  def save_fe(value, key, individual):
43
+ individual = add_data_to_individual("wounded_dead", "followup " + key.lower(), value.lower())
44
  return individual
45
 
46
 
app/geolocalisation/maps.py CHANGED
@@ -1,6 +1,6 @@
1
  from geopy.geocoders import Nominatim
2
  import gradio as gr
3
- from validation_submission.add_json import add_data_to_individual
4
  from geolocalisation.class_geolocalisation import Geolocalisation
5
 
6
 
 
1
  from geopy.geocoders import Nominatim
2
  import gradio as gr
3
+ from validation_submission.utils_individual import add_data_to_individual
4
  from geolocalisation.class_geolocalisation import Geolocalisation
5
 
6
 
app/main.py CHANGED
@@ -1,10 +1,9 @@
1
  import gradio as gr
2
  from gradio_modal import Modal
3
 
4
- from validation_submission.create_json import create_json_all_individuals, create_json_one_individual, create_tmp, reset_json
5
- from validation_submission.add_json import add_data_to_individual
6
  from validation_submission.validation import reset_error_box
7
- from display import save_display_individual
8
  from geolocalisation.maps import get_location
9
  from functools import partial
10
  from dead import show_section_dead
@@ -16,9 +15,16 @@ from physical.physical_checkbox import on_select_body_part, hide_physical
16
  from behavior.behavior_checkbox import show_behavior, on_select_behavior
17
  from follow_up.followup_events import save_fe
18
  from styling.style import *
19
- from styling.theme import css
20
 
21
  from geolocalisation.js_geolocation import js_geocode, display_location
 
 
 
 
 
 
 
22
 
23
  from dotenv import load_dotenv
24
  import os
@@ -27,170 +33,192 @@ PATH = os.getcwd() + "/"
27
  PATH_ASSETS = os.getenv('PATH_ASSETS')
28
  PATH_ICONS = PATH + PATH_ASSETS + "icons/"
29
 
30
- # with gr.Blocks(theme=theme, css=css) as demo:
31
  with gr.Blocks(theme='shivi/calm_seafoam') as demo:
32
  individual = gr.State({})
 
33
 
34
- #with gr.Blocks() as demo:
35
- create_json_all_individuals()
36
  # ---------------------------------------------------------
37
- # Intro Text
38
  with gr.Row():
39
- with gr.Row():
40
- gr.Image(PATH_ICONS+"swallow.png", scale =0.1,
41
  interactive=False,
42
  show_fullscreen_button = False, show_share_button=False,
43
  show_download_button=False, show_label=False)
44
- with gr.Column(scale=1):
45
- title = gr.Markdown("# Welcome to Digiwild", label="Title")
46
- description = gr.Markdown("Please record your wildlife observations here !", label="description")
47
-
48
- with gr.Row():
49
- show_modal = gr.Button("Add an Animal", icon = PATH_ICONS+"chicken.png", scale=3)
50
- submit_button = gr.Button("Submit All Animals", icon = PATH_ICONS+ "flying-doves-group.png", scale=1)
51
- show_creds = gr.Button("Credits", icon=PATH_ICONS+"copyright.png", scale=0.5)
52
- df = gr.Dataframe(headers=["Identifier", "Location", "Wounded", "Dead"], visible=False, interactive=False)
53
- gallery = gr.Gallery(
54
- label="Gallery of Records", elem_id="gallery",
55
- columns=[1], rows=[1],
56
- object_fit="contain", height="auto", interactive=False)
57
-
58
- with Modal(visible=False) as modal:
59
- # ---------------------------------------------------------
60
- # Intro Text
61
- with gr.Row():
62
- with gr.Row():
63
- gr.Image(PATH_ICONS+"pigeon.png", scale =0.1,
64
- interactive=False,
65
- show_fullscreen_button = False, show_share_button=False,
66
- show_download_button=False, show_label=False)
67
- with gr.Column(scale=1):
68
- title = gr.Markdown("# Animal Report", label="Title")
69
- description = gr.Markdown("Please record your observation here.", label="description")
70
 
 
 
 
 
 
 
 
 
 
71
  # ---------------------------------------------------------
72
- # Camera
73
- with gr.Row():
74
- def save_image(camera, individual):
75
- individual = add_data_to_individual("image", camera.tolist(), individual)
76
- return individual
77
 
78
- camera = gr.Image(elem_id="image")
79
- camera.input(save_image, inputs=[camera, individual], outputs=[individual])
80
- # ---------------------------------------------------------
81
- # Location
82
- #with gr.Row():
83
- with gr.Column(scale=1):
84
- gr.Button("Location", icon=PATH_ICONS+"pin.png", variant="primary")
85
- gr.Markdown("#### Location (Using address)")
86
- location = gr.Textbox(visible=True, interactive=True, label="Location of Sighting")
87
- #display location processing
88
- identified_location= gr.Textbox(visible=False, interactive=False,
89
- label="Identified GPS Location")
90
- with gr.Row():
91
- #to submit it
92
- submit_location = gr.Button("Get Coordinates using address",
93
- visible=True, interactive=True, scale=3)
94
- submit_location.click(get_location, inputs=[location, individual], outputs=[identified_location, individual])
95
- #to clear it
96
- clear_location = gr.ClearButton(components=[location, identified_location],
97
- visible=True, interactive=True, scale=1
98
- )
99
- clear_location.click()
100
 
101
- # Geolocation
102
- gr.Markdown("#### Location (Using GPS)")
103
- location_data = gr.JSON(label="Identified GPS Location")
104
- hidden_input = gr.Textbox(visible=False, elem_id="textbox_id")
105
- btn_gpslocation = gr.Button("Get Coordinates using GPS (Permission required)")
106
- btn_gpslocation.click(None, [], [], js=js_geocode)
107
- hidden_input.change(display_location, inputs=hidden_input, outputs=location_data)
 
 
 
 
 
108
 
109
-
110
- # Introducing text_box for Species
111
- gr.Button("General Details", icon=PATH_ICONS+"bird.png", variant="primary")
112
- with gr.Row():
113
- specie = gr.Textbox(
114
- label="Species (if known)",
115
- placeholder="e.g. European Robin, Common Blackbird",
116
- info="Enter the species name if you can identify it. If unsure, provide your best guess or general description (e.g. 'small brown bird')",
117
- visible=True,
118
- interactive=True
119
- )
120
 
121
- # Number of individuals
122
- with gr.Row():
123
- num_individuals = gr.Number(
124
- label="Number of Individuals",
125
- value=1, # Default value
126
- minimum=1,
127
- precision=0, # Only whole numbers
128
- info="Enter the number of animals observed",
129
- #placeholder="Enter number...",
130
- visible=True,
131
- interactive=True
132
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- # Introducing text_box for comments
135
- with gr.Row():
136
- comments = gr.TextArea(
137
- label="Additional Comments",
138
- placeholder="Enter any additional observations or notes about the sighting...",
139
- info="Optional: Add any relevant details about the animal(s) or circumstances",
140
- lines=3,
141
- max_lines=5,
142
- visible=True,
143
- interactive=True
144
- )
 
 
 
 
 
 
 
 
 
145
 
146
-
147
- # ---------------------------------------------------------
148
- # ---------------------------------------------------------
149
- # Dead and Wounded Buttons
150
- with gr.Row():
151
- gr.Image(PATH_ICONS+"medical-app.png", scale =0.1,
152
- interactive=False,
153
- show_fullscreen_button = False, show_share_button=False,
154
- show_download_button=False, show_label=False)
155
- with gr.Column():
156
- gr.Markdown("## The State of the Animal", label="Title")
157
- gr.Markdown("Please tell us if the animal was wounded / sick or dead.", label="description")
158
- gr.Markdown("Please fill out as many fields as you can, based on what you can see.", label="description")
159
- gr.Markdown("Do not touch the animal unless absolutely necessary.", label="description")
160
- with gr.Row() as block_form:
161
- with gr.Column(scale=1):
162
- butt_wounded = gr.Button("Wounded / Sick", elem_id="wounded")
163
- with gr.Column(scale=1):
164
- butt_dead = gr.Button("Dead", elem_id="dead")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
- # ---------------------------------------------------------
167
- # Initiate sections
168
- section_dead, individual, radio_circumstance_dead, radio_physical_dead,\
169
- button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead, \
170
- dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
171
- physical_boxes_dead, \
172
- checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead, \
173
- fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
174
- fe_name_recipient_dead, fe_collection_ref_dead \
175
- = show_section_dead(False, individual)
176
-
177
- section_wounded, individual, radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded, \
178
- button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded, \
179
- dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, \
180
- behavior_checkbox, behavior_text, \
181
- physical_boxes_wounded, \
182
  checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
183
  fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
184
- fe_name_recipient_wounded, fe_collection_ref_wounded \
185
- = show_section_wounded(False, individual)
186
 
187
- # ---------------------------------------------------------
188
- # ---------------------------------------------------------
189
- # ---------------------------------------------------------
190
- # Dead Button Logic
191
- partial_show_section_dead = partial(show_section_dead, True)
192
- partial_hide_section_wounded = partial(show_section_wounded, False)
193
- butt_dead.click(partial_show_section_dead,
194
  inputs=[individual],
195
  outputs=[section_dead,
196
  individual,
@@ -202,237 +230,178 @@ with gr.Blocks(theme='shivi/calm_seafoam') as demo:
202
  fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
203
  fe_name_recipient_dead, fe_collection_ref_dead \
204
  ])
205
-
206
- butt_dead.click(partial_hide_section_wounded,
207
- inputs=[individual],
208
- outputs=[section_wounded,
209
- individual,
210
- radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
211
- button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
212
- dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
213
- behavior_checkbox, behavior_text,
214
- physical_boxes_wounded, \
215
- checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
216
- fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
217
- fe_name_recipient_wounded, fe_collection_ref_wounded \
218
- ])
219
-
220
- # ---------------------------------------------------------
221
- # Wounded Button Logic
222
- partial_show_section_wounded = partial(show_section_wounded, True)
223
- partial_hide_section_dead = partial(show_section_dead, False)
 
 
224
 
225
- butt_wounded.click(partial_show_section_wounded,
226
- inputs=[individual],
227
- outputs=[section_wounded,
228
- individual,
229
- radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
230
- button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
231
- dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
232
- behavior_checkbox, behavior_text,
233
- physical_boxes_wounded, \
234
- checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
235
- fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
236
- fe_name_recipient_wounded, fe_collection_ref_wounded \
237
- ])
238
-
239
- butt_wounded.click(partial_hide_section_dead,
240
- inputs=[individual],
241
- outputs=[section_dead,
242
- individual,
243
- radio_circumstance_dead, radio_physical_dead,
244
- button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
245
- dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
246
- physical_boxes_dead, \
247
- checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead, \
248
- fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
249
- fe_name_recipient_dead, fe_collection_ref_dead \
250
- ])
251
-
252
- # ---------------------------------------------------------
253
- # ---------------------------------------------------------
254
- # ---------------------------------------------------------
255
- # ---------------------------------------------------------
256
- # DEAD
257
- # ---------------------------------------------------------
258
- # Radio Circumstance Dead
259
- radio_circumstance_dead.change(fn=show_circumstances,
260
- inputs=[radio_circumstance_dead, individual],
261
- outputs=[button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
262
- dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual]
263
- )
264
-
265
- # Dropdowns Dead
266
- button_collision_dead.click(dropdown_collision,
267
- inputs=[individual],
268
- outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
269
- button_deliberate_destruction_dead.click(dropdown_deliberate_destruction, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
270
- button_indirect_destruction_dead.click(dropdown_indirect_destruction, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
271
- button_natural_cause_dead.click(dropdown_natural_cause, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
272
 
273
- dropdown_dead.select(on_select, inputs=[individual], outputs=[dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
274
- dropdown_level2_dead.select(on_select_dropdown_level2, inputs=[individual], outputs=[individual] )
275
- openfield_level2_dead.change(on_change_openfield_level2, inputs=[openfield_level2_dead, individual], outputs=[individual])
276
- dropdown_extra_level2_dead.select(on_select_dropdown_extra_level2, inputs=[individual], outputs=[individual])
277
- # ---------------------------------------------------------
278
- # Radio Physical Dead
279
- radio_physical_dead.change(fn=show_physical,
280
- inputs=[radio_physical_dead, gr.Text("dead", visible=False), individual],
281
- outputs=[physical_boxes_dead, individual])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
- # Checkbox Physical Dead
284
- physical_boxes_dead.select(find_bounding_box,
285
- inputs=[physical_boxes_dead, gr.Textbox(value="dead", visible=False)],
286
- outputs=[checkbox_beak_dead, text_beak_dead,
287
- checkbox_body_dead, text_body_dead,
288
- checkbox_feathers_dead, text_feathers_dead,
289
- checkbox_head_dead, text_head_dead,
290
- checkbox_legs_dead, text_legs_dead
291
- ])
292
- checkbox_beak_dead.select(on_select_body_part, inputs=[checkbox_beak_dead, gr.Text("beak", visible=False), individual], outputs=[individual])
293
- checkbox_body_dead.select(on_select_body_part, inputs=[checkbox_body_dead, gr.Text("body", visible=False), individual], outputs=[individual])
294
- checkbox_feathers_dead.select(on_select_body_part, inputs=[checkbox_feathers_dead, gr.Text("feathers", visible=False), individual], outputs=[individual])
295
- checkbox_head_dead.select(on_select_body_part, inputs=[checkbox_head_dead, gr.Text("head", visible=False), individual], outputs=[individual])
296
- checkbox_legs_dead.select(on_select_body_part, inputs=[checkbox_legs_dead, gr.Text("legs", visible=False), individual], outputs=[individual])
297
- # ---------------------------------------------------------
298
- # ---------------------------------------------------------
299
- # ---------------------------------------------------------
300
- # ---------------------------------------------------------
301
- # WOUNDED
302
- # ---------------------------------------------------------
303
- # Radio Circumstance Wounded
304
- radio_circumstance_wounded.change(fn=show_circumstances,
305
- inputs=[radio_circumstance_wounded, individual],
306
- outputs=[button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
307
- dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual]
308
- )
309
-
310
- # Dropdowns Circumstance Wounded
311
- button_collision_wounded.click(dropdown_collision,
312
- inputs=[individual],
313
- outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
314
- button_deliberate_destruction_wounded.click(dropdown_deliberate_destruction, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
315
- button_indirect_destruction_wounded.click(dropdown_indirect_destruction, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
316
- button_natural_cause_wounded.click(dropdown_natural_cause, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
317
-
318
- dropdown_wounded.select(on_select, inputs=[individual], outputs=[dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
319
- dropdown_level2_wounded.select(on_select_dropdown_level2, inputs=[individual], outputs=[individual])
320
- openfield_level2_wounded.change(on_change_openfield_level2, inputs=[openfield_level2_wounded, individual])
321
- dropdown_extra_level2_wounded.select(on_select_dropdown_extra_level2, inputs=[individual], outputs=[individual])
322
- # ---------------------------------------------------------
323
- # Radio Behavior Wounded
324
- radio_behavior_wounded.change(fn=show_behavior,
325
- inputs=[radio_behavior_wounded, gr.Text("wounded / sick", visible=False), individual],
326
- outputs=[behavior_checkbox, behavior_text, individual])
327
- behavior_checkbox.select(on_select_behavior,
328
- inputs=[behavior_checkbox, individual],
329
- outputs=[individual])
330
- # ---------------------------------------------------------
331
- # Radio Physical Wounded
332
- radio_physical_wounded.change(fn=show_physical,
333
- inputs=[radio_physical_wounded, gr.Text("wounded / sick", visible=False), individual],
334
- outputs=[physical_boxes_wounded, individual])
335
 
336
- # Checkbox Physical Wounded
337
- physical_boxes_wounded.select(find_bounding_box,
338
- inputs=[physical_boxes_wounded, gr.Textbox(value="wounded / sick", visible=False)],
339
- outputs=[checkbox_beak_wounded, text_beak_wounded,
340
- checkbox_body_wounded, text_body_wounded,
341
- checkbox_feathers_wounded, text_feathers_wounded,
342
- checkbox_head_wounded, text_head_wounded,
343
- checkbox_legs_wounded, text_legs_wounded
344
- ])
345
- checkbox_beak_wounded.select(on_select_body_part, inputs=[checkbox_beak_wounded, gr.Text("beak", visible=False), individual], outputs=[individual])
346
- checkbox_body_wounded.select(on_select_body_part, inputs=[checkbox_body_wounded, gr.Text("body", visible=False), individual], outputs=[individual])
347
- checkbox_feathers_wounded.select(on_select_body_part, inputs=[checkbox_feathers_wounded, gr.Text("feathers", visible=False), individual], outputs=[individual])
348
- checkbox_head_wounded.select(on_select_body_part, inputs=[checkbox_head_wounded, gr.Text("head", visible=False), individual], outputs=[individual])
349
- checkbox_legs_wounded.select(on_select_body_part, inputs=[checkbox_legs_wounded, gr.Text("legs", visible=False), individual], outputs=[individual])
350
-
351
- # ---------------------------------------------------------
352
- # Follow Up Events Wounded
353
- fe_collection_dropdown_wounded.select(save_fe, inputs=[fe_collection_dropdown_wounded, gr.Textbox("animal collected", visible=False), individual], outputs=[individual])
354
- fe_recepient_dropdown_wounded.select(save_fe, inputs=[fe_recepient_dropdown_wounded, gr.Textbox("recipient", visible=False), individual],outputs=[individual])
355
- fe_radio_dropdown_wounded.select(save_fe, inputs=[fe_radio_dropdown_wounded, gr.Textbox("radiography", visible=False), individual],outputs=[individual])
356
- fe_answer_dropdown_wounded.select(save_fe, inputs=[fe_answer_dropdown_wounded, gr.Textbox("given answer", visible=False), individual],outputs=[individual])
357
- fe_name_recipient_wounded.input(save_fe, inputs=[fe_name_recipient_wounded, gr.Textbox("recipient name", visible=False), individual],outputs=[individual])
358
- fe_collection_ref_wounded.input(save_fe, inputs=[fe_collection_ref_wounded, gr.Textbox("collection reference", visible=False), individual],outputs=[individual])
359
 
360
- # ---------------------------------------------------------
361
- # Follow Up Events Dead
362
- fe_collection_dropdown_dead.select(save_fe, inputs=[fe_collection_dropdown_dead, gr.Textbox("animal collected", visible=False), individual],outputs=[individual])
363
- fe_recepient_dropdown_dead.select(save_fe, inputs=[fe_recepient_dropdown_dead, gr.Textbox("recipient", visible=False), individual],outputs=[individual])
364
- fe_radio_dropdown_dead.select(save_fe, inputs=[fe_radio_dropdown_dead, gr.Textbox("radiography", visible=False), individual],outputs=[individual])
365
- fe_answer_dropdown_dead.select(save_fe, inputs=[fe_answer_dropdown_dead, gr.Textbox("given answer", visible=False), individual],outputs=[individual])
366
- fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("recipient name", visible=False), individual],outputs=[individual])
367
- fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("collection reference", visible=False), individual], outputs=[individual])
368
 
369
- # ---------------------------------------------------------
370
- # Error Box
371
- error_box = gr.Text(value=None, visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
 
373
- # ---------------------------------------------------------
374
- # Add One Individual's Data to the Dataframe
375
- # And Allow clearing of all previous output
376
- with gr.Row():
377
- button_df = gr.Button("Submit Animal Report", icon=PATH_ICONS+"effective.png",
378
- variant="primary", scale = 3)
379
- button_clear = gr.ClearButton(variant="primary",
380
- scale = 1,
381
- components=[
382
- camera,
383
- location, identified_location,
384
- #dead reset
385
- radio_circumstance_dead, radio_physical_dead,
386
- button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
387
- dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead,
388
- physical_boxes_dead,
389
- checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead,
390
- fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead,
391
- fe_name_recipient_dead, fe_collection_ref_dead,
392
- #wounded reset
393
- radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
394
- button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
395
- dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
396
- behavior_checkbox, behavior_text,
397
- physical_boxes_wounded,
398
- checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded,
399
- fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded,
400
- fe_name_recipient_wounded, fe_collection_ref_wounded,
401
- error_box
402
- ])
403
- button_close = gr.Button("Back to Display", variant="primary", scale = 1)
404
- show_creds_v2 = gr.Button("Credits", icon=PATH_ICONS+"copyright.png", scale=0.5)
405
 
406
-
407
- # ---------------------------------------------------------
408
- # Button Click Logic
409
- button_clear.click()
410
- button_clear.click(hide_physical,
411
- outputs=[checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded])
412
- button_clear.click(hide_physical,
413
- outputs=[checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead])
414
-
415
- button_clear.click(reset_error_box, inputs=[error_box], outputs=[error_box])
416
- button_clear.click(reset_json)
417
-
418
- button_df.click(save_display_individual,
419
- inputs=[gallery, df, error_box, individual],
420
- outputs=[gallery, df, error_box, individual]
421
- )
422
- button_close.click(lambda: Modal(visible=False), None, modal)
423
-
424
  # ---------------------------------------------------------
425
- # Event Functions of the landing page buttons
426
- show_modal.click(lambda: Modal(visible=True), None, modal)
427
- show_modal.click(create_json_one_individual)
428
- show_modal.click(create_tmp)
429
- #submit_button.click(save_and_rest_df, inputs=[df], outputs=[df])
430
  # ---------------------------------------------------------
431
- from credits import credits_text
432
  with Modal(visible=False) as modal_creds:
433
  gr.Markdown(credits_text)
434
  show_creds.click(lambda: Modal(visible=True), None, modal_creds)
435
- show_creds_v2.click(lambda: Modal(visible=True), None, modal_creds)
436
 
437
 
438
 
 
1
  import gradio as gr
2
  from gradio_modal import Modal
3
 
4
+ from validation_submission.utils_individual import add_data_to_individual
5
+ from validation_submission.submission import validate_save_individual
6
  from validation_submission.validation import reset_error_box
 
7
  from geolocalisation.maps import get_location
8
  from functools import partial
9
  from dead import show_section_dead
 
15
  from behavior.behavior_checkbox import show_behavior, on_select_behavior
16
  from follow_up.followup_events import save_fe
17
  from styling.style import *
18
+ from credits import credits_text
19
 
20
  from geolocalisation.js_geolocation import js_geocode, display_location
21
+ from validation_submission.utils_individual import generate_random_md5
22
+
23
+ from datasets import disable_caching
24
+ disable_caching()
25
+
26
+ dataset_id = "SDSC/digiwild-dataset"
27
+ data_files = "data/train-00000-of-00001.parquet"
28
 
29
  from dotenv import load_dotenv
30
  import os
 
33
  PATH_ASSETS = os.getenv('PATH_ASSETS')
34
  PATH_ICONS = PATH + PATH_ASSETS + "icons/"
35
 
 
36
  with gr.Blocks(theme='shivi/calm_seafoam') as demo:
37
  individual = gr.State({})
38
+ individual.value = add_data_to_individual("image_md5", generate_random_md5(), individual.value)
39
 
 
 
40
  # ---------------------------------------------------------
41
+ # Header Text
42
  with gr.Row():
43
+ gr.Image(PATH_ICONS+"swallow.png", scale =0.1,
 
44
  interactive=False,
45
  show_fullscreen_button = False, show_share_button=False,
46
  show_download_button=False, show_label=False)
47
+ with gr.Column(scale=1):
48
+ title = gr.Markdown("# Welcome to Digiwild", label="Title")
49
+ description = gr.Markdown("Please record your wildlife observations here !", label="description")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
+ # ---------------------------------------------------------
52
+ # Camera
53
+ with gr.Row():
54
+ def save_image(camera, individual):
55
+ individual = add_data_to_individual("image", camera.tolist(), individual)
56
+ return individual
57
+ camera = gr.Image(elem_id="image")
58
+ camera.input(save_image, inputs=[camera, individual], outputs=[individual])
59
+
60
  # ---------------------------------------------------------
61
+ # General Details
62
+ with gr.Column(scale=1):
63
+ gr.Button("General Details", icon=PATH_ICONS+"bird.png", variant="primary")
 
 
64
 
65
+ with gr.Row():
66
+ specie = gr.Textbox(
67
+ label="Species (if known)",
68
+ placeholder="e.g. European Robin, Common Blackbird",
69
+ info="Enter the species name if you can identify it. If unsure, provide your best guess or general description (e.g. 'small brown bird')",
70
+ visible=True,
71
+ interactive=True
72
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
+ # Number of individuals
75
+ with gr.Row():
76
+ num_individuals = gr.Number(
77
+ label="Number of Individuals",
78
+ value=1, # Default value
79
+ minimum=1,
80
+ precision=0, # Only whole numbers
81
+ info="Enter the number of animals observed",
82
+ #placeholder="Enter number...",
83
+ visible=True,
84
+ interactive=True
85
+ )
86
 
87
+ # Introducing text_box for comments
88
+ with gr.Row():
89
+ comments = gr.TextArea(
90
+ label="Additional Comments",
91
+ placeholder="Enter any additional observations or notes about the sighting...",
92
+ info="Optional: Add any relevant details about the animal(s) or circumstances",
93
+ lines=3,
94
+ max_lines=5,
95
+ visible=True,
96
+ interactive=True
97
+ )
98
 
99
+ # ---------------------------------------------------------
100
+ # Location
101
+ gr.Button("Location", icon=PATH_ICONS+"pin.png", variant="primary")
102
+ with gr.Row():
103
+ with gr.Column(scale=1):
104
+ gr.Markdown("#### Location (Using address)")
105
+ location = gr.Textbox(visible=True, interactive=True, label="Location of Sighting")
106
+ #display location processing
107
+ identified_location= gr.Textbox(visible=False, interactive=False,
108
+ label="Identified GPS Location")
109
+ with gr.Row():
110
+ #to submit it
111
+ submit_location = gr.Button("Get Coordinates using address",
112
+ visible=True, interactive=True, scale=3)
113
+ submit_location.click(get_location, inputs=[location, individual], outputs=[identified_location, individual])
114
+ #to clear it
115
+ clear_location = gr.ClearButton(components=[location, identified_location],
116
+ visible=True, interactive=True, scale=1
117
+ )
118
+ clear_location.click()
119
+
120
+ with gr.Column(scale=1):
121
+ # Geolocation
122
+ gr.Markdown("#### Location (Using GPS)")
123
+ location_data = gr.JSON(label="Identified GPS Location")
124
+ hidden_input = gr.Textbox(visible=False, elem_id="textbox_id")
125
+ btn_gpslocation = gr.Button("Get Coordinates using GPS (Permission required)")
126
+ btn_gpslocation.click(None, [], [], js=js_geocode)
127
+ hidden_input.change(display_location, inputs=hidden_input, outputs=location_data)
128
+
129
+ # ---------------------------------------------------------
130
+ # Dead and Wounded Buttons
131
+ gr.Button("State of the Animal", variant="primary")
132
+ with gr.Row():
133
+ gr.Image(PATH_ICONS+"medical-app.png", scale =0.1,
134
+ interactive=False,
135
+ show_fullscreen_button = False, show_share_button=False,
136
+ show_download_button=False, show_label=False)
137
+ with gr.Column():
138
+ gr.Markdown("## The State of the Animal", label="Title")
139
+ gr.Markdown("Please tell us if the animal was wounded / sick or dead.", label="description")
140
+ gr.Markdown("Please fill out as many fields as you can, based on what you can see.", label="description")
141
+ gr.Markdown("### Do not touch the animal unless absolutely necessary.", label="description")
142
+ with gr.Row() as block_form:
143
+ with gr.Column(scale=1):
144
+ butt_wounded = gr.Button("Wounded / Sick", elem_id="wounded", variant="primary")
145
+ with gr.Column(scale=1):
146
+ butt_dead = gr.Button("Dead", elem_id="dead", variant="primary")
147
 
148
+ # ---------------------------------------------------------
149
+ # Initiate sections
150
+ section_dead, individual, radio_circumstance_dead, radio_physical_dead,\
151
+ button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead, \
152
+ dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
153
+ physical_boxes_dead, \
154
+ checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead, \
155
+ fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
156
+ fe_name_recipient_dead, fe_collection_ref_dead \
157
+ = show_section_dead(False, individual)
158
+
159
+ section_wounded, individual, radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded, \
160
+ button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded, \
161
+ dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, \
162
+ behavior_checkbox, behavior_text, \
163
+ physical_boxes_wounded, \
164
+ checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
165
+ fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
166
+ fe_name_recipient_wounded, fe_collection_ref_wounded \
167
+ = show_section_wounded(False, individual)
168
 
169
+ # ---------------------------------------------------------
170
+ # ---------------------------------------------------------
171
+ # ---------------------------------------------------------
172
+ # Dead Button Logic
173
+ partial_show_section_dead = partial(show_section_dead, True)
174
+ partial_hide_section_wounded = partial(show_section_wounded, False)
175
+ butt_dead.click(partial_show_section_dead,
176
+ inputs=[individual],
177
+ outputs=[section_dead,
178
+ individual,
179
+ radio_circumstance_dead, radio_physical_dead,
180
+ button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
181
+ dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, \
182
+ physical_boxes_dead, \
183
+ checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead, \
184
+ fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
185
+ fe_name_recipient_dead, fe_collection_ref_dead \
186
+ ])
187
+
188
+ butt_dead.click(partial_hide_section_wounded,
189
+ inputs=[individual],
190
+ outputs=[section_wounded,
191
+ individual,
192
+ radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
193
+ button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
194
+ dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
195
+ behavior_checkbox, behavior_text,
196
+ physical_boxes_wounded, \
197
+ checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
198
+ fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
199
+ fe_name_recipient_wounded, fe_collection_ref_wounded \
200
+ ])
201
+
202
+ # ---------------------------------------------------------
203
+ # Wounded Button Logic
204
+ partial_show_section_wounded = partial(show_section_wounded, True)
205
+ partial_hide_section_dead = partial(show_section_dead, False)
206
 
207
+ butt_wounded.click(partial_show_section_wounded,
208
+ inputs=[individual],
209
+ outputs=[section_wounded,
210
+ individual,
211
+ radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
212
+ button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
213
+ dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
214
+ behavior_checkbox, behavior_text,
215
+ physical_boxes_wounded, \
 
 
 
 
 
 
 
216
  checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded, \
217
  fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded, \
218
+ fe_name_recipient_wounded, fe_collection_ref_wounded \
219
+ ])
220
 
221
+ butt_wounded.click(partial_hide_section_dead,
 
 
 
 
 
 
222
  inputs=[individual],
223
  outputs=[section_dead,
224
  individual,
 
230
  fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead, \
231
  fe_name_recipient_dead, fe_collection_ref_dead \
232
  ])
233
+
234
+ # ---------------------------------------------------------
235
+ # ---------------------------------------------------------
236
+ # ---------------------------------------------------------
237
+ # ---------------------------------------------------------
238
+ # DEAD
239
+ # ---------------------------------------------------------
240
+ # Radio Circumstance Dead
241
+ radio_circumstance_dead.change(fn=show_circumstances,
242
+ inputs=[radio_circumstance_dead, individual],
243
+ outputs=[button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
244
+ dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual]
245
+ )
246
+
247
+ # Dropdowns Dead
248
+ button_collision_dead.click(dropdown_collision,
249
+ inputs=[individual],
250
+ outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
251
+ button_deliberate_destruction_dead.click(dropdown_deliberate_destruction, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
252
+ button_indirect_destruction_dead.click(dropdown_indirect_destruction, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
253
+ button_natural_cause_dead.click(dropdown_natural_cause, inputs=[individual], outputs=[dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
254
 
255
+ dropdown_dead.select(on_select, inputs=[individual], outputs=[dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead, individual])
256
+ dropdown_level2_dead.select(on_select_dropdown_level2, inputs=[individual], outputs=[individual] )
257
+ openfield_level2_dead.change(on_change_openfield_level2, inputs=[openfield_level2_dead, individual], outputs=[individual])
258
+ dropdown_extra_level2_dead.select(on_select_dropdown_extra_level2, inputs=[individual], outputs=[individual])
259
+ # ---------------------------------------------------------
260
+ # Radio Physical Dead
261
+ radio_physical_dead.change(fn=show_physical,
262
+ inputs=[radio_physical_dead, gr.Text("dead", visible=False), individual],
263
+ outputs=[physical_boxes_dead, individual])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
+ # Checkbox Physical Dead
266
+ physical_boxes_dead.select(find_bounding_box,
267
+ inputs=[physical_boxes_dead, gr.Textbox(value="dead", visible=False)],
268
+ outputs=[checkbox_beak_dead, text_beak_dead,
269
+ checkbox_body_dead, text_body_dead,
270
+ checkbox_feathers_dead, text_feathers_dead,
271
+ checkbox_head_dead, text_head_dead,
272
+ checkbox_legs_dead, text_legs_dead
273
+ ])
274
+ checkbox_beak_dead.select(on_select_body_part, inputs=[checkbox_beak_dead, gr.Text("beak", visible=False), individual], outputs=[individual])
275
+ checkbox_body_dead.select(on_select_body_part, inputs=[checkbox_body_dead, gr.Text("body", visible=False), individual], outputs=[individual])
276
+ checkbox_feathers_dead.select(on_select_body_part, inputs=[checkbox_feathers_dead, gr.Text("feathers", visible=False), individual], outputs=[individual])
277
+ checkbox_head_dead.select(on_select_body_part, inputs=[checkbox_head_dead, gr.Text("head", visible=False), individual], outputs=[individual])
278
+ checkbox_legs_dead.select(on_select_body_part, inputs=[checkbox_legs_dead, gr.Text("legs", visible=False), individual], outputs=[individual])
279
+ # ---------------------------------------------------------
280
+ # ---------------------------------------------------------
281
+ # ---------------------------------------------------------
282
+ # ---------------------------------------------------------
283
+ # WOUNDED
284
+ # ---------------------------------------------------------
285
+ # Radio Circumstance Wounded
286
+ radio_circumstance_wounded.change(fn=show_circumstances,
287
+ inputs=[radio_circumstance_wounded, individual],
288
+ outputs=[button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
289
+ dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual]
290
+ )
291
+
292
+ # Dropdowns Circumstance Wounded
293
+ button_collision_wounded.click(dropdown_collision,
294
+ inputs=[individual],
295
+ outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
296
+ button_deliberate_destruction_wounded.click(dropdown_deliberate_destruction, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
297
+ button_indirect_destruction_wounded.click(dropdown_indirect_destruction, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
298
+ button_natural_cause_wounded.click(dropdown_natural_cause, inputs=[individual], outputs=[dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
299
+
300
+ dropdown_wounded.select(on_select, inputs=[individual], outputs=[dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded, individual])
301
+ dropdown_level2_wounded.select(on_select_dropdown_level2, inputs=[individual], outputs=[individual])
302
+ openfield_level2_wounded.change(on_change_openfield_level2, inputs=[openfield_level2_wounded, individual])
303
+ dropdown_extra_level2_wounded.select(on_select_dropdown_extra_level2, inputs=[individual], outputs=[individual])
304
+ # ---------------------------------------------------------
305
+ # Radio Behavior Wounded
306
+ radio_behavior_wounded.change(fn=show_behavior,
307
+ inputs=[radio_behavior_wounded, gr.Text("wounded / sick", visible=False), individual],
308
+ outputs=[behavior_checkbox, behavior_text, individual])
309
+ behavior_checkbox.select(on_select_behavior,
310
+ inputs=[behavior_checkbox, individual],
311
+ outputs=[individual])
312
+ # ---------------------------------------------------------
313
+ # Radio Physical Wounded
314
+ radio_physical_wounded.change(fn=show_physical,
315
+ inputs=[radio_physical_wounded, gr.Text("wounded / sick", visible=False), individual],
316
+ outputs=[physical_boxes_wounded, individual])
317
 
318
+ # Checkbox Physical Wounded
319
+ physical_boxes_wounded.select(find_bounding_box,
320
+ inputs=[physical_boxes_wounded, gr.Textbox(value="wounded / sick", visible=False)],
321
+ outputs=[checkbox_beak_wounded, text_beak_wounded,
322
+ checkbox_body_wounded, text_body_wounded,
323
+ checkbox_feathers_wounded, text_feathers_wounded,
324
+ checkbox_head_wounded, text_head_wounded,
325
+ checkbox_legs_wounded, text_legs_wounded
326
+ ])
327
+ checkbox_beak_wounded.select(on_select_body_part, inputs=[checkbox_beak_wounded, gr.Text("beak", visible=False), individual], outputs=[individual])
328
+ checkbox_body_wounded.select(on_select_body_part, inputs=[checkbox_body_wounded, gr.Text("body", visible=False), individual], outputs=[individual])
329
+ checkbox_feathers_wounded.select(on_select_body_part, inputs=[checkbox_feathers_wounded, gr.Text("feathers", visible=False), individual], outputs=[individual])
330
+ checkbox_head_wounded.select(on_select_body_part, inputs=[checkbox_head_wounded, gr.Text("head", visible=False), individual], outputs=[individual])
331
+ checkbox_legs_wounded.select(on_select_body_part, inputs=[checkbox_legs_wounded, gr.Text("legs", visible=False), individual], outputs=[individual])
332
+
333
+ # ---------------------------------------------------------
334
+ # Follow Up Events Wounded
335
+ fe_collection_dropdown_wounded.select(save_fe, inputs=[fe_collection_dropdown_wounded, gr.Textbox("animal collected", visible=False), individual], outputs=[individual])
336
+ fe_recepient_dropdown_wounded.select(save_fe, inputs=[fe_recepient_dropdown_wounded, gr.Textbox("recipient", visible=False), individual],outputs=[individual])
337
+ fe_radio_dropdown_wounded.select(save_fe, inputs=[fe_radio_dropdown_wounded, gr.Textbox("radiography", visible=False), individual],outputs=[individual])
338
+ fe_answer_dropdown_wounded.select(save_fe, inputs=[fe_answer_dropdown_wounded, gr.Textbox("given answer", visible=False), individual],outputs=[individual])
339
+ fe_name_recipient_wounded.input(save_fe, inputs=[fe_name_recipient_wounded, gr.Textbox("recipient name", visible=False), individual],outputs=[individual])
340
+ fe_collection_ref_wounded.input(save_fe, inputs=[fe_collection_ref_wounded, gr.Textbox("collection reference", visible=False), individual],outputs=[individual])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
 
342
+ # ---------------------------------------------------------
343
+ # Follow Up Events Dead
344
+ fe_collection_dropdown_dead.select(save_fe, inputs=[fe_collection_dropdown_dead, gr.Textbox("animal collected", visible=False), individual],outputs=[individual])
345
+ fe_recepient_dropdown_dead.select(save_fe, inputs=[fe_recepient_dropdown_dead, gr.Textbox("recipient", visible=False), individual],outputs=[individual])
346
+ fe_radio_dropdown_dead.select(save_fe, inputs=[fe_radio_dropdown_dead, gr.Textbox("radiography", visible=False), individual],outputs=[individual])
347
+ fe_answer_dropdown_dead.select(save_fe, inputs=[fe_answer_dropdown_dead, gr.Textbox("given answer", visible=False), individual],outputs=[individual])
348
+ fe_name_recipient_dead.input(save_fe, inputs=[fe_name_recipient_dead, gr.Textbox("recipient name", visible=False), individual],outputs=[individual])
349
+ fe_collection_ref_dead.input(save_fe, inputs=[fe_collection_ref_dead, gr.Textbox("collection reference", visible=False), individual], outputs=[individual])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
 
351
+ # ---------------------------------------------------------
352
+ # Error Box
353
+ error_box = gr.Text(value=None, visible=False)
 
 
 
 
 
354
 
355
+ # ---------------------------------------------------------
356
+ # Allow clearing of all previous output
357
+ with gr.Row():
358
+ button_df = gr.Button("SUBMIT OBSERVATION", icon=PATH_ICONS+"effective.png",
359
+ scale = 3)
360
+ button_clear = gr.ClearButton(value="CLEAR",
361
+ scale = 1,
362
+ components=[
363
+ camera,
364
+ location, identified_location,
365
+ #dead reset
366
+ radio_circumstance_dead, radio_physical_dead,
367
+ button_collision_dead, button_deliberate_destruction_dead, button_indirect_destruction_dead, button_natural_cause_dead,
368
+ dropdown_dead, dropdown_level2_dead, openfield_level2_dead, dropdown_extra_level2_dead,
369
+ physical_boxes_dead,
370
+ checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead,
371
+ fe_collection_dropdown_dead, fe_recepient_dropdown_dead, fe_radio_dropdown_dead, fe_answer_dropdown_dead,
372
+ fe_name_recipient_dead, fe_collection_ref_dead,
373
+ #wounded reset
374
+ radio_circumstance_wounded, radio_behavior_wounded, radio_physical_wounded,
375
+ button_collision_wounded, button_deliberate_destruction_wounded, button_indirect_destruction_wounded, button_natural_cause_wounded,
376
+ dropdown_wounded, dropdown_level2_wounded, openfield_level2_wounded, dropdown_extra_level2_wounded,
377
+ behavior_checkbox, behavior_text,
378
+ physical_boxes_wounded,
379
+ checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded,
380
+ fe_collection_dropdown_wounded, fe_recepient_dropdown_wounded, fe_radio_dropdown_wounded, fe_answer_dropdown_wounded,
381
+ fe_name_recipient_wounded, fe_collection_ref_wounded,
382
+ error_box
383
+ ])
384
+ show_creds = gr.Button("CREDITS", icon=PATH_ICONS+"copyright.png", scale=0.5)
385
 
386
+ # ---------------------------------------------------------
387
+ # Button Click Logic
388
+ button_clear.click()
389
+ button_clear.click(hide_physical,
390
+ outputs=[checkbox_beak_wounded, text_beak_wounded, checkbox_body_wounded, text_body_wounded, checkbox_feathers_wounded, text_feathers_wounded, checkbox_head_wounded, text_head_wounded, checkbox_legs_wounded, text_legs_wounded])
391
+ button_clear.click(hide_physical,
392
+ outputs=[checkbox_beak_dead, text_beak_dead, checkbox_body_dead, text_body_dead, checkbox_feathers_dead, text_feathers_dead, checkbox_head_dead, text_head_dead, checkbox_legs_dead, text_legs_dead])
393
+ button_clear.click(reset_error_box, inputs=[error_box], outputs=[error_box])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
 
395
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  # ---------------------------------------------------------
397
+ # VALIDATE ANIMAL
398
+ button_df.click(validate_save_individual, inputs=[individual, error_box],
399
+ outputs=[error_box])
 
 
400
  # ---------------------------------------------------------
401
+ #CREDITS
402
  with Modal(visible=False) as modal_creds:
403
  gr.Markdown(credits_text)
404
  show_creds.click(lambda: Modal(visible=True), None, modal_creds)
 
405
 
406
 
407
 
app/physical/physical_boxes_map.py CHANGED
@@ -17,9 +17,6 @@ def draw_bounding_boxes(image_path, gdf):
17
  # try:
18
  font = ImageFont.truetype(PATH_ASSETS + "fonts/LiberationSans-Regular.ttf",
19
  20)
20
- # except IOError:
21
- # print("default")
22
- # font = ImageFont.load_default()
23
 
24
  # Draw each bounding box on the image
25
  for _, row in gdf.iterrows():
 
17
  # try:
18
  font = ImageFont.truetype(PATH_ASSETS + "fonts/LiberationSans-Regular.ttf",
19
  20)
 
 
 
20
 
21
  # Draw each bounding box on the image
22
  for _, row in gdf.iterrows():
app/physical/physical_checkbox.py CHANGED
@@ -1,7 +1,7 @@
1
  import gradio as gr
2
  from utils.utils_config import get_custom_config_dropdowns
3
  from utils.utils_checkbox import create_checkbox
4
- from validation_submission.add_json import add_data_tmp
5
  #---------------------------------------------------------
6
  def get_body_parts():
7
  dropdown_config = get_custom_config_dropdowns("config_checkbox_physical.json")
@@ -72,9 +72,9 @@ def process_body_parts(section, matched_box):
72
  #---------------------------------------------------------
73
 
74
  def on_select_body_part(body_part_checkbox, body_part, individual):
75
- individual = add_data_tmp("wounded_dead", "physical_type_"+body_part.lower(), body_part.lower(), individual)
76
  body_part_checkbox = [body_part_check.lower() for body_part_check in body_part_checkbox]
77
- individual = add_data_tmp("wounded_dead", "physical_anomaly_"+body_part.lower(), body_part_checkbox, individual)
78
  return individual
79
 
80
  #---------------------------------------------------------
 
1
  import gradio as gr
2
  from utils.utils_config import get_custom_config_dropdowns
3
  from utils.utils_checkbox import create_checkbox
4
+ from validation_submission.utils_individual import add_data_to_individual
5
  #---------------------------------------------------------
6
  def get_body_parts():
7
  dropdown_config = get_custom_config_dropdowns("config_checkbox_physical.json")
 
72
  #---------------------------------------------------------
73
 
74
  def on_select_body_part(body_part_checkbox, body_part, individual):
75
+ individual = add_data_to_individual("wounded_dead", "physical_type_"+body_part.lower(), body_part.lower(), individual)
76
  body_part_checkbox = [body_part_check.lower() for body_part_check in body_part_checkbox]
77
+ individual = add_data_to_individual("wounded_dead", "physical_anomaly_"+body_part.lower(), body_part_checkbox, individual)
78
  return individual
79
 
80
  #---------------------------------------------------------
app/physical/physical_select_animal.py CHANGED
@@ -29,7 +29,6 @@ def find_bounding_box(evt: gr.SelectData, img, section: str):
29
  # Gradio app
30
  def create_bird_anatomy(visible, section: str):
31
  # Draw bounding boxes on the image
32
- print
33
  img_with_boxes = gr.Image(value=PATH_ASSETS+'images/bird_boxed.png',
34
  show_label=False,
35
  height="600px",
 
29
  # Gradio app
30
  def create_bird_anatomy(visible, section: str):
31
  # Draw bounding boxes on the image
 
32
  img_with_boxes = gr.Image(value=PATH_ASSETS+'images/bird_boxed.png',
33
  show_label=False,
34
  height="600px",
app/sync_dataset_hf.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datasets import load_dataset, DownloadMode
2
+ import json
3
+ import os
4
+ from huggingface_hub import HfApi , hf_hub_download
5
+
6
+ dataset_id = "SDSC/digiwild-dataset"
7
+ token = os.getenv("HUGGINGFACE_TOKEN")
8
+
9
+ # Initialize API client
10
+ api = HfApi(token=token)
11
+
12
+ # Load all metadata files
13
+ files = api.list_repo_files(dataset_id, repo_type="dataset")
14
+ json_files = [file for file in files if file.endswith(".json")]
15
+
16
+ # Load the metadata compilation
17
+ try:
18
+ data_files = "data/train-00000-of-00001.parquet"
19
+ metadata = load_dataset(
20
+ dataset_id,
21
+ data_files=data_files)
22
+ # Add new json entries to dataset
23
+ for file in json_files:
24
+ file = hf_hub_download(repo_id=dataset_id, filename=file, repo_type="dataset")
25
+ with open(file, "r") as f:
26
+ new = json.load(f)
27
+ if not(new["image_md5"] in metadata["train"]["image_md5"]):
28
+ metadata["train"] = metadata["train"].add_item(new)
29
+ except:
30
+ metadata = load_dataset(
31
+ dataset_id,
32
+ data_files=json_files)
33
+
34
+
35
+ metadata.push_to_hub(dataset_id, token=token)
app/validation_submission/add_json.py DELETED
@@ -1,19 +0,0 @@
1
- from validation_submission.create_json import create_json_one_individual, create_tmp
2
- import json
3
-
4
- def add_data_to_individual(key, value, individual):
5
- # with open("data/one_individual.json", 'r') as openfile:
6
- # one_individual = json.load(openfile)
7
- # one_individual[key] = value
8
- # create_json_one_individual(one_individual)
9
- individual[key] = value
10
- return individual
11
-
12
- def add_data_tmp(tmp_name, key, value, individual):
13
- # with open(f"app/assets/tmp_json/tmp_{tmp_name}.json", 'r') as openfile:
14
- # tmp = json.load(openfile)
15
- # tmp[key] = value
16
- # create_tmp(tmp_name, tmp)
17
- individual[key] = value
18
- return individual
19
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/validation_submission/create_json.py DELETED
@@ -1,20 +0,0 @@
1
- import json
2
-
3
- def create_json_one_individual(one_individual={}):
4
- one_individual = json.dumps(one_individual)
5
- with open("data/one_individual.json", "w") as outfile:
6
- outfile.write(one_individual)
7
-
8
- def create_json_all_individuals(all_individuals={}):
9
- all_individuals = json.dumps(all_individuals)
10
- with open("data/all_individuals.json", "w") as outfile:
11
- outfile.write(all_individuals)
12
-
13
- def create_tmp(tmp_name="wounded_dead", tmp={}):
14
- tmp = json.dumps(tmp)
15
- with open(f"app/assets/tmp_json/tmp_{tmp_name}.json", "w") as outfile:
16
- outfile.write(tmp)
17
-
18
- def reset_json():
19
- create_json_one_individual()
20
- create_tmp()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/validation_submission/get_json.py DELETED
@@ -1,16 +0,0 @@
1
- import json
2
-
3
- def get_json_one_individual():
4
- with open("data/one_individual.json", 'r') as openfile:
5
- one_individual = json.load(openfile)
6
- return one_individual
7
-
8
- def get_json_all_individuals():
9
- with open("data/all_individuals.json", "r") as openfile:
10
- all_individuals = json.load(openfile)
11
- return all_individuals
12
-
13
- def get_json_tmp(tmp_name):
14
- with open(f"app/assets/tmp_json/tmp_{tmp_name}.json", "r") as openfile:
15
- tmp_json = json.load(openfile)
16
- return tmp_json
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/validation_submission/submission.py CHANGED
@@ -1,17 +1,27 @@
1
  import json
2
- from validation_submission.get_json import get_json_all_individuals
3
  from validation_submission.validation import validate_individual
4
 
 
 
 
5
  def validate_save_individual(data, error_box):
6
  individual, error_box = validate_individual(data, error_box)
7
  if individual:
8
- save_to_all_individuals(individual.model_dump())
9
- return individual, error_box, data
10
-
11
- def save_to_all_individuals(one_individual):
12
- all_individuals = get_json_all_individuals()
13
- all_individuals[str(len(all_individuals))] = one_individual
14
- all_individuals_for_json = json.dumps(all_individuals)
15
- with open("data/all_individuals.json", "w") as outfile:
16
- outfile.write(all_individuals_for_json)
17
- return all_individuals
 
 
 
 
 
 
 
 
 
1
  import json
 
2
  from validation_submission.validation import validate_individual
3
 
4
+ from huggingface_hub import HfApi
5
+ import os
6
+
7
  def validate_save_individual(data, error_box):
8
  individual, error_box = validate_individual(data, error_box)
9
  if individual:
10
+ push_to_dataset_hf(individual.model_dump())
11
+ return error_box
12
+
13
+ def push_to_dataset_hf(individual):
14
+ token = os.environ.get("HF_TOKEN", None)
15
+ api = HfApi(token=token)
16
+ import tempfile
17
+ f = tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False)
18
+ json.dump(individual, f)
19
+ f.flush()
20
+ f.close()
21
+ path_in_repo= f"data/{individual['image_md5']}.json"
22
+ api.upload_file(
23
+ path_or_fileobj=f.name,
24
+ path_in_repo=path_in_repo,
25
+ repo_id="SDSC/digiwild-dataset",
26
+ repo_type="dataset",
27
+ )
app/validation_submission/utils_individual.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import string
3
+ import hashlib
4
+
5
+ def generate_random_md5():
6
+ # Generate a random string
7
+ random_string = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
8
+ # Encode the string and compute its MD5 hash
9
+ md5_hash = hashlib.md5(random_string.encode()).hexdigest()
10
+ return md5_hash
11
+
12
+ def add_data_to_individual(key, value, individual):
13
+ individual[key] = value
14
+ return individual
15
+
app/validation_submission/validation.py CHANGED
@@ -2,7 +2,7 @@ import uuid
2
  from pydantic import ValidationError
3
  import gradio as gr
4
 
5
- from validation_submission.get_json import get_json_tmp, get_json_one_individual
6
  from circumstances.class_circumstance import Circumstances
7
  from behavior.class_behavior import Behaviors
8
  from physical.class_physical import PhysicalAnomalies
@@ -50,6 +50,7 @@ def validate_individual(data, error_box):
50
  try :
51
  individual = Report(identifier = data["identifier"],
52
  image = img,
 
53
  geolocalisation = geolocalisation,
54
  wounded_state = data["wounded_state"],
55
  wounded = Wounded(circumstances = circumstance,
@@ -65,6 +66,7 @@ def validate_individual(data, error_box):
65
  try:
66
  individual = Report(identifier = data["identifier"],
67
  image = img,
 
68
  geolocalisation = geolocalisation,
69
  wounded_state = data["wounded_state"],
70
  dead_state = data["dead_state"],
@@ -79,6 +81,7 @@ def validate_individual(data, error_box):
79
  try:
80
  individual = Report(identifier = data["identifier"],
81
  image = img,
 
82
  geolocalisation = geolocalisation,
83
  wounded_state = data["wounded_state"],
84
  dead_state = data["dead_state"])
 
2
  from pydantic import ValidationError
3
  import gradio as gr
4
 
5
+ # from validation_submission.get_json import get_json_tmp, get_json_one_individual
6
  from circumstances.class_circumstance import Circumstances
7
  from behavior.class_behavior import Behaviors
8
  from physical.class_physical import PhysicalAnomalies
 
50
  try :
51
  individual = Report(identifier = data["identifier"],
52
  image = img,
53
+ image_md5 = data["image_md5"],
54
  geolocalisation = geolocalisation,
55
  wounded_state = data["wounded_state"],
56
  wounded = Wounded(circumstances = circumstance,
 
66
  try:
67
  individual = Report(identifier = data["identifier"],
68
  image = img,
69
+ image_md5 = data["image_md5"],
70
  geolocalisation = geolocalisation,
71
  wounded_state = data["wounded_state"],
72
  dead_state = data["dead_state"],
 
81
  try:
82
  individual = Report(identifier = data["identifier"],
83
  image = img,
84
+ image_md5 = data["image_md5"],
85
  geolocalisation = geolocalisation,
86
  wounded_state = data["wounded_state"],
87
  dead_state = data["dead_state"])
app/wounded.py CHANGED
@@ -4,7 +4,7 @@ from physical.physical_select_animal import create_bird_anatomy
4
  from physical.physical_checkbox import process_body_parts
5
  from behavior.behavior_checkbox import create_behavior_checkbox
6
  from follow_up.followup_events import create_followup_dropdowns, create_followup_open
7
- from validation_submission.add_json import add_data_to_individual
8
 
9
  from dotenv import load_dotenv
10
  import os
@@ -19,7 +19,7 @@ def show_section_wounded(visible, individual):
19
  individual = add_data_to_individual("dead_state", "No", individual)
20
 
21
  with gr.Column(visible=visible, elem_id="wounded") as wounded_section:
22
- gr.Markdown("# Wounded / Sick Animal")
23
 
24
  gr.Button("Do you know what conditions caused this?",
25
  icon=PATH_ICONS + "eye.png",
@@ -27,14 +27,14 @@ def show_section_wounded(visible, individual):
27
  radio_cause = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
28
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible=False)
29
 
30
- gr.Button("Is the bird displaying behavioural changes?",
31
  icon=PATH_ICONS + "neuron.png",
32
  variant= "primary")
33
  radio_behaviour = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
34
  with gr.Row():
35
  behavior_checkbox, behavior_text = create_behavior_checkbox("wounded", False)
36
 
37
- gr.Button("Are there physical changes on the bird?",
38
  icon=PATH_ICONS + "cardiogram.png",
39
  variant= "primary")
40
  radio_physical = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
 
4
  from physical.physical_checkbox import process_body_parts
5
  from behavior.behavior_checkbox import create_behavior_checkbox
6
  from follow_up.followup_events import create_followup_dropdowns, create_followup_open
7
+ from validation_submission.utils_individual import add_data_to_individual
8
 
9
  from dotenv import load_dotenv
10
  import os
 
19
  individual = add_data_to_individual("dead_state", "No", individual)
20
 
21
  with gr.Column(visible=visible, elem_id="wounded") as wounded_section:
22
+ gr.Markdown("## The animal is wounded / sick.")
23
 
24
  gr.Button("Do you know what conditions caused this?",
25
  icon=PATH_ICONS + "eye.png",
 
27
  radio_cause = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
28
  button_collision, button_deliberate_destruction, button_indirect_destruction, button_natural_cause, dropdown, dropdown_level2, openfield_level2, dropdown_extra_level2 = create_circumstances(visible=False)
29
 
30
+ gr.Button("Is the animal displaying behavioural changes?",
31
  icon=PATH_ICONS + "neuron.png",
32
  variant= "primary")
33
  radio_behaviour = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
34
  with gr.Row():
35
  behavior_checkbox, behavior_text = create_behavior_checkbox("wounded", False)
36
 
37
+ gr.Button("Are there physical changes on the animal?",
38
  icon=PATH_ICONS + "cardiogram.png",
39
  variant= "primary")
40
  radio_physical = gr.Radio(["Yes", "No"], value=None, show_label=False, interactive=True)
requirements.txt CHANGED
@@ -3,4 +3,7 @@ gradio_modal
3
  geopy
4
  geopandas
5
  pillow
6
- python-dotenv
 
 
 
 
3
  geopy
4
  geopandas
5
  pillow
6
+ python-dotenv
7
+ datasets
8
+ huggingface_hub
9
+ hashlib