88from glob import glob
99from numpy .typing import NDArray
1010from datetime import datetime , timedelta , date
11+ import psutil
1112
1213from WITOIL_iMagine .src .utils .utils import Utils
1314from WITOIL_iMagine .src .utils .config import Config
1617
1718logger = logging .getLogger (__name__ )
1819
20+ def print_memory_debug (tag , obj = None ):
21+ process = psutil .Process ()
22+ mem_used = process .memory_info ().rss / 1024 ** 2 # MB
23+ if obj is not None :
24+ try :
25+ size = obj .nbytes / 1024 ** 2 # MB
26+ except AttributeError :
27+ size = sys .getsizeof (obj ) / 1024 ** 2
28+ print (f"DEBUG [{ tag } ] - Used RAM: { mem_used :.2f} MB, Object size: { size :.2f} MB" )
29+ else :
30+ print (f"DEBUG [{ tag } ] - Used RAM: { mem_used :.2f} MB" )
31+
1932class PreProcessing :
2033 """
2134 This class embeds functions for pre-processing, with a user-interface purpose.
@@ -61,13 +74,15 @@ def process_currents(self, oce_path: str = None):
6174 if glob (oce_path ) == []:
6275 oce_path = f"{ self .exp_folder } /oce_files/*.nc"
6376 concat = xr .open_mfdataset (oce_path , combine = "nested" , engine = "netcdf4" )
77+ print_memory_debug ("process_currents - concat" , concat )
6478 concat = concat .drop_duplicates (dim = "time" , keep = "last" )
6579 if self .config ["input_files" ]["set_domain" ]:
6680 concat = concat .sel (
6781 lon = slice (lon_min , lon_max ), lat = slice (lat_min , lat_max )
6882 )
6983 # Interpolating the values in time, transforming it from daily to hourly values
7084 concat = concat .resample (time = "1h" ).interpolate ("linear" )
85+ print_memory_debug ("process_currents - after resample" , concat )
7186 Utils .write_mrc (concat , exp_folder = self .exp_folder )
7287 self ._copy_nc_files (oce_path , f"{ self .exp_folder } /oce_files/" )
7388 print ("DEBUG: process_currents() completed" )
@@ -82,9 +97,11 @@ def process_winds(self, met_path: str = None):
8297 if glob (met_path ) == []:
8398 met_path = f"{ self .exp_folder } /met_files/*.nc"
8499 concat = xr .open_mfdataset (met_path , combine = "nested" , engine = "netcdf4" )
100+ print_memory_debug ("process_winds - concat" , concat )
85101 concat = concat .drop_duplicates (dim = "time" , keep = "first" )
86102 # Interpolating the values in time, transforming it from daily to hourly values
87103 concat = concat .resample (time = "1h" ).interpolate ("linear" )
104+ print_memory_debug ("process_winds - after resample" , concat )
88105 # Handle longitude and latitude
89106 concat ["lon" ] = xr .where (
90107 concat ["lon" ] > 180 , concat ["lon" ] - 360 , concat ["lon" ]
@@ -125,6 +142,10 @@ def process_bathymetry(self,gebco):
125142
126143 # interpolation on medslik grid
127144 med = gebco .interp (lon = grid .lon .values .tolist (),lat = grid .lat .values .tolist ())
145+ print_memory_debug ("process_bathymetry - interpolated gebco" , med )
146+ print ("DEBUG: bathymetry memory usage (MB):" , med .nbytes / 1e6 )
147+ print ("DEBUG: GEBCO dimensions:" , gebco .sizes )
148+ print ("DEBUG: interpolated med dimensions:" , med .sizes )
128149 #converting from begative depths to positive
129150 med ['elevation' ] = med .elevation * - 1
130151 #filling nan to -9999 as expected by medslik
@@ -143,6 +164,8 @@ def process_bathymetry(self,gebco):
143164 mdk_z = np .array (mdk_z )
144165 land_mask = np .where (mdk_z <= 0 )
145166 mdk_z [land_mask ]= 9999
167+ print_memory_debug ("process_bathymetry - mdk_z array" , mdk_z )
168+
146169
147170 BathFile = open (f'{ self .exp_folder } /bnc_files/dtm.bath' , "w" )
148171 BathFile .write ("MEDSLIK-II compatible bathymetry file. Degraded resolution based on GEBCO 30''\n " )
@@ -172,6 +195,7 @@ def process_coastline(self,gshhs):
172195 ymax = grid .lat .max () + buffer
173196
174197 shp = gpd .read_file (gshhs )
198+ print_memory_debug ("process_coastline - gshhs read" , shp )
175199
176200 # Cropping to a smaller area
177201 shp = shp .cx [xmin :xmax , ymin :ymax ]
@@ -264,7 +288,9 @@ def write_config_files(self,
264288 separate_slicks = False ,
265289 s_num = None ,
266290 ):
267-
291+ print ("DEBUG: write_config_files() called" )
292+ print_memory_debug ("before write_config_files" )
293+ print (f" simname={ spill_dictionary ['simname' ]} , separate_slicks={ separate_slicks } , s_num={ s_num } " )
268294 # obtaining the variables
269295 simname = spill_dictionary ["simname" ]
270296 dt_sim = spill_dictionary ["dt_sim" ]
@@ -287,25 +313,30 @@ def write_config_files(self,
287313 else :
288314 config_file = f"WITOIL_iMagine/cases/{ simname } /xp_files/slick{ s_num + 1 } /config1.txt"
289315 # Refactored: Copy the template file
316+ print (f"DEBUG: Copying config1 template to { config_file } " )
290317 source_file = "WITOIL_iMagine/src/templates/config1_template_0.txt"
291318 shutil .copy (source_file , config_file )
292319 # adding spill Name - Add slick number if separate slicks
293320 if separate_slicks == False :
321+ print ("DEBUG: Replacing run name" )
294322 Utils .search_and_replace (config_file , "RUNNAME" , simname )
295323 else :
296324 Utils .search_and_replace (config_file , "RUNNAME" , simname + f"_slick{ s_num + 1 } " )
297325 # adding spill date and hour information
326+ print ("DEBUG: Replacing datetime info" )
298327 Utils .search_and_replace (config_file , "DD" , f"{ dt_sim .day :02d} " )
299328 Utils .search_and_replace (config_file , "MM" , f"{ dt_sim .month :02d} " )
300329 Utils .search_and_replace (config_file , "YY" , f"{ dt_sim .year - 2000 :02d} " )
301330 Utils .search_and_replace (config_file , "c_Hour" , f"{ dt_sim .hour :02d} " )
302331 Utils .search_and_replace (config_file , "c_minute" , f"{ dt_sim .minute :02d} " )
303332 # adding simulation length
333+ print ("DEBUG: Replacing simulation length" )
304334 Utils .search_and_replace (config_file , "SIMLENGTH" , f"{ sim_length :04d} " )
305335 # adding spill coordinates - dd for degrees and mm for minutes
306336 # Latitude
307337 dd = int (latitude )
308338 mm = (float (latitude ) - dd ) * 60
339+ print ("DEBUG: Replacing coordinates" )
309340 Utils .search_and_replace (config_file , "LATd" , f"{ dd :02d} " )
310341 Utils .search_and_replace (config_file , "LATm" , f"{ mm :.3f} " )
311342 # Longitude
@@ -314,10 +345,13 @@ def write_config_files(self,
314345 Utils .search_and_replace (config_file , "LONd" , f"{ dd :02d} " )
315346 Utils .search_and_replace (config_file , "LONm" , f"{ mm :.3f} " )
316347 # spill duration
348+ print ("DEBUG: Replacing spill duration and rate" )
317349 Utils .search_and_replace (config_file , "SDUR" , f"{ spill_duration :04d} " )
318350 # spill volume
319351 Utils .search_and_replace (config_file , "SRATE" , f"{ spill_rate :08.2f} " )
320352 # oil characteristics
353+ print ("DEBUG: Replacing oil type" )
354+ print (f" OIL={ self .config ['input_files' ]['oil' ]['type' ]} , OIL_TYPE={ self .config ['input_files' ]['oil' ]['value' ]} " )
321355 Utils .search_and_replace (config_file , "APIOT" , f"{ oil_api } " )
322356 # number of slicks
323357 Utils .search_and_replace (config_file , "N_SLICK" , f"{ number_slick } " )
@@ -342,7 +376,7 @@ def write_config_files(self,
342376 slik = "NO"
343377 # Writing that will use slick countor
344378 Utils .search_and_replace (config_file , "SSLICK" , f"{ slik } " )
345- print ("DEBUG: config1.txt written " )
379+ print ("DEBUG: write_config_files() finished " )
346380
347381if __name__ == "__main__" :
348382
0 commit comments