def add_zones(location, NPP, max_time_experiment): '''Function used to add zones of several ensembles together. Loaded variables : NPP01_Z1 or NPP11_dead for example, depends on provided arg NPP Saves made : Sum_Zones (dict) : contains sums of Z1, Z2, Z3, Z4, Z5, dead Args : location (str): path to the file with the saved opt such as path = '/data/ebent/Octopus/output/' + location + '/' NPP (str): number from 01 to 12 for the ensemble of particles being studied max_time_experiment (int) : used to crop each zone from the end to have same sizes ''' from func_pickle import pickle_load, pickle_save Ensembles = {} Z = ['Z1', 'Z2', 'Z3', 'Z4', 'Z5', 'dead'] npp = NPP path = '/data/ebent/Octopus/output/' + location + '/' max_time_experiment = max_time_experiment # Start by loading each zone and saving it in a dictionary (Zones) of a dictionary (Ensembles) for NPP in npp: Zones = {} for zone in Z: Zones[zone] = pickle_load('NPP' + NPP + '_' + zone, path, verbose=False)[max_time_experiment:] Zones['dead'] = Zones['dead'] - Zones['dead'][0] Ensembles[NPP] = Zones pickle_save('Ensembles', path, Ensembles) # Then sum up each different zone together with the other ones of each ensemble and save it in a dictionary (Sum_Zones) Sum_Zones = {} for NPP in npp: for zone in Z: if NPP == '01': Sum_Zones[zone] = Ensembles[NPP][zone].copy() else: Sum_Zones[zone] += Ensembles[NPP][zone] pickle_save('Sum_Zones', path, Sum_Zones)
def func_mask(casename, NPP, location, lon_W, lon_E, lat_S, lat_N): '''Function mask Octopus output. Masks the particles that go on land and particles with wrong initial position (because if particles were initialized on bathymetry, they are randomly shuffled somewere else. This function calls the function post_processing(casename, NPP, location) which is an automated version of p_xy.py Args : casename (str): casename used to save Octopus opt NPP (str): number from 01 to 12 for the ensemble of particles being masked location (str): path to the file with the saved opt such as path = '/data/ebent/Octopus/output/' + location + '/' lon_W (float): longitude west of box of initialisation for the particles as described in init_parti_xyz.py lon_E (float): longitude east of box of initialisation for the particles as described in init_parti_xyz.py lat_S (float): latitude south of box of initialisation for the particles as described in init_parti_xyz.py lat_N (float): latitude north of box of initialisation for the particles as described in init_parti_xyz.py Saves made : LON, LAT, DEP, xround, yround, zround ''' from func_pickle import pickle_load, pickle_save from func_p_xy import post_processing import numpy as np import h5py import netCDF4 load_path2='/data/SO12/runs/RUN_BLING_Dec2017/SO12_RUN/DIAGNOSTICS/' load_path3='/data/soccom/GRID_12/' # Load files file1 = netCDF4.Dataset(load_path2+'so12_i0_year2006_5day_Salt.nc','r') # This is hFacC for the SOUTHERN HEMISPHERE file_h = h5py.File(load_path3 + 'grid.mat','r') hFacC = file_h.get('hFacC') hFacC = np.array(hFacC) Xf = file_h.get('XC') Xf = np.array(Xf) Yf = file_h.get('YC') Yf = np.array(Yf) # On selectionne la bonne taille de hFacC == taille de "bigger domain" lon_min = 1440 lon_max = 3241 lat_min = 0 lat_max = 1024 YC = file1.variables['lat'][lat_min:lat_max] # de -77,99 a -40,05 XC = file1.variables['lon'][lon_min:lon_max] # de 120,04 a 270,04 XC, YC = np.meshgrid(XC, YC) hfacc = hFacC[:, lat_min:lat_max, lon_min:lon_max] ################### Extract the output of Octopus ########################### # Call function post_processing that I wrote lon, lat, dep, xround, yround, zround = post_processing(casename=casename, NPP=NPP, location=location) LON = np.ma.masked_array(lon, mask=False) LAT = np.ma.masked_array(lat, mask=False) DEP = np.ma.masked_array(dep, mask=False) # Put a mask on hfacc==0 for p in range(LON.shape[1]): for t in range(LON.shape[0]): if LON.mask[t,p]==True: continue if hfacc[zround[t,p], yround[t,p], xround[t,p]]==0.: #print t,p LON.mask[t:,p]=True # Put a mask on all time steps after the first LON.mask[t,p]==True for each parti for p in range(LON.shape[1]): for t in range(LON.shape[0]): if LON.mask[t,p]==True: LON.mask[t:,p]=True break # Mask particles that have an initial pos out of the box I chose (this happens because of the pb of bathymetry in initial pos) parti = [] for p in range(LON.shape[1]): if LON[0,p]<lon_W or LON[0,p]>lon_E or LAT[0,p]<lat_S or LAT[0,p]>lat_N: LON.mask[:,p]=True parti.append(p) print '' print 'Number of particles that are out of the initial box on first time step :', len(parti) print '' # Make sure all pos have the same mask LAT.mask = LON.mask DEP.mask = LON.mask xround.mask = LON.mask yround.mask = LON.mask zround.mask = LON.mask # Save the variables path = '/data/ebent/Octopus/output/' + location + '/' pickle_save('NPP' + NPP + '_DEP', path, DEP) pickle_save('NPP' + NPP + '_LAT', path, LAT) pickle_save('NPP' + NPP + '_LON', path, LON) pickle_save('NPP' + NPP + '_zround', path, zround) pickle_save('NPP' + NPP + '_yround', path, yround) pickle_save('NPP' + NPP + '_xround', path, xround)
def count_zones(location, NPP, npts): '''Function to count how many particles of the Octopus output are in each 5 zones of the domain of study. Function first counts how many particles are "alive" for at least one time step then counts for each zone at each time step how many particles are in. Also counts the particles that "die" which is equivalent of one a particle gets masked. Args : location (str): path to the file with the saved opt such as path = '/data/ebent/Octopus/output/' + location + '/' NPP (str): number from 01 to 12 for the ensemble of particles being studied npts (int): total number of particles in this ensemble Loaded variables : LON, LAT, DEP, xround, yround, zround, southern_front Saves made : Z1, Z2, Z3, Z4, Z5, dead ''' import numpy as np from func_pickle import pickle_load, pickle_save southern_front = pickle_load('ACC_southern_front', '/data/ebent/', verbose=False) southern_front = np.ma.masked_array(southern_front, mask=False) path = '/data/ebent/Octopus/output/' + location + '/' DEP = pickle_load('NPP' + NPP + '_DEP', path, verbose=False) LAT = pickle_load('NPP' + NPP + '_LAT', path, verbose=False) LON = pickle_load('NPP' + NPP + '_LON', path, verbose=False) zround = pickle_load('NPP' + NPP + '_zround', path, verbose=False) yround = pickle_load('NPP' + NPP + '_yround', path, verbose=False) xround = pickle_load('NPP' + NPP + '_xround', path, verbose=False) W_boundary = 12 # 121,04 degrees E_boundary = 1560 # 250,04 degrees # Count the particles that are "alive" during part of the time serie are_alive = [] for p in range(npts): south_front = southern_front[ yround[:, p], xround[:, p]] # select southern_front of one particle traj south_front.mask = xround[:, p].mask parti_are_dead = np.squeeze( np.array(np.ma.where(xround.mask[:, p] == False))) if parti_are_dead.size > 0.: are_alive.append(p) print '' print 'Number of particles "alive" :', len(are_alive) # Particle analysis : count the particles in each zone according to time Z1 = np.zeros(xround.shape[0]) Z2 = np.zeros(xround.shape[0]) Z3 = np.zeros(xround.shape[0]) Z4 = np.zeros(xround.shape[0]) Z5 = np.zeros(xround.shape[0]) dead = np.zeros(xround.shape[0]) for p in are_alive: #range(npts) south_front = southern_front[ yround[:, p], xround[:, p]] # select southern_front of one particle traj south_front.mask = xround[:, p].mask # mask elements of south_front that are irrelevant #print '' #print 'nb of parti :', p for t in range(xround.shape[0]): if south_front[t] != 0 and xround[t, p] > W_boundary and xround[ t, p] < E_boundary: #print t, 'in RG' Z1[t] += 1 #print Z1[t], Z2[t], Z3[t], Z4[t], Z5[t], dead[t] elif south_front[t] == 0: #print t, 'north' Z2[t:] += 1 #print Z1[t], Z2[t], Z3[t], Z4[t], Z5[t], dead[t] break # after the break, the particle is considered forever in the zone elif xround[t, p] <= W_boundary: #print t,'out to the west' Z3[t:] += 1 #print Z1[t], Z2[t], Z3[t], Z4[t], Z5[t], dead[t] break elif xround[t, p] >= E_boundary: #print t, 'east' Z4[t:] += 1 #print Z1[t], Z2[t], Z3[t], Z4[t], Z5[t], dead[t] break elif xround[t, p] <= W_boundary and xround[t, p] >= E_boundary: #print t, 'east and west' Z5[t:] += 1 #print Z1[t], Z2[t], Z3[t], Z4[t], Z5[t], dead[t] break elif south_front[t - 1] != 0 and xround[ t - 1, p] > W_boundary and xround[ t - 1, p] < E_boundary and xround.mask[t, p] == True: #print t, 'parti is dead !' dead[t:] += 1 #print Z1[t], Z2[t], Z3[t], Z4[t], Z5[t], dead[t] #print Z1[t-1], Z2[t-1], Z3[t-1], Z4[t-1], Z5[t-1], dead[t-1] break ##print Z1[t], Z2[t], Z3[t], Z4[t], Z5[t], dead[t] print '' print 'Different zones at t = 0 :', Z1[0], Z2[0], Z3[0], Z4[0], Z5[ 0], dead[0] print 'Different zones at t =', xround.shape[0], ':', Z1[-1], Z2[-1], Z3[ -1], Z4[-1], Z5[-1], dead[-1] print 'check at t = 0 :', Z1[0] + Z2[0] + Z3[0] + Z4[0] + Z5[0] + dead[0] print 'check at t = 44 :', Z1[44] + Z2[44] + Z3[44] + Z4[44] + Z5[ 44] + dead[44] print 'check at t = 100 :', Z1[100] + Z2[100] + Z3[100] + Z4[100] + Z5[ 100] + dead[100] print 'check at t =', xround.shape[ 0], ':', Z1[-1] + Z2[-1] + Z3[-1] + Z4[-1] + Z5[-1] + dead[-1] print '' pickle_save('NPP' + NPP + '_Z1', path, Z1, verbose=False) pickle_save('NPP' + NPP + '_Z2', path, Z2, verbose=False) pickle_save('NPP' + NPP + '_Z3', path, Z3, verbose=False) pickle_save('NPP' + NPP + '_Z4', path, Z4, verbose=False) pickle_save('NPP' + NPP + '_Z5', path, Z5, verbose=False) pickle_save('NPP' + NPP + '_dead', path, dead, verbose=False)