# ====================================================================
#
# Copyright 2025, PBL Netherlands Environmental Assessment Agency
# See the copyright notice at the end of this file.
#
# ====================================================================


# SDMfunction
# This function goes for each species through the following steps:
#   - SELECTION OF PRESENCES AND ABSENCES
#   - FORMAT INPUT DATA
#   - FITTING SDMS 
#   - EVALUATING THE CROSS-VALIDATED SDMS
#   - CALCULATE VARIABLE IMPORTANCE
#   - STORE RESPONSE CURVES AND MODELLED NICHE OPTIMA 
#   - PROJECT SDMs FOR ALL SCENARIO'S
#   - SAVE SPECIES SPECIFIC STATISTICS

SDMfunction <- function(myRespName){
  
  setwd(file.path(user_dir, base_dir))
  cat('\n',myRespName,'modeling...') 
  WriteLogFile(paste(user_dir, base_dir, species_out_dir, LogFile,sep="/"), ln=paste0("1. Start modelling ", myRespName,"."))
  
  tryCatch( {
    
    #============5. START SELECTION OF PRESENCES AND ABSENCES
    #===================================================================================================
    
    # Select a random sample of presences and absences
    ObservationData <- SelectSpeciesObservations(myRespName)
    
    # save plots locations in images to hard disk
    ImagesOfPlotLocations(myRespName, ObservationData, modelsetup$PlotLocations.dir)
    
    
    #============6. FORMAT INPUT DATA 
    #===================================================================================================
    
    BioModData <- FormatInputForFitting(ObservationData$AllData_test,
                                        VariableData$Variables, 
                                        ObservationData$AllData_GLM_GAM_fit, 
                                        ObservationData$AllData_BRT_fit,
                                        myRespName)
    
    
    #============7. START FITTING SDMS 
    #===================================================================================================
    
    # Fit the SDMs for Cross validation
    WriteLogFile(paste(user_dir, base_dir, species_out_dir, LogFile,sep="/"),
                 ln=paste0("2. Start fitting algoritms for ", myRespName,"."))
    
    ModelFits_CV <- FitSDMs(BioModData$BioModData_GAMGLM_CV,
                            BioModData$BioModData_BRT_CV,
                            ObservationData$ContinueAnalysis,
                            myRespName)
    
    # Fit the SDMs with 100% of the data for projections
    WriteLogFile(paste(user_dir, base_dir, species_out_dir, LogFile,sep="/"),
                 ln=paste0("3. Start fitting algoritms for ", myRespName," with all data."))
    
    ModelFits_100p <- FitSDMs(BioModData$BioModData_GAMGLM_100p,
                              BioModData$BioModData_BRT_100p,
                              ObservationData$ContinueAnalysis,
                              myRespName)
    
    
    #============8. START EVALUATING THE CROSS-VALIDATED SDMS
    #===================================================================================================
    
    CV_Evaluation_Data <- Evaluate_CV_SDMs(ModelFits_CV, 
                                           ObservationData, 
                                           myRespName)
    
    #============9. CALCULATE VARIABLE IMPORTANCE  
    #================================================================================================+
    
    VariableImportance <- VarImpFunction(VariableData$Variables,
                                         ModelFits_100p$ModelFit_GAMGLM, 
                                         ModelFits_100p$ModelFit_BRT,
                                         myRespName)
    
    
    #============10. STORE RESPONSE CURVES AND MODELLED NICHE OPTIMA 
    #================================================================================================+
    
    if(MIVCalc == TRUE){
      WriteLogFile(paste(user_dir, base_dir, species_out_dir, LogFile,sep="/")
                   ,ln=paste0("4. Calculate Response curves for ", myRespName,"."))
      
      CalculateResponseCurves(ModelFits_100p$ModelFit_GAMGLM, 
                              ModelFits_100p$ModelFit_BRT,
                              modelsetup$response.dir,
                              myRespName)
      
      WriteLogFile(paste(user_dir, base_dir, species_out_dir, LogFile,sep="/")
                   ,ln=paste0("5. Calculate MIV for ", myRespName,"."))
      
      MIV <- CalculateMIV(myRespName,modelsetup$response.dir,CV_Evaluation_Data$weights)
    } else MIV <- NA
    
    #============11. PROJECT SDMs FOR ALL SCENARIO'S
    #================================================================================================+
    
    # Make ensembled maps of the probability of occurrence of the species 
    # for each of the scenarios for which projections need to be made 
    MakeEnsembleMaps(ProjectScenarios, ModelFits_100p,myRespName, CV_Evaluation_Data$weights)
    
    # Calculate cut-off values or load them if they already exist
    cutoff.ens <- CutOffValue(myRespName, BioModData)
    
    # Save images of the range maps (PoO and binarized) to the hard disk
    ImageOfRangeMap(ProjectScenarios,  cutoff.ens, myRespName) 
    
    
    
    #============12. SAVE SPECIES SPECIFIC STATISTICS 
    #================================================================================================+
    
    ModelCorrectlyFinished <- TRUE
    
    
    SpeciesMetrics.dir <- modelsetup$SpeciesMetrics.dir
    
    
    # save species statistics and metadata to the hard disk
    SaveStats(myRespName, 
              modelsetup$SpeciesMetrics.dir, 
              ObservationData, 
              VariableImportance,
              CV_Evaluation_Data,
              MIV,
              ModelCorrectlyFinished,
              cutoff.ens)
    
    
    # clean memory
    CleanMemory()
    
  },
  error = function(e){
    cat("\nERROR in Biomod2 function for", myRespName, ": Aborted!\n")
    
    # write error message to log file
    error <- geterrmessage()
    WriteLogFile( file.path(user_dir, base_dir, species_out_dir, LogFile),
                  ln=paste0("ERROR: error in function of ", myRespName, ": ", error))
    
    ModelCorrectlyFinished <- FALSE
    
    # save species statistics and metadata to the hard disk
    SaveStats(myRespName, 
              modelsetup$SpeciesMetrics.dir, 
              ObservationData, 
              VariableImportance,
              CV_Evaluation_Data,
              MIV,
              ModelCorrectlyFinished)
    
    
    # clean memory
    CleanMemory() 
    
  }
  )
  
  
}




# ====================================================================
#
# Copyright 2025, PBL Netherlands Environmental Assessment Agency
# 
# This source code of the BioScore model is owned by PBL Netherlands Environmental Assessment Agency. 
# It is not permitted to copy, redistribute, remix, transform, and build upon the material without written approval of PBL. 
# Permission for commercial purposes will not be granted. 
# This code is published to improve the transparency of the models used by PBL, 
# but without any warranty for fitness for any other purpose. 
# After approval of PBL to use the code, PBL will not provide any support.
#
# 
# ====================================================================

