Project

General

Profile

« Previous | Next » 

Revision d299c301

Added by Benoit Parmentier about 9 years ago

adding residuals calls to function for kriging of residuals and clean up of main mosaicing script

View differences:

climate/research/oregon/interpolation/global_run_scalingup_mosaicing.R
5 5
#Analyses, figures, tables and data are also produced in the script.
6 6
#AUTHOR: Benoit Parmentier 
7 7
#CREATED ON: 04/14/2015  
8
#MODIFIED ON: 12/17/2015            
8
#MODIFIED ON: 12/19/2015            
9 9
#Version: 5
10 10
#PROJECT: Environmental Layers project     
11 11
#COMMENTS: analyses run for reg4 1992 for test of mosaicing using 1500x4500km and other tiles
12 12
#TODO:
13
#1) Make this is a script/function callable from the shell/bash
14
#2) generalize to run dates and region fast (use python mosaic Alberto code)
15
#3) clean up temporary files, it builds currently on the disk
16
#4) fix output folder for some of output files
17
#5) create a helper function for inputs/arguments to automate...?? Could also be in the assessment stage
13
#1) Make this is a script/function callable from the shell/bas
14
#2) clean up temporary files, it builds currently on the disk
15
#3) fix output folder for some of output files: create a mosaic output folder if doesn't exist?
16
#4) create a helper function for inputs/arguments to automate...?? Could also be in the assessment stage
18 17

  
19 18
### Before running, the gdal modules and other environment parameters need to be set if on NEX-NASA.
20 19
### This can be done by running the following commands:
......
25 24
#
26 25
#setfacl -Rmd user:aguzman4:rwx /nobackupp8/bparmen1/output_run10_1500x4500_global_analyses_pred_1992_10052015
27 26
#
27
#reg1   : North America
28
#reg23" : Europe + Asia
29
#reg4"  : South America
30
#reg5   : Africa
31
#reg6   : Oceania+ South East Asia
32
#
33

  
28 34
#################################################################################################
29 35

  
30 36
### Loading R library and packages        
......
58 64

  
59 65
#### FUNCTION USED IN SCRIPT
60 66

  
61
function_mosaicing <-"global_run_scalingup_mosaicing_function_12172015.R"
67
function_mosaicing <-"global_run_scalingup_mosaicing_function_12192015.R"
62 68

  
63
#in_dir_script <-"/home/parmentier/Data/IPLANT_project/env_layers_scripts" #NCEAS UCSB
64
in_dir_script <- "/nobackupp8/bparmen1/env_layers_scripts" #NASA NEX
69
in_dir_script <-"/home/parmentier/Data/IPLANT_project/env_layers_scripts" #NCEAS UCSB
70
#in_dir_script <- "/nobackupp8/bparmen1/env_layers_scripts" #NASA NEX
65 71
source(file.path(in_dir_script,function_mosaicing))
66 72

  
67 73
load_obj <- function(f)
......
86 92
############################################
87 93
#### Parameters and constants  
88 94

  
89
#Data is on ATLAS: reg4 (South America)
95
#Data is on ATLAS or NASA NEX
96
#PARAM 1
97
in_dir <- "/data/project/layers/commons/NEX_data/output_run10_1500x4500_global_analyses_pred_1992_12072015" #NCEAS
98
#in_dir <- "/nobackupp8/bparmen1/output_run10_1500x4500_global_analyses_pred_1992_12072015" #NEX
90 99

  
91
#in_dir <- "/data/project/layers/commons/NEX_data/mosaicing_data_test" #PARAM1
92
#in_dir <- "/data/project/layers/commons/NEX_data/output_run10_1500x4500_global_analyses_pred_1992_10052015" #PARAM4
93
#in_dir <- "/data/project/layers/commons/NEX_data/output_run10_1500x4500_global_analyses_pred_1992_12072015" #NEX
94
in_dir <- "/nobackupp8/bparmen1/output_run10_1500x4500_global_analyses_pred_1992_12072015" #NEX
95

  
96
in_dir_tiles <- file.path(in_dir,"tiles")
97
#in_dir_tiles <- "/nobackupp8/bparmen1/output_run10_1500x4500_global_analyses_pred_1992_10052015/tiles" #North America
98
#in_dir <- "/data/project/layers/commons/NEX_data/mosaicing_data_test/reg2" #Europe
99
#in_dir <- "/data/project/layers/commons/NEX_data/mosaicing_data_test/reg4" #South America
100
#in_dir <- "/data/project/layers/commons/NEX_data/mosaicing_data_test/reg5" #Africa
100
in_dir_tiles <- file.path(in_dir,"tiles") #this is valid both for Atlas and NEX
101 101

  
102 102
y_var_name <- "dailyTmax" #PARAM2
103 103
interpolation_method <- c("gam_CAI") #PARAM3
......
128 128
use_autokrige <- F #PARAM 19
129 129

  
130 130
###Separate folder for masks by regions, should be listed as just the dir!!... #PARAM 20
131
infile_mask <- "/nobackupp8/bparmen1/regions_input_files/r_mask_reg4.tif"
132
#infile_mask <- "/data/project/layers/commons/NEX_data/regions_input_files/r_mask_reg4.tif"
131
#infile_mask <- "/nobackupp8/bparmen1/regions_input_files/r_mask_reg4.tif"
132
infile_mask <- "/data/project/layers/commons/NEX_data/regions_input_files/r_mask_reg4.tif"
133 133

  
134 134
#tb_accuracy_name <- file.path(in_dir,paste("tb_diagnostic_v_NA","_",out_suffix_str,".txt",sep=""))
135 135
#tb_accuracy_name <- "/data/project/layers/commons/NEX_data/output_run10_1500x4500_global_analyses_pred_1992_12072015/tb_diagnostic_v_NA_run10_1500x4500_global_analyses_pred_1992_12072015.txt" #PARAM 21
......
138 138
#data_day_s_name <- "/data/project/layers/commons/NEX_data/output_run10_1500x4500_global_analyses_pred_1992_12072015/data_day_s_NAM_run10_1500x4500_global_analyses_pred_1992_12072015.txt" ##PARAM 24
139 139
#df_tile_processed_name <- "/data/project/layers/commons/NEX_data/output_run10_1500x4500_global_analyses_pred_1992_12072015/df_tile_processed_run10_1500x4500_global_analyses_pred_1992_12072015.txt" ##PARAM 25
140 140

  
141
#in_dir can be on NEX or Atlas
141 142
tb_accuracy_name <- file.path(in_dir,"tb_diagnostic_v_NA_run10_1500x4500_global_analyses_pred_1992_12072015.txt") #PARAM 21
142 143
data_month_s_name <- file.path(in_dir,"data_month_s_NAM_run10_1500x4500_global_analyses_pred_1992_12072015.txt") #PARAM 22
143 144
data_day_v_name <- file.path(in_dir,"data_day_v_NAM_run10_1500x4500_global_analyses_pred_1992_12072015.txt") #PARAM 23
......
145 146
df_tile_processed_name <- file.path(in_dir,"df_tile_processed_run10_1500x4500_global_analyses_pred_1992_12072015.txt") ##PARAM 25
146 147

  
147 148
#python script and gdal on NEX NASA:
148
mosaic_python <- "/nobackupp6/aguzman4/climateLayers/sharedCode/"
149
python_bin <- "/nobackupp6/aguzman4/climateLayers/sharedModules2/bin"
149
#mosaic_python <- "/nobackupp6/aguzman4/climateLayers/sharedCode/"
150
#python_bin <- "/nobackupp6/aguzman4/climateLayers/sharedModules2/bin"
150 151
#python script and gdal on Atlas NCEAS
151
#mosaic_python <- "/data/project/layers/commons/NEX_data/sharedCode" #PARAM 26
152
#python_bin <- "/usr/bin" #PARAM 27
152
mosaic_python <- "/data/project/layers/commons/NEX_data/sharedCode" #PARAM 26
153
python_bin <- "/usr/bin" #PARAM 27
153 154

  
154 155
algorithm <- "python" #PARAM 28 #if R use mosaic function for R, if python use modified gdalmerge script from Alberto Guzmann
155 156
#algorithm <- "R" #if R use mosaic function for R, if python use modified gdalmerge script from Alberto Guzmann
156 157
 
157 158
match_extent <- "FALSE" #PARAM 29 #try without matching!!!
158 159

  
160
#for residuals...
161
list_models <- NULL #PARAM 30
162
#list_models <- paste(var_pred,"~","1",sep=" ") #if null then this is the default...
163

  
159 164
########################## START SCRIPT ##############################
160 165

  
161 166

  
......
192 197

  
193 198
##################### PART 2: produce the mosaic ##################
194 199

  
195
##########################
196
#### First generate rmse images for each date and tile for the region
200
#This is is assuming a list of file for a region!! 
201
#this is where the main function for mosaicing region starts!!
202
#use reg4 to test the code for now, redo later for any regions!!!
203
k<-2
204
for(k in 1:length(region_names)){
205
  region_selected <- region_names[k]
206
  ##########################
207
  #### First generate rmse images for each date and tile for the region
197 208

  
198
#lf <- lf_mosaic1 #list of files to mosaic for date 1, there a 28 files for reg4, South America
199 209

  
200
#use reg4 to test the code for now, redo later for any regions!!!
201
lf_mosaic <- reg_lf_mosaic[[2]] #list of files to mosaic for date 1, there a 28 files for reg4, South America
202

  
203
#tb <- list_param$tb #fitting or validation table with all days
204
#metric_name <- "rmse" #RMSE, MAE etc.
205
#pred_mod_name <- "mod1"
206
#y_var_name 
207
#interpolation_method #c("gam_CAI") #PARAM3
208
days_to_process <- day_to_mosaic
209
#NA_flag_val <- list_param$NA_flag_val
210
#file_format <- list_param$file_format
211
out_dir_str <- out_dir
212
out_suffix_str <- out_suffix
213

  
214
#Improved by adding multicores option
215
num_cores_tmp <- 6
216
list_param_accuracy_metric_raster <- list(lf,tb,metric_name,pred_mod_name,y_var_name,interpolation_method,
210
  lf_mosaic <- reg_lf_mosaic[[k]] #list of files to mosaic by regions
211
                                #There a 28 files for reg4, South America
212

  
213
  #######################################
214
  ################### PART I: Accuracy layers by tiles #############
215
  #first generate accuracy layers using tiles definitions and output from the accuracy assessment
216
  
217
  #tb <- list_param$tb #fitting or validation table with all days
218
  #metric_name <- "rmse" #RMSE, MAE etc.
219
  #pred_mod_name <- "mod1"
220
  #y_var_name 
221
  #interpolation_method #c("gam_CAI") #PARAM3
222
  days_to_process <- day_to_mosaic
223
  #NA_flag_val <- list_param$NA_flag_val
224
  #file_format <- list_param$file_format
225
  out_dir_str <- out_dir
226
  out_suffix_str <- out_suffix
227
  lf <- lf_mosaic
228

  
229
  #Improved by adding multicores option
230
  num_cores_tmp <- num_cores
231
  list_param_accuracy_metric_raster <- list(lf,tb,metric_name,pred_mod_name,y_var_name,interpolation_method,
217 232
                    days_to_process,num_cores_tmp,NA_flag_val,file_format,out_dir_str,out_suffix_str) 
218
names(list_param_accuracy_metric_raster) <- c("lf","tb","metric_name","pred_mod_name","y_var_name","interpolation_method",
233
  names(list_param_accuracy_metric_raster) <- c("lf","tb","metric_name","pred_mod_name","y_var_name","interpolation_method",
219 234
                       "days_to_process","num_cores","NA_flag_val","file_format","out_dir_str","out_suffix_str") 
220
list_raster_created_obj <- lapply(1:length(day_to_mosaic),FUN=create_accuracy_metric_raster,
235
  list_raster_created_obj <- lapply(1:length(day_to_mosaic),FUN=create_accuracy_metric_raster,
221 236
                                  list_param=list_param_accuracy_metric_raster)
222 237

  
223
#debug(create_accuracy_metric_raster)
224
#list_raster_created_obj <- lapply(1:1,FUN=create_accuracy_metric_raster,
225
#                                  list_param=list_param_accuracy_metric_raster)
226

  
227
#raster_created_obj <- create_accuracy_metric_raster(1, list_param_accuracy_metric_raster)
228

  
229
#Extract list of files for rmse and date 1 (19920101), there should be 28 raster images
230
lf_accuracy_raster <- lapply(1:length(list_raster_created_obj),FUN=function(i){unlist(list_raster_created_obj[[i]]$list_raster_name)}) 
231

  
232
#Plot as quick check
233
r1 <- raster(lf_mosaic[[1]][1]) 
234
#r2 <- raster(lf_mosaic2[2]) 
235

  
236
#plot(r1)
237
#plot(r2)
238
#r1_ac <- raster(lf_accuracy_raster[[1]][1]) 
239
#plot(r1_ac)
240

  
241
####################################
242
### Now create accuracy surfaces from residuals...
243

  
244
## Create accuracy surface by kriging
245

  
246
num_cores_tmp <- 7
247
lf_day_tiles  <- lf_mosaic #list of raster files by dates
248
data_df <- data_day_v # data.frame table/spdf containing stations with residuals and variable
249
#df_tile_processed  #tiles processed during assessment usually by region
250
#var_pred  #variable being modeled
251
list_models <- paste(var_pred,"~","1",sep=" ")
252
#use_autokrige #if TRUE use automap/gstat package
253
#y_var_name  #"dailyTmax" #PARAM2
254
#interpolation_method #c("gam_CAI") #PARAM3, need to select reg!!
255
#date_processed #can be a monthly layer
256
#num_cores #number of cores used
257
#NA_flag_val 
258
#file_format 
259
out_dir_str <- out_dir
260
out_suffix_str <- out_suffix 
261
days_to_process <- day_to_mosaic
262
df_tile_processed$path_NEX <- as.character(df_tile_processed$path_NEX)
263
df_tile_processed$reg <- basename(dirname(df_tile_processed$path_NEX))
264

  
265
##By regions, selected earlier
266
for(k in 1:length(region_names)){
267
  df_tile_processed_reg <- subset(df_tile_processed,reg==region_names[k])#use reg4
238
  #debug(create_accuracy_metric_raster)
239
  #list_raster_created_obj <- lapply(1:1,FUN=create_accuracy_metric_raster,
240
  #                                  list_param=list_param_accuracy_metric_raster)
241
  #raster_created_obj <- create_accuracy_metric_raster(1, list_param_accuracy_metric_raster)
242

  
243
  #Extract list of files for rmse and date 1 (19920101), there should be 28 raster images
244
  lf_accuracy_raster <- lapply(1:length(list_raster_created_obj),FUN=function(i){unlist(list_raster_created_obj[[i]]$list_raster_name)}) 
245

  
246
  #Plot as quick check
247
  #r1 <- raster(lf_mosaic[[1]][1]) 
248
  #plot(r1)
249

  
250
  ####################################
251
  ### Now create accuracy surfaces from residuals...
252

  
253
  ## Create accuracy surface by kriging
254

  
255
  num_cores_tmp <-num_cores
256
  lf_day_tiles  <- lf_mosaic #list of raster files by dates
257
  data_df <- data_day_v # data.frame table/spdf containing stations with residuals and variable
258
  #df_tile_processed  #tiles processed during assessment usually by region
259
  #var_pred  #variable being modeled
260
  #if not list of models is provided generate one
261
  if(is.null(list_models)){
262
    list_models <- paste(var_pred,"~","1",sep=" ")
263
  }
264

  
265
  #use_autokrige #if TRUE use automap/gstat package
266
  #y_var_name  #"dailyTmax" #PARAM2
267
  #interpolation_method #c("gam_CAI") #PARAM3, need to select reg!!
268
  #date_processed #can be a monthly layer
269
  #num_cores #number of cores used
270
  #NA_flag_val 
271
  #file_format 
272
  out_dir_str <- out_dir
273
  out_suffix_str <- out_suffix 
274
  days_to_process <- day_to_mosaic
275
  df_tile_processed$path_NEX <- as.character(df_tile_processed$path_NEX) 
276
  df_tile_processed$reg <- basename(dirname(df_tile_processed$path_NEX))
277

  
278
  ##By regions, selected earlier
279
  #for(k in 1:length(region_names)){
280
  df_tile_processed_reg <- subset(df_tile_processed,reg==region_selected)#use reg4
268 281
  #i<-1 #loop by days/date to process!!
269 282
  #test on the first day 
270 283
  list_param_create_accuracy_residuals_raster <- list(lf_day_tiles,data_df,df_tile_processed_reg,
......
276 289
                    "days_to_process","num_cores_tmp","NA_flag_val","file_format","out_dir_str",
277 290
                    "out_suffix_str") 
278 291

  
279
  #list_create_accuracy_residuals_raster_obj <- lapply(1:length(day_to_mosaic),FUN=create_accuracy_residuals_raster_obj,
280
  #                                list_param=list_param_create_accuracy_residuals_raster_obj)
292
  list_create_accuracy_residuals_raster_obj <- lapply(1:length(day_to_mosaic),FUN=create_accuracy_residuals_raster,
293
                                  list_param=list_param_create_accuracy_residuals_raster)
281 294

  
282 295
  #undebug(create_accuracy_residuals_raster)
283
  list_create_accuracy_residuals_raster_obj <- lapply(1:1,FUN=create_accuracy_residuals_raster,
284
                                  list_param=list_param_create_accuracy_residuals_raster)
296
  #list_create_accuracy_residuals_raster_obj <- lapply(1:1,FUN=create_accuracy_residuals_raster,
297
  #                                list_param=list_param_create_accuracy_residuals_raster)
285 298

  
286 299
  #create_accuracy_residuals_raster_obj <- create_accuracy_metric_raster(1, list_param_create_accuracy_residuals_raster_obj)
287 300

  
288
}
289

  
290
lf_accuracy_residuals_raster <- lapply(1:length(list_raster_created_obj),FUN=function(i){unlist(list_raster_created_obj[[i]]$list_raster_name)}) 
291

  
292
#Plot as quick check
293
r1 <- raster(lf_mosaic[[1]][1]) 
301
  #note that three tiles did not produce a residuals surface!!! find out more later, join the output
302
  #to df_raste_tile to keep track of which one did not work...
303
  #lf_accuracy_residuals_raster <- as.character(unlist(lapply(1:length(list_create_accuracy_residuals_raster_obj),FUN=function(i,x){unlist(extract_from_list_obj(x[[i]]$list_pred_res_obj,"raster_name"))},x=list_create_accuracy_residuals_raster_obj))) 
304
  lf_accuracy_residuals_raster <- lapply(1:length(list_create_accuracy_residuals_raster_obj),FUN=function(i,x){as.character(unlist(extract_from_list_obj(x[[i]]$list_pred_res_obj,"raster_name")))},x=list_create_accuracy_residuals_raster_obj)
294 305

  
295
list_create_accuracy_residuals_raster_obj
296

  
297
#################################
298
#### Second mosaic tiles for the variable and accuracy metrid
299

  
300
#methods availbable:use_sine_weights,use_edge,use_linear_weights
301
#only use edge method for now
302
#loop to dates..., make this a function...
303
list_mosaic_obj <- vector("list",length=length(day_to_mosaic))
304
for(i in 1:length(day_to_mosaic)){
306
  #Plot as quick check
307
  #r1 <- raster(lf_mosaic[[1]][1]) 
308
  #list_create_accuracy_residuals_raster_obj
305 309
  
306
  mosaic_method <- "use_edge_weights" #this is distance from edge
307
  out_suffix_tmp <- paste(interpolation_method,y_var_name,day_to_mosaic[i],out_suffix,sep="_")
308
  #debug(mosaicFiles)
309
  #can also loop through methods!!!
310
  #python_bin <- "/usr/bin/" #python gdal bin, on Atlas NCEAS
311
  #python_bin <- "/nobackupp6/aguzman4/climateLayers/sharedModules/bin" #on NEX
312
  #gdal_merge_sum_noDataTest.py
313

  
314
  mosaic_edge_obj_prediction <- mosaicFiles(lf_mosaic[[i]],
310
  ######################################################
311
  #### PART 2: GENETATE MOSAIC FOR LIST OF FILES #####
312
  #################################
313
  #### Mosaic tiles for the variable predicted and accuracy metric
314

  
315
  #methods availbable:use_sine_weights,use_edge,use_linear_weights
316
  #only use edge method for now
317
  #loop to dates..., make this a function...
318
  list_mosaic_obj <- vector("list",length=length(day_to_mosaic))
319
  for(i in 1:length(day_to_mosaic)){
320
    #
321
    mosaic_method <- "use_edge_weights" #this is distance from edge
322
    out_suffix_tmp <- paste(interpolation_method,y_var_name,day_to_mosaic[i],out_suffix,sep="_")
323
    #debug(mosaicFiles)
324
    #can also loop through methods!!!
325
    #python_bin <- "/usr/bin/" #python gdal bin, on Atlas NCEAS
326
    #python_bin <- "/nobackupp6/aguzman4/climateLayers/sharedModules/bin" #on NEX
327
    #gdal_merge_sum_noDataTest.py
328

  
329
    mosaic_edge_obj_prediction <- mosaicFiles(lf_mosaic[[i]],
315 330
                                        mosaic_method="use_edge_weights",
316 331
                                        num_cores=num_cores,
317 332
                                        r_mask_raster_name=infile_mask,
......
325 340
                                        out_suffix=out_suffix_tmp,
326 341
                                        out_dir=out_dir)
327 342
  
328
  mosaic_method <- "use_edge_weights" #this is distance from edge
329
  out_suffix_tmp <- paste(interpolation_method,metric_name,day_to_mosaic[i],out_suffix,sep="_")
343
    mosaic_method <- "use_edge_weights" #this is distance from edge
344
    out_suffix_tmp <- paste(interpolation_method,metric_name,day_to_mosaic[i],out_suffix,sep="_")
330 345

  
331
  #debug(mosaicFiles)
332
  #can also loop through methods!!!
333
  mosaic_edge_obj_accuracy <- mosaicFiles(lf_accuracy_raster[[i]],
346
    #debug(mosaicFiles)
347
    #can also loop through methods!!!
348
    mosaic_edge_obj_accuracy <- mosaicFiles(lf_accuracy_raster[[i]],
334 349
                                        mosaic_method="use_edge_weights",
335 350
                                        num_cores=num_cores,
336 351
                                        r_mask_raster_name=infile_mask,
......
343 358
                                        out_suffix=out_suffix_tmp,
344 359
                                        out_dir=out_dir)
345 360
  
346
  list_mosaic_obj[[i]] <- list(prediction=mosaic_edge_obj_prediction,accuracy=mosaic_edge_obj_accuracy)
347

  
348
  ### produce residuals mosaics
349
  mosaic_method <- "use_edge_weights" #this is distance from edge
350
  out_suffix_tmp <- paste(interpolation_method,"kriged_residuals",day_to_mosaic[i],out_suffix,sep="_")
351
  lf_tmp<-list.files(pattern="*kriged_residuals.*.tif",full.names=T)
352
  #lf_accuracy_residuals_raster[[i]]
353
  mosaic_edge_obj_residuals <- mosaicFiles(lf_tmp,
361
    list_mosaic_obj[[i]] <- list(prediction=mosaic_edge_obj_prediction,accuracy=mosaic_edge_obj_accuracy)
362

  
363
    ### produce residuals mosaics
364
    mosaic_method <- "use_edge_weights" #this is distance from edge
365
    out_suffix_tmp <- paste(interpolation_method,"kriged_residuals",day_to_mosaic[i],out_suffix,sep="_")
366
    #lf_tmp<-list.files(pattern="*kriged_residuals.*.tif",full.names=T)
367
    lf_tmp <- lf_accuracy_residuals_raster[[i]]
368
    #lf_accuracy_residuals_raster[[i]]
369
    #debug(mosaicFiles)
370
    mosaic_edge_obj_residuals <- mosaicFiles(lf_tmp,
354 371
                                        mosaic_method="use_edge_weights",
355 372
                                        num_cores=num_cores,
356 373
                                        r_mask_raster_name=infile_mask,
357 374
                                        python_bin=python_bin,
358 375
                                        mosaic_python=mosaic_python,
359 376
                                        algorithm=algorithm,
377
                                        match_extent=match_extent,
360 378
                                        df_points=NULL,
361 379
                                        NA_flag=NA_flag_val,
362 380
                                        file_format=file_format,
363 381
                                        out_suffix=out_suffix_tmp,
364 382
                                        out_dir=out_dir)
365 383
  
366
  list_mosaic_obj[[i]] <- list(prediction=mosaic_edge_obj_prediction,accuracy=mosaic_edge_obj_accuracy,mosaic_edge_obj_residuals)
367
  
384
    list_mosaic_obj[[i]] <- list(prediction=mosaic_edge_obj_prediction,accuracy=mosaic_edge_obj_accuracy,mosaic_edge_obj_residuals)
385
  }
386

  
387
  ##End of mosaicing function for region predictions
368 388
}
369 389

  
390

  
370 391
#####################
371 392
###### PART 2: Analysis and figures for the outputs of mosaic function #####
372 393

  

Also available in: Unified diff