Skip to content

Commit

Permalink
#262 add extract shoreline report to zoo workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
2320sharon committed Jun 18, 2024
1 parent bc1fc6f commit c9b686a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/coastseg/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3373,10 +3373,10 @@ def create_roi_settings(
dates = settings["dates"]
for roi in selected_rois["features"]:
roi_id = str(roi["properties"]["id"])
polygon = roi["geometry"]["coordinates"]
sitename = (
"" if date_str == "" else "ID_" + str(roi_id) + "_datetime" + date_str
)
polygon = roi["geometry"]["coordinates"]
inputs_dict = {
"dates": dates,
"sat_list": sat_list,
Expand Down
23 changes: 15 additions & 8 deletions src/coastseg/extracted_shoreline.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,8 @@ def process_satellite_image(
Returns:
dict: A dictionary containing the extracted shoreline and cloud cover percentage.
"""
logger = logging.getLogger('extract_shorelines_logger')

# get image date
date = filename[:19]
# get the filenames for each of the tif files (ms, pan, qa)
Expand Down Expand Up @@ -592,15 +594,17 @@ def process_satellite_image(
# compute cloud_cover percentage (with no data pixels)
cloud_cover_combined = get_cloud_cover_combined(cloud_mask)
if cloud_cover_combined > 0.99: # if 99% of cloudy pixels in image skip
logger.info(f"cloud_cover_combined > 0.99 : {filename} ")
logger.info(f"cloud cover and no data covererage exceeds 99% skipping : {filename} ")
return None

# compute cloud cover percentage (without no data pixels)
cloud_cover = get_cloud_cover(cloud_mask, im_nodata)
logger.info(f"{satname} {date} cloud cover : {cloud_cover:.2%}")
# skip image if cloud cover is above user-defined threshold
if cloud_cover > settings["cloud_thresh"]:
logger.info(f"Cloud thresh exceeded for {filename}")
logger.info(f"Cloud thresh exceeded {cloud_cover} > {settings['cloud_thresh']} skipping {filename}")
return None
logger.info(f"The cloud cover was : {cloud_cover}")
# calculate a buffer around the reference shoreline (if any has been digitised)
# buffer is dilated by 5 pixels
ref_shoreline_buffer = SDS_shoreline.create_shoreline_buffer(
Expand All @@ -612,7 +616,7 @@ def process_satellite_image(
npz_file = find_matching_npz(filename, session_path)
# logger.info(f"npz_file: {npz_file}")
if npz_file is None:
logger.warning(f"npz file not found for {filename}")
logger.warning(f"Npz file not found. Skipping {filename}")
return None

# get the labels for water and land
Expand Down Expand Up @@ -1310,7 +1314,7 @@ def find_shoreline(
except Exception as e:
logger.error(f"{e}\nCould not map shoreline for this image: {filename}")
return None
# print(f"Settings used by process_shoreline: {settings}")
# process the water contours into a shoreline
shoreline = SDS_shoreline.process_shoreline(
contours, cloud_mask_adv, im_nodata, georef, image_epsg, settings
Expand Down Expand Up @@ -1345,6 +1349,7 @@ def extract_shorelines_with_dask(
Returns:
dict: A dictionary containing the extracted shorelines for each satellite.
"""
logger = logging.getLogger('extract_shorelines_logger')
sitename = settings["inputs"]["sitename"]
filepath_data = settings["inputs"]["filepath"]

Expand All @@ -1358,6 +1363,7 @@ def extract_shorelines_with_dask(

# get the list of files that were sorted as 'good'
filtered_files = get_filtered_files_dict(good_folder, "npz", sitename)

# keep only the metadata for the files that were sorted as 'good'
metadata = edit_metadata(metadata, filtered_files)

Expand Down Expand Up @@ -1874,9 +1880,11 @@ def create_extracted_shorelines_from_session(
Returns:
- object: The Extracted_Shoreline class instance.
"""

# validate input parameters are not empty and are of the correct type
self._validate_input_params(roi_id, shoreline, roi_settings, settings)

logger = logging.getLogger('extract_shorelines_logger')
logger.info(f"Extracting shorelines for ROI id: {roi_id}")

# read model settings from session path
Expand All @@ -1893,7 +1901,7 @@ def create_extracted_shorelines_from_session(
# read model card from downloaded models path
downloaded_models_dir = common.get_downloaded_models_dir()
downloaded_models_path = os.path.join(downloaded_models_dir, model_type)
logger.info(
logger.info(
f"Searching for model card in downloaded_models_path: {downloaded_models_path}"
)
model_card_path = file_utilities.find_file_by_regex(
Expand Down Expand Up @@ -1925,10 +1933,8 @@ def create_extracted_shorelines_from_session(
)
# Check and log 'reference_shoreline' if it exists
ref_sl = self.shoreline_settings.get("reference_shoreline", np.array([]))
if isinstance(ref_sl, np.ndarray):
logger.info(f"reference_shoreline.shape: {ref_sl.shape}")
logger.info(
f"Number of 'reference_shoreline': {len(ref_sl)} for ROI {roi_id}"
f"Length of 'reference_shoreline': {len(ref_sl)} for ROI {roi_id}"
)
# gets metadata used to extract shorelines
metadata = get_metadata(self.shoreline_settings["inputs"])
Expand Down Expand Up @@ -1983,6 +1989,7 @@ def create_extracted_shorelines_from_session(
extracted_shorelines_dict = remove_duplicates(
extracted_shorelines_dict
) # removes duplicates (images taken on the same date by the same satellite

extracted_shorelines_dict = remove_inaccurate_georef(
extracted_shorelines_dict, 10
) # remove inaccurate georeferencing (set threshold to 10 m)
Expand Down
57 changes: 50 additions & 7 deletions src/coastseg/zoo_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,36 @@

logger = logging.getLogger(__name__)

def setup_logger(
folder,
base_filename="download_report",
log_format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
):
# Determine the next available log file number
i = 1
while True:
log_filename = f"{base_filename}{i}.txt" if i > 1 else f"{base_filename}.txt"
log_filepath = os.path.join(folder, log_filename)
if not os.path.exists(log_filepath):
break
i += 1

# Create a custom logger
logger = logging.getLogger("extract_shorelines_logger")
logger.setLevel(logging.INFO) # Log all levels of messages

# Create handlers
file_handler = logging.FileHandler(log_filepath)
file_handler.setLevel(logging.INFO)

# Create formatters and add it to handlers
log_format = logging.Formatter(log_format)
file_handler.setFormatter(log_format)

# Add handlers to the logger
logger.addHandler(file_handler)

return logger

def filter_no_data_pixels(files: list[str], percent_no_data: float = 0.50) -> list[str]:
def percentage_of_black_pixels(img: "PIL.Image") -> float:
Expand Down Expand Up @@ -77,12 +107,12 @@ def has_image_files(file_list, extensions):
if file.endswith(".jpg") or file.endswith(".jpeg") or file.endswith(".png"):
img = Image.open(file)
percentage = percentage_of_black_pixels(img)

if percentage <= percent_no_data:
valid_images.append(file)

return valid_images


def get_files_to_download(
available_files: List[dict], filenames: List[str], model_id: str, model_path: str
) -> dict:
Expand Down Expand Up @@ -788,9 +818,11 @@ def extract_shorelines_with_unet(
shoreline_extraction_area_path (str, optional): The path to the shoreline extraction area. Defaults to "".
Returns:
None
"""
logger.info(f"extract_shoreline_settings: {settings}")

"""
# logger.info("extract_shoreline_settings: %s", settings)



# save the selected model session
settings["model_session_path"] = session_path
self.set_settings(**settings)
Expand All @@ -802,7 +834,18 @@ def extract_shorelines_with_unet(


new_session_path.mkdir(parents=True, exist_ok=True)

logger = setup_logger(
new_session_path,
"extract_shorelines_report",
log_format="%(levelname)s - %(message)s",
)
# by default assume no ROI
roi_id = None
logger.info(f"Extract Shorelines Settings: {settings}")

# roi_settings = get_roi_settings_from_config(session_path)

# load the ROI settings from the config file
try:
config = file_utilities.load_json_data_from_file(
Expand All @@ -824,13 +867,13 @@ def extract_shorelines_with_unet(
raise Exception(
f"The roi ID {roi_id} did not exist is the config.json \n config.json: {config}"
)
logger.info(f"roi_settings: {roi_settings}")

logger.info(f"Settings of the ROI having shorelines extracted: {roi_settings}")
# read ROI from config geojson file
config_geojson_location = file_utilities.find_file_recursively(
session_path, "config_gdf.geojson"
)
logger.info(f"config_geojson_location: {config_geojson_location}")
logger.info(f"Location of config_gdf.geojson: {config_geojson_location}")
config_gdf = geodata_processing.read_gpd_file(config_geojson_location)
roi_gdf = config_gdf[config_gdf["id"] == roi_id]
if roi_gdf.empty:
Expand Down

0 comments on commit c9b686a

Please sign in to comment.