Source code for dpest.wheat.utils.uplantgro

from dpest.functions import *

[docs] def uplantgro( plantgro_file_path=None, treatment=None, variables=None, nspaces_year_header=None, nspaces_doy_header = None, nspaces_columns_header = None, ): """ Updates the PlantGro.OUT file with new rows if necessary. Parameters: plantgro_file_path (str): Path to the PlantGro.OUT file treatment (str): Treatment identifier variables (list): List of variables to consider nspaces_year_header (int): Number of spaces for year header (default 5) nspaces_doy_header (int): Number of spaces for day of year header (default 4) nspaces_columns_header (int): Number of spaces for other columns (default 6) Returns: None """ rows_added = 0 # Initialize try: # Validate plantgro_file_path validated_path = validate_file(plantgro_file_path, '.OUT') # Validate treatment if not treatment or not isinstance(treatment, str): raise ValueError("The 'treatment' must be a non-empty string.") # Convert 'variables' to a list if it's not already a list if not isinstance(variables, list): variables = [variables] # Validate that 'variables' is a non-empty list of strings if not variables or not all(isinstance(var, str) for var in variables): raise ValueError( "The 'variables' should be a non-empty string or a list of strings. For example: 'LAID' or ['LAID', 'CWAD']") # Assign default values if None and validate integer input if nspaces_year_header is None: nspaces_year_header = 5 elif not isinstance(nspaces_year_header, int): raise ValueError("nspaces_year_header must be an integer.") if nspaces_doy_header is None: nspaces_doy_header = 4 elif not isinstance(nspaces_doy_header, int): raise ValueError("nspaces_doy_header must be an integer.") if nspaces_columns_header is None: nspaces_columns_header = 6 elif not isinstance(nspaces_columns_header, int): raise ValueError("nspaces_columns_header must be an integer.") # Get treatment range treatment_range = simulations_lines(plantgro_file_path)[treatment] # Read growth file plantgro_file_df = read_growth_file(plantgro_file_path, treatment_range) # Get treatment number treatment_dict = simulations_lines(plantgro_file_path) treatment_number_name, treatment_experiment_name = extract_treatment_info_plantgrowth(plantgro_file_path, treatment_dict) # Make the path for the WHT file wht_file_path = os.path.join(os.path.dirname(plantgro_file_path), treatment_experiment_name.get(treatment) + '.WHT') # Get the dataframe from the WHT file data wht_df = wht_filedata_to_dataframe(wht_file_path) # Load and filter data for all variables and get the measured year dates_variable_values_dict = filter_dataframe(wht_df, treatment, treatment_number_name, variables) #year_measured_key = int(list(dates_variable_values_dict.keys())[-1]) # Get the year and day of the year and join it as one unique number year_sim = int(str(plantgro_file_df['@YEAR'].iloc[-1]) + f"{plantgro_file_df['DOY'].iloc[-1]:03}") # Handle both 4-digit and 2-digit years for year_measured year_measured_key_str = str(list(dates_variable_values_dict.keys())[-1]) if len(year_measured_key_str) == 5: # If year_measured has a 2-digit year year_measured_year = int(year_measured_key_str[:2]) doy_measured = int(year_measured_key_str[2:]) # Determine the correct century for the 2-digit year century = year_sim // 100000 # Get the century from year_sim year_measured = int(f"{century}{year_measured_year:02d}{doy_measured:03d}") else: # If year_measured has a 4-digit year year_measured = int(year_measured_key_str) # Create the new rows to insert if year_sim < year_measured: number_rows_add = year_measured - year_sim # Get the new rows using the new_rows() function new_rows = new_rows_add(plantgro_file_df, number_rows_add) # Read the existing file and store its contents with open(plantgro_file_path, 'r') as file: lines = file.readlines() # Identify the line where the headers are defined (e.g., '@YEAR') header_line = next(line for line in lines if '@YEAR' in line) # Extract column headers to maintain correct order headers = header_line.strip().split() # Convert each dictionary into a formatted row string new_rows_dic = [] for row_data in new_rows: row = ( str(row_data.get('@YEAR', 0)).rjust(nspaces_year_header) + str(row_data.get('DOY', 0)).rjust(nspaces_doy_header) + ''.join(str(row_data.get(col, 0)).rjust(nspaces_columns_header) for col in headers if col not in ['@YEAR', 'DOY']) + '\n' ) new_rows_dic.append(row) # Add new rows to the lines list lines[treatment_range[1]:treatment_range[1]] = new_rows_dic # Update the rows_added counter rows_added = len(new_rows) # Write the updated content back to the file with open(plantgro_file_path, 'w') as file: file.writelines(lines) # Add messages about rows added (now inside the try block) if rows_added > 0: print(f"PlantGro.OUT update: {rows_added} row{'s' if rows_added > 1 else ''} added successfully.") else: print("PlantGro.OUT status: No update required.") except ValueError as ve: print(f"ValueError: {ve}") except FileNotFoundError as fe: print(f"FileNotFoundError: {fe}") except Exception as e: print(f"An unexpected error occurred: {e}")