Restructuring FPRESS 2.0.0

Put some intro-text here.

#FPRESS.run.r 
#Andrew Campbell
#Marine Institite, Galway
#andrew.campbell@marine.ie
#V1 10/07/2006
#V2 28/08/2006	  completed comments, some minor modifications to make
#                 code more readable
#V2 10/10/2006	  tacopt,simtype,tacmin,tacmax,tacbias,taccv,fmin,fmax,fbarcv,
#                 fbias replaced with variable,resolution,varmin,varmax,varcv,varbias
#V2 16/10/2006	  function changed to FPRESS.Run(), runref missing, output 
#                 directory changed to outdata
#
# Einar Hjörleifsson
# Marines Research Institute, Reykavík
# einarhj@hafro.is
# 
# FPRESS obtained from Andrew Campell on 12.8.2009
# Relative to the original run.r script, only minor changes have been made to the
# actual executable part of the program. However, major restructuring has been
# done on programming blocks and the commenting.
# Track on some critical bugs that have been discovered in the original run.r
# are kept on the DokuWiki-site fishvice.hafro.is
#

#        10        20        30        40        50        60        70        80        90
#234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234

















































FPRESS.Run<-function(runref="missing",batch=0,debug=0)
{
   # runref - the simulation reference. Function will examine file 
   # options<runref>.xml
   # for model parameters
   # batch - batch flag. If true(1), the function will not prompt user for
   # any settings and will use defaults.
   # debug flag - if true(1), print debug information to the screen

   if (!(is.numeric(batch)))
      stop("FPRESS.Run::if batch argument is supplied it must assume a value of 0 or 1\n")
   if (!(is.numeric(debug)))
      stop("FPRESS.Run::if debug argument is supplied it must assume a value of 0 or 1\n")
   if (!(batch==1) & !(batch==0)) 
      stop("FPRESS.Run::if batch argument is supplied it must assume a value of 0 or 1\n")
   if (!(debug==1) & !(debug==0))
      stop("FPRESS.Run::if debug argument is supplied it must assume a value of 0 or 1\n")

   
   currwd<-getwd()            #save the current working directory
   home <- FPRESS.Home()      #get the FPRESS home directory
   if (debug==1) {cat("home=",home,"\n")}
   if (nchar(home)==0) 
      stop("Exiting - no FPRESSHome environment variable")
   #prompt for the run reference (only if not in batch mode)
   if (batch==0) {
      if (missing(runref)) { 
	     runref<-winDialogString("Run Reference?","")
      }
   } else {
      if (missing(runref)) stop("No run reference")
   }
   if (nchar(runref)==0) stop("Exiting - no run reference provided")

  ##############################################################################
  # READ IN THE OPTION FILE
  #
  # This file contains simulation parameters and controls with regards to
  # the fisheries and management and user controls of output files
  # The file is located in the folder options in the path given by
  # FPRESS.Home. This section contains the following steps:
  # 1. Check if the file exists. If not stop, otherwise read the.xml file
  # 2. Assign the individual parameters in the file to a local variable name
  # are assigned to a local r variable name
  # 3. Generate some illegible computer ontrol with regards user requested
  #    output.
  # 4. Some code to adapt the generic FPRESS to iCod HCR evaluation
  # 5. Give some user feedback, if requested
  #
  # Some explanation of each variable in the control file:
  # datarecyear - the final year of historical recruitment data contained in
  #               recfile that is to be included in the simulation (including
  #               the bootstrapping options). This parameter permits the use of 
  #               only a portion of the historical recruitment data. If greater
  #               than the final year's data then all data in the file will
  #                be used
  # varcv - the coefficient of variation to used when adding in noise to the 
  #         controlling variable    
  # varbias - the amount of bias to apply when randomising the controlling
  #            variable
  # varmin - the minimum (first) or only (for resolution=0) value to use
  #          for the controlling variable
  # varmax - for simulations with resolution>0, he maximum (final) value to
  #          use for the controlling variable
  #          assessdelay - this parameter controls the timing of assessment
  #          events. The assessment will be based on simulated data
  #          corresponding to the current year less the number of years
  #          given in assessdelay.
  # hcrchange - the proportional change to TAC of F (as a result of an HCR)
  #             permitted in a single year   
  # ssbhcr - reference SSB level used by some HCRs for comparison with
  #          simulated SSB levels
  # fbarhcr - reference fbar value used by some HCRs for comparison with
  #           simulated fbar values 
  # minTAC - if a minimum TAC must be taken then this value will be greater
  #          than zero. Applies only with variable=0   
  # hcrperiod - (in years) between harvest control rule actions being applied
  #             to the assessment
  # OTHER VARIABLES - see in-line comments below
   
  # 1. Read in the whole file ##################################################
  #
   optionsfile = paste(FPRESS.Home(),"\\options\\","options",runref,".xml",sep="")
   #check options file exists
   if (!(file.exists(optionsfile))) {
      stop(paste("\nOptions file",optionsfile,"doesn't exist\nUnable to continue\n",sep=" "))}
   doc<-xmlTreeParse(optionsfile)    # read in the file


  # 2. Pick individual parameters and assign them to a local variable name #####
  #
   root<-xmlRoot(doc) #root xmlNode object
   stockname<-nodeval(root,"stockname","")                # Stock name etc.
   indata.path<-paste(FPRESS.Home(),"\\indata\\",sep="")  # path to input data
   outdata.path<-paste(FPRESS.Home(),"\\outdata\\",sep="")# path to output
   datfile<-nodeval(root,"datfile","")                    # age data file
   recfile<-nodeval(root,"recfile","")                    # historical R & SBB
   catchfile<-nodeval(root,"catchfile","")                # historical Y & F
   minage<-as.integer(nodeval(root,"minage",1))           # minimum age
   maxage<-as.integer(nodeval(root,"maxage",1))           # max age, treated as a +group
   fbarmin<-as.integer(nodeval(root,"fbarmin",0))         # lower age class for fbar
   fbarmax<-as.integer(nodeval(root,"fbarmax",1))         # upper age class for fbar
   ssbtest1<-as.integer(nodeval(root,"ssbtest1",0))       # virtual ssb test level 1 (e.g. Blim)
   ssbtest2<-as.integer(nodeval(root,"ssbtest2",0))       # vitural ssb text level 2 (e.g. Bpa)
   resolution<-as.integer(nodeval(root,"resolution",0))   # number of steps of F or TAC to be tested
   startyear<-as.integer(nodeval(root,"startyear",1))     # simulation start year
   years<-as.integer(nodeval(root,"years",1))             # number of simulation years
   iterations<-as.integer(nodeval(root,"iterations",1))   # simulation number per resolution
   histrec<-as.integer(nodeval(root,"histrec",0))         # flag, if 1 use historical recruits
   histreccv<-as.numeric(nodeval(root,"histreccv",0))     # historical recruit cv
   histcatch<-as.integer(nodeval(root,"histcatch",0))     # flag, if 1 then use historical catch/fbar
   histcatchcv<-as.numeric(nodeval(root,"histcatchcv",0)) # historical catch/fbar cv
   rec<-as.integer(nodeval(root,"rec",0))                 # recruitment model number
   recmean<-as.numeric(nodeval(root,"recmean",0))         # mean recruitment (sometimes used)
   reccv<-as.numeric(nodeval(root,"reccv",0))             # recruitment cv
   seggrad<-as.numeric(nodeval(root,"seggrad",1))         # slope of the segmented regression line
   ssbcut<-as.numeric(nodeval(root,"ssbcut",0))           # SSB (S*) break point value in the segm. regression
   datarecyear<-as.integer(nodeval(root,"datarecyear",0)) # See comments at start
   variable<-as.numeric(nodeval(root,"variable",0))       # TAC(0) or F(1) based simulation
   varcv<-as.numeric(nodeval(root,"varcv",0))
   varbias<-as.numeric(nodeval(root,"varbias",1))
   varmin<-as.numeric(nodeval(root,"varmin",1))
   varmax<-as.numeric(nodeval(root,"varmax",1))
   assessdelay<-as.integer(nodeval(root,"assessdelay",1))
   ssbassessbias<-as.numeric(nodeval(root,"ssbassessbias",1))     # ssb assessment bias
   ssbassesscv<-as.numeric(nodeval(root,"ssbassesscv",0))         # ssb assessment cv
   fbarassessbias<-as.numeric(nodeval(root,"fbarassessbias",1))   # F assessment bias
   fbarassesscv<-as.numeric(nodeval(root,"fbarassesscv",0))       # F assessment cv
   hcrrule<-as.integer(nodeval(root,"hcrrule",0))                 # hcrrule
   hcrperiod<-as.integer(nodeval(root,"hcrperiod",1))             
   hcrchange<-as.numeric(nodeval(root,"hcrchange",1))
   ssbhcr<-as.numeric(nodeval(root,"ssbhcr",0))
   fbarhcr<-as.numeric(nodeval(root,"fbarhcr",0))
   mintac<-as.numeric(nodeval(root,"minimumtac",0))
   opftacmult<-as.numeric(nodeval(root,"opftacmult",0))        # ftac multiplier
   oprecruits<-as.numeric(nodeval(root,"oprecruits",1))        # recruits
   oppop<-as.numeric(nodeval(root,"oppop",0))                  # population (Nay)
   opftac<-as.numeric(nodeval(root,"opftac",0))                # opftac (F or TAC)
   opf<-as.numeric(nodeval(root,"opf",0))                      # opf
   opfmult<-as.numeric(nodeval(root,"opfmult",0))              # F multiplier
   opspawningmass<-as.numeric(nodeval(root,"opspawningmass",1))# SSB
   opfbar<-as.numeric(nodeval(root,"opfbar",1))                # Fbar
   opcatch<-as.numeric(nodeval(root,"opcatch",0))              # Catch (numbers)
   opcatchweight<-as.numeric(nodeval(root,"opcatchweight",1))  # Catch (weight)
   opyestock<-as.numeric(nodeval(root,"opyestock",0))          # stock in final year
   opindex<-as.numeric(nodeval(root,"opindex",0))              # ?????




   # 3. Code related to controling file output #################################
   #                                              
    savedobjs<-c()
    if (opindex>=1024){savedobjs<-c(savedobjs,"YearEndStock");         opindex<-opindex-1024}
    if (opindex>=512) {savedobjs<-c(savedobjs,"CatchWeight");          opindex<-opindex-512}
    if (opindex>=256) {savedobjs<-c(savedobjs,"Catch");                opindex<-opindex-256}
    if (opindex>=128) {savedobjs<-c(savedobjs,"FBar");                 opindex<-opindex-128}
    if (opindex>=64)  {savedobjs<-c(savedobjs,"NewSpawnMass");         opindex<-opindex-64}
    if (opindex>=32)  {savedobjs<-c(savedobjs,"FishingMortalityMult"); opindex<-opindex-32}
    if (opindex>=16)  {savedobjs<-c(savedobjs,"FishingMortality");     opindex<-opindex-16}
    if (opindex>=8)   {savedobjs<-c(savedobjs,"FTac");                 opindex<-opindex-8}
    if (opindex>=4)   {savedobjs<-c(savedobjs,"Pop");                  opindex<-opindex-4}
    if (opindex>=2)   {savedobjs<-c(savedobjs,"Recruits");             opindex<-opindex-2}
    if (opindex>=1)   {savedobjs<-c(savedobjs,"FTacMult");             opindex<-opindex-1}
    if (debug==1) {cat("savedobjs=",savedobjs,"\n")}
  # 4. Some shitmix related to iCod adaptation
  #  If variable=0 (TAC fisheries) and varmin < 1 then on assumes that
  #  varmin (and varmax) stands for harvest rate. 
  #
   if(variable==0 & varmin<1) (variable<-2)

  # 5. Give user some feedback, if he requested  ###############################
  #   
   if (debug==1) {cat("stockname=",stockname,"\n",
                      "indata.path=",indata.path,"\n",
                      "outdata.path=",outdata.path,"\n",
                      "datfile=",datfile,"\n",
                      "recfile=",recfile,"\n",
                      "catchfile=",catchfile,"\n",
                      "minage=",minage,"\n",
                      "maxage=",maxage,"\n",
                      "fbarmin=",fbarmin,"\n",
                      "fbarmax=",fbarmax,"\n",
                      "ssbtest1=",ssbtest1,"\n",
                      "ssbtest2=",ssbtest2,"\n",
                      "resolution=",resolution,"\n",
                      "startyear=",startyear,"\n",
                      "years=",years,"\n",
                      "iterations=",iterations,"\n",
                      "histrec=",histrec,"\n",
                      "histreccv=",histreccv,"\n",
                      "histcatch=",histcatch,"\n",
                      "histcatchcv=",histcatchcv,"\n",
                      "rec=",rec,"\n",
                      "recmean=",recmean,"\n",
                      "reccv=",reccv,"\n",
                      "seggrad=",seggrad,"\n",
                      "ssbcut=",ssbcut,"\n",
                      "datarecyear=",datarecyear,"\n",
                      "variable=",variable,"\n",
                      "varcv=",varcv,"\n",
                      "varbias=",varbias,"\n",
                      "varmin=",varmin,"\n",
                      "varmax=",varmax,"\n",
                      "assessdelay=",assessdelay,"\n",
                      "ssbassessbias=",ssbassessbias,"\n",
                      "ssbassesscv=",ssbassesscv,"\n",
                      "fbarassessbias=",fbarassessbias,"\n",
                      "fbarassesscv=",fbarassesscv,"\n",
                      "hcrrule=",hcrrule,"\n",
                      "hcrperiod=",hcrperiod,"\n",
                      "hcrchange=",hcrchange,"\n",
                      "ssbhcr=",ssbhcr,"\n",
                      "fbarhcr=",fbarhcr,"\n",
                      "minimumtac=",mintac,"\n")}
                      
  #
  # END:  READ IN THE OPTION FILE
  ##############################################################################


   
 


  ##############################################################################
  # READ IN THE (AGE) DATA FILE
  #
  # This file contains age structured biological information about the stock
  # to be used in the simulation. The code below is in following steps:
  #   1. Check if the file exists, if not STOP the program
  #   2. Read in the whole file. Check for consistency in the number of age
  #      age groups in the data file and the control file. STOP if there is
  #      inconsistencey
  #   3. Assign individual values to local parameters
  
  # 1. Check for existence
    if (!(file.exists(datfile))) {
     stop(paste("\nInitialisation file",datfile,"doesn't exist\nUnable to continue\n",sep=" "))}
  # 2. Read in the whole file and check for inconsistency
   indata<-matrix(scan(datfile,0,quiet=TRUE),ncol=17,byrow=TRUE)   # EINAR - replaced ncol=18 with ncol=17 
   numage<-length(indata[,1])
   if ((maxage-minage+1)!=numage) {
      stop(paste("\nThe age class data supplied in the initialisation data file (",datfile,")\ndoes not match the age class range (",minage,"-",maxage,") in the options file (",optionsfile,")\n",sep=""))
   }
  # 3. Read in each vector file
   initage<-indata[,1]             #age class
   initpopint<-indata[,2]          #population (000s)
   initpopcv<-indata[,3]           #population cv
   initspwnweightint<-indata[,4]   #spawning weight (kg)
   initspwnweightcv <-indata[,5]   #spawning weight cv
   initcatweightint<-indata[,6]    #catch weight (kg)
   initcatweightcv<-indata[,7]     #catch weight cb
   initmatureint<-indata[,8]       #maturity
   initmaturecv<-indata[,9]        #maturity cv
   initfint<-indata[,10]           #fishing mortality
   initfcv<-indata[,11]            #fishing mortality cv  
   initfprop<-indata[,12]          #proportion of fishing mort. before spawning 
   initdisfint<-indata[,13]        #discard mortality
   initdisfcv<-indata[,14]         #discard mortality cv
   initmint<-indata[,15]           #natural mortality
   initmcv<-indata[,16]            #natural mortality cv
   initmprop<-indata[,17]          #proportio of natural mort. before spawning
   
  #
  # END: READ IN THE DATA FILE
  ##############################################################################
                                                                                  
  ##############################################################################
  # READ IN HISTORICAL RECRUITMENT, SSB, CATCH & FISHING MORTALITY
  #
  # 1. Read in the recruit file. The file contains year, recruitment at a
  #    at a specific age and spawning stock biomass. The setup of the
  #     external file is thus in the classical ICES summary table format
  #
  # 2. Read in the historical catch and and F file
   
  # 1. Historical recruit file 
    input<-scan(recfile,list(0,0,0),quiet=TRUE)
    recyear<-input[[1]]   #recruitment data year vector
    recr<-input[[2]]      #recruitment data recruitment numbers vector
    rssbin<-input[[3]]    #recruitment data ssb vector
    SS <- data.frame(year=recyear,recr=recr,ssb<-rssbin)  # Einar check
  # 2. Historical catch file
   input<-scan(catchfile,list(0,0,0),quiet=TRUE)
   catyear<-input[[1]]
   ccatch<-input[[2]]
   cfbar<-input[[3]]

  #
  # END: READ IN HISTORICAL RECRUITMENT, SSB, CATCH & FISHING MORTALITY
  ##############################################################################
  
  






  ##############################################################################
  #    START of INITIALISATION
  #
  # 

  # create a vector of output filenames. The number of output files
  #   will be resolution+1
   FLRfiles<-paste("FLRObjects_",runref,"_",1:(resolution+1),".dat",sep="")

  # The varmin in the options file specifies either the lowest fishing mortality
  # (variable=1) or the lowest catch (variable=0) to be tested. In the running
  # of the model this value gets assign to the local variable ftac.
   ftac<-varmin           # start with the min. value of variable (F or TAC)

   ftacmult<-1          # used in controlling the fisheries via managment module
   oldftacmult<-1       # initialisation
   endyear<-startyear+years-1
 
   lenrecyr<-length(recyear)                 # length of recruitment data set
   if (histrec==1) {maxrecyr<-max(recyear)}  # 
   
   if(histcatch==1){     
      maxcatyr<-max(catyear)     #last year of catch data      
      lencatyr<-length(catyear)}  #number of years of catch data}
   else  {     
      maxcatyr<-0}                #set maximum year to zero

   ### Initialise arrays for storage  ##########################################
   # Initialise a number of arrays to STORE the various parameters of          
   # interest. Each array will hold all values i.e. over all age groups,       
   # simulations years and iterations for each resolution. Initial values are  
   # all zero. The arrays are designed to look like FLQuant objects (prior to  
   # versrion 2), hence the age, year, unit, season and area dimension names   
   # and some redundancy (with unit and season). The area dimension is being   
   # used in this context as the iteration dimension                           
   # Note that with FLR version 2, the iterations should be moved and stored   
   # in the iter slot (6th dimension). This would only need minor modification 
   # in the run.r script. However, the FPRESS plotting routines would also     
   # need to be updated, hence will wait a while                               
   # Note that newbiomassarray was put in by EINAR. The intent here is to      
   # store the B4+ biomass for iCod. This actually also requires a new input   
   # column in the datafile.                                                   
    arr_dim<-c(numage,years,1,1,iterations)  
    arr_dimnames=list(age=minage:maxage,
                      year=startyear:endyear,
                       unit='unique',
                       season='all',
                       area=1:iterations)

    catchweightarray<-array(0,dim=arr_dim,dimnames=arr_dimnames)
    catcharray<-array(0,dim=arr_dim,dimnames=arr_dimnames)
    newspawnmassarray<-array(0,dim=arr_dim,dimnames=arr_dimnames)
    newbiomassarray<-array(0,dim=arr_dim,dimnames=arr_dimnames)  #EINAR - added this for iCod
    yearendstockarray<-array(0,dim=arr_dim,dimnames=arr_dimnames)
    poparray<-array(0,dim=arr_dim,dimnames=arr_dimnames)
    fishingmortalityarray<-array(0,dim=arr_dim,dimnames=arr_dimnames)
    fishingmortalitymultarray<-array(0,dim=arr_dim,dimnames=arr_dimnames)
    farray<-array(0,dim=arr_dim,dimnames=arr_dimnames)

   # the following arrays do not include age-disaggregated data and so
   # do not expand this dimension
    arr_dim_noage<-c(1,years,1,1,iterations)
    arr_dimnames_noage<-list(age=0,
                             year=startyear:endyear,
                             unit='unique',
                             season='all',
                             area=1:iterations)

    recruitsarray<-array(0,dim=arr_dim_noage,dimnames=arr_dimnames_noage)
    fbararray<-array(0,dim=arr_dim_noage,dimnames=arr_dimnames_noage)
    ftacarray<-array(0,dim=arr_dim_noage,dimnames=arr_dimnames_noage)
    ftacmultarray<-array(0,dim=arr_dim_noage,dimnames=arr_dimnames_noage)
    hcrsubarray<-array(0,dim=arr_dim_noage,dimnames=arr_dimnames_noage)
   

   ### Adjust spawning and recruit data ########################################
   #
   # Create three new vectors to hold the recruitment data offset so that
   # the recruitment value corresponds to the spawning year rather than the
   # year it entered the fishery. Depending on the value of minage, this is
   # likely to require recruitment data for years that are after the start
   # date of the projection (e.g. if the simulation starts in 2000 and 
   # minage = 2, then recruitment data will be required for at least 1998, 
   # 1999, 2000 and 2001). 
   #
   # NOTE: The variables generated here are actually not used in the
   #       subsequent run. Thus this block is effectively REDUNDANT
   
    diffxs<-max(recyear)-startyear+1  # year between start of simulation 
                                      # and final year w. availabe recruitment
    spwnyr<-seq(1,1,length=lenrecyr-max(minage,diffxs))
    spwnssb<-spwnyr
    spwnrec<-spwnyr
    for(i in 1:(lenrecyr-max(minage,diffxs))){
      spwnyr[i]<-recyear[i]
      spwnssb[i]<-rssbin[i]
      spwnrec[i]<-recr[i+minage]
    }
   SSadjust1 <- data.frame(year=spwnyr,recr=spwnrec,ssb<-spwnssb) #EINAR check

   ### The SSB-R dataset to be used estimating SSB-R parameters ################  
   # 
   # Same procedure as above, except the vectors may be of a different
   # length than those above depending on the value of datarecyear. 
   # This parameter gives the
   # maximum year in the recfile that data is to be used from in the
   # recruitment functions. This allows fictional future recruitment to be
   # entered into the recruits data file, but only the real historical data to 
   # be used in fitting parametric functions or bootstrapping. If 
   # datarecyear > max(recyear) (the oldest year in the recruits data file), 
   # then all data in the file is used in the recruitment functions. The
   # vectors spwnfnyr,spwnfnssb, spwnfnrec are used in the recruitment functions
   
   # calculate the number of years between the last year of recruitment data 
   # and the final year that is to be used in the simulations
    diffxt<-max(recyear)-datarecyear+1  
    spwnfnyr<-seq(1,1,length=lenrecyr-max(minage,diffxt))
    spwnfnssb<-spwnfnyr
    spwnfnrec<-spwnfnyr
    for(i in 1:(lenrecyr-max(minage,diffxt))){
      spwnfnyr[i]<-recyear[i]
      spwnfnssb[i]<-rssbin[i]
      spwnfnrec[i]<-recr[i+minage]
    }
   SSadjust2 <- data.frame(year=spwnfnyr,recr=spwnfnrec,ssb<-spwnfnssb) #Einar check   









#
# END: INITIALISATION
##############################################################################################
   
   











################################################################################
#    START OF MAIN BODY                                                        #
################################################################################
 
 print(stockname)
 print(Sys.time())
 startdate<-as.POSIXlt(Sys.time(),Sys.timezone())    # Store start time
 
 ###############################################################################
 #   Loop over range of of F or TAC values, res is the counter variable        #
 ###############################################################################
   for(res in 0:resolution) {

      if (debug==1) {cat("res=",res,"\n")}

      #calculate the appropriate FTAC value for this resolution
      if (resolution>0) {      
         ftac<-((varmax-varmin)*res/resolution)+varmin               
         if(ftac==0){ftac<-0.0001}     #ensure we don't proceed with a 0 value      
         ftac2 <- ftac
         
         # calculate the percentage of the simulation that is
         # complete for reporting purpose
         percent<-round((res/(resolution+1))*100,digits=2)      
         if (variable==1) {
	         cat("fval = ",ftac," ",percent,"% complete","\n",sep="")
         } else {
	         cat("tacval = ",ftac," ",percent,"% complete","\n",sep="")
         }
      }
      flush.console()    #update the console to ouput above messages
  ##############################################################################
  #   Main iterative loop, iter is the counter variable                        #
  ##############################################################################

  for(iter in 1:iterations){

	 #if the resolution is zero then the simulation is running for a single 
	 #TAC or F value. In this case report progress on basis of the number of iterations
	 #completed. Issue report every 10%
	 if (resolution == 0) {
	    percent <- 100*iter/iterations
	    if ((percent%%10) == 0) {
	       cat(percent,"% complete","\n",sep="")
	    }
	 }

	 flush.console()

	 if (debug==1) {cat("iter=",iter,"\n")}
   #############################################################################
   #  Year loop, year is the counter variable                                  #
   #############################################################################

    for(year in 1:years){    
    	if (debug==1) {cat("year=",year,"\n")}
	    simyear<-year+startyear-1           #calculate the current simulation year
	    if (debug==1) {cat("A&M..")}
	    
















    ############################################################################
    #  ASSESSMENT, MANAGEMENT AND F/TAC to be applied
    #
    #  1a. Assessment: The function (see assessment.r) calculates new 
    #      applying user specified noise (cv) and bias to existing values
    #      of bio, ssb and/or fbar. This effectively emulates uncertainty
    #      in stock assessment.
    #      Output: New bio, ssb and f
    #  1b. Management: The function (see managment.r) calculates the 
    #      ftac multiplier (ftacmult) based on a user specified HCR given
    #      an uncertain assessment
    #      Output: New ftacmult
    #  2   F or TAC to be applied this year (if not historical values)  
    #      2.a) If not historical values
    #      2.b) If historical values
    #      Output: New Fbar or TAC (ftac)
    #
    #  Note that the estimates are correspond to the following years
    #    relative to the assessment year y
    #     SSBy-1
    #     BIOy-1
    #     F?
    
    # 1. Assessment model & Managment ##########################################
    #
     if((year-assessdelay)>0){
         assres<-assessment(bio,ssb,
	                          fbar,
                            ssbassessbias,
                            ssbassesscv,
                            fbarassessbias,
                            fbarassesscv)
         bio <- assres[1]        	       
         ssb<-assres[2]   
         fbar<-assres[3]  

     
         man_ret<-management(bio,ssb,
                             fbar,
                             ftac,
                             year,
                             years,
                             assessdelay,
                             hcrperiod,
                             hcrrule,
                             hcrchange,
                             ssbhcr,
                             oldftacmult,
                             fbarhcr,
                             ssbtest1,
                             ssbtest2,
                             mintac)	       
         ftacmult<-man_ret[1]    	       
         hcrsub<-man_ret[2]      #...(not currently used)
	   } else {
         ftacmult<-1             # no change is effected
         hcrsub<-0	    
     }

     ftacmultarray[1,year,1,1,iter]<-ftacmult  # permanent storage
     hcrsubarray[1,year,1,1,iter]<-hcrsub      # permanent storage














    ### 2a. F or TAC to be applied this year (if not historical values) ########
    #
    #  Here the ftac parameter gets modified by the ftacmult parameter which
    #  came out from the management function. Note that the origftac is a
    #  placeholder for the ftac that is set in place at the beginning of
    #  each resolution-loop.
    #  The outputted ftac value has the following meaning depending on the
    #  setting of the parameter 'variable':
    #    variable=1: Fbar in F-based simulation
    #    variable=0: TAC in TAC based simulation
    #    variable=2: harvest rate in TAC based simulation
    #
    #  output: ftac                                              
    #
      origftac<-ftac               # save the original value
     # Adjust the ftac according the the management rule (ftacmult)
      if ((variable==0) & (ftacmult*ftac < mintac)) ftac=mintac 
      else {ftac<-ftacmult*ftac}
      
      if (debug==1) {cat("Init..")}
      tmp <- ftac                    # EINAR: Temporary placeholder
     # HARDWIRE - iCod HCR  ####################################################      
      if(variable==2 & year>1) {
         if (hcrchange == 0) {
             ftac<-max(ftac*bio,mintac)
             } else {
         ftac<-max((ftac*bio+ftacarray[1,year-1,1,1,iter])/2,mintac)}}
     if (year> 1) myText <- paste(year,"origftac=",origftac,"ftacmult=",round(ftacmult,3),"ftac1=",round(tmp,3),"ftac2=",round(ftac,0),"hr=",round(ftac/bio,2))

    # 2b. F or TAC to be applied this year (if historical values) ############################
    #
    # Historical F og Yield values are in most cases needed , at least for the first year(s).
		# One may also be intersted in running "hindcasting" from some historical starting year.
		# Here the appropriate yield or fbar from the historical dataset are located and a user
		# defined (histcatchcv) allocated ???? if historical values are used for catch then the
		# bias and cv ssociated with F/TAC will be set to 1 and 0 respectively????
    #
    # Output: New Fbar or TAC (ftac)
    #
	    newvarcv<-varcv
	    newvarbias<-varbias

	    if ((histcatch==1) & (simyear<=maxcatyr)) {
          #identify the relevant year
          index<-0
          for (i in 1:lencatyr) {
		        if(catyear[i]==simyear){index<-i}}
          #now perform the random draw
          #F controlled fishery
            if (variable==1) {
             ftac<--1
             #randomise
             while(ftac<0){ftac<-rnorm(1,cfbar[index],cfbar[index]*histcatchcv)}
             #reset cv, bias parameters
             newvarcv<-0
             newvarbias<-1
            }
	        #TAC controlled fishery
	          if (variable %in% c(0,2)) {                # EINAR - iCod adaptation
             ftac<--1
             #randomise
             while(ftac<0){ftac<-rnorm(1,ccatch[index],ccatch[index]*histcatchcv)}
             #reset cv, bias parameters
             newvarcv<-0
             newvarbias<-1
	          }
	    }
	    
	    #update the ftac array
	    ftacarray[1,year,1,1,iter]<-ftac
      #print(ftac)
	    if (debug==1) {cat("Fmult..")}

		#
    # END: ASSESSMENT, MANAGEMENT AND F/TAC to be applied
    ############################################################################
    #  UPDATING AGE-BASED PARAMETERS
    # 1. Initialize values
		# 2. Update the Nay matrix
    #    2.a) Update the Nay matrix
    #    2.b) Update the recruits (overrides the youngest age in step 1.a)
    # 3. Update cWay, sWay, MATay, cSay, dSay and May
    # 4. Update Fay
    #    4.a) F-based fisheries
    #    4.b) TAC-based fisheries

    ### 1. Initialise age vectors for start of year ############################
		#
    # If in the first year of the simulation, used the populations as specified
    # in the input datafile. If past the first year of the simulation, use the 
    # population simulated at the end of the previous year. 
    # Thus, popcv (which conventionally would be labelled as Nay contains the
    # true population numbers in the assessment year (year y). Note that this
    # is different from the ssb, bio and f above, to which cv and assessment
    # bias have been applied to  
    #
    # There may be some redunance in usage here, revisit that stuff later
      age<-initage                       #age class  EINAR - looks redundant
      if (year>1) {popint<-newyearplus1} else {popint<-initpopint}	    
	    popcv<-initpopcv                   #population cv	    
	    spwnweightint<-initspwnweightint   #spawning weight	    
	    spwnweightcv <-initspwnweightcv    #spawning weight cv	    
	    catweightint<-initcatweightint     #catch weight
	    catweightcv<-initcatweightcv       #catch weight cv    
	    matureint<-initmatureint           #maturity	    
	    maturecv<-initmaturecv             #maturity cv	    
	    fint<-initfint                     #fishing mortality	    
	    fcv<-initfcv                       #fishing mortality cv	    
	    fprop<-initfprop                   #prop. of fishing mor. prior to spawning	    
	    disfint<-initdisfint               #discard mortality	    
	    disfcv<-initdisfcv                 #discard mortality cv	    
	    mint<-initmint                     #natural mortality	    
	    mcv<-initmcv                       #natural mortality cv	    
	    mprop<-initmprop                   #prop. of natural mort. before spawning


    ### 2a. Update the Nay matrix (all except recruits)  #######################
    # Pop is assigned the Nay values. These numbers could either come from the
    # end of the previous year (former year-loop or if this is the first year,
    # from the input file.
    # Adding noise / stochasticity to account for environmental/operational
    # variability
    # Initial population (randomised in first year of projection only).
    # If year>1 the randomization has taken place at the end of the previous
    # year loop.
	  #  
      pop<-popint 
      popintsd<-(popcv*popint)
      if(year==1){ 
	       pop <- -popint
	       #keep drawing until a positive result is obtained
	       while(min(pop)<0){
            for(i in 1:numage){pop[i]<-rnorm(1,popint[i],popintsd[i])}
	       }
	    }

    ### 2b. Updating the Nay matrix - this year recruits #######################
    # Recruitments will only be supplied here if minage>0. When minage=0
    # the fish enter the fishery immediately after spawning. These cases
    # are dealt with in a later code (once SSBy has been calculated)
    #
    # Here (when minage>0) incoming recruits can come from one of two sources:
    #   1. The historical recruit file
    #      Since these values arise from ssb values prior to the execution
    #      period of the program and more importantly because the estimates
    #      may be based on actual measurements, the recruitment values are 
    #      stored in the historical recruitment file. An account must be taken
    #      of the age of recruitment in order to correctly locate the right
    #      recruit relative to the simulation year. Once locatated an 
    #      historical recruitment cv value is also applied.
    #      As an example, if minage=3 and the model starts execution in 2000, 
    #      the first year that the model can calculate recruitment for is 2003.
    #      Thus historical values are required for 2000, 2001 and 2002      
    #   2. Recruits generated internally from a stock-recruit function. In that
    #      case the values have already been generated in previous years inside
    #      the loop and stored in the recruitsarray
    #
    # Output: 
    #  
      if (debug==1) {cat("Rec after spawn..")}

	    if (minage>0) {
       # 1. Historical recruit values, stored in the input files        
       if (simyear-minage <= maxrecyr) {
             for (i in 1:lenrecyr) {if (recyear[i]==simyear-minage) {index<-i}}
             frec<--1
             while(frec<0){frec<-rnorm(1,recr[index],recr[index]*histreccv)}
             recruitsarray[1,year,1,1,iter]<-frec
       }
       # 2. Recruit values already generated internally in prior year loops        
       else {frec<-as.numeric(recruitsarray[1,(year-minage),1,1,iter])}
      
		  fishrecruited<-frec      
      }  # end if(minage>0)
      	    
	    if(minage>0){pop[1]<-fishrecruited}

    ### 3. Updating other age parameters (sWay, cWay, MATay, cSay, dSay, May #################
	  # The objective here is to generate numbers that are equivalent to the real numbers
		# "observed" numbers (remember, we are continuously predicting in this simulation
		# framework. These new numbers are then used to calculate the actual stock size, as one
		# would have as measurements it in the beginning of the next year loop (end of this years
		# loop). What is done here is just to supply new random numbers to the original input,
		# not taking into account correlations among ages. Note, the randomization process is
		# fully independent across age groups. Effectively this may mean that the sum or the
		# agerage of this white noise will be zero. E.g. since SSB is the sumproduct numbers,
		# weight and maturity, the white noise within each of these vectors may cancel each
    # other out when it comes to calcuating SSB. Remedy: Call Höski :-)
    # Additional thing - should store all these values and export
    #                  - the stuff below calls for a seperate function
    #                  - like myWhile(XXXint,XXXvn)
     
     #Spawning weight
	    spwnweight<--spwnweightint
	    spwnweightsd<-spwnweightcv*spwnweightint 
	    while(min(spwnweight)<0){
	       for(i in 1:numage){
		        spwnweight[i]<-rnorm(1,spwnweightint[i],spwnweightsd[i])}}

	    #Catch weight
	     catweight<--catweightint
	     catweightsd<-catweightcv*catweightint 
	     while(min(catweight)<0){
			    for(i in 1:numage){
		        catweight[i]<-rnorm(1,catweightint[i],catweightsd[i])}}
	    
	    #Maturity
	     mature<--matureint
	     maturesd<-maturecv*matureint
	      while(min(mature)<0){
	       for(i in 1:numage){
		        mature[i]<-min(rnorm(1,matureint[i],maturesd[i]),1)}}
	    
	    #Fishing mortality  -  more properly referred to as selection pattern
	     f<--fint
	     fsd<-fcv*fint      
	     while(min(f)<0){ 
	       for(i in 1:numage){
		        f[i]<-rnorm(1,fint[i],fsd[i])}}

	    #Discard mortality
	     disf<--disfint
	     disfsd<-disfcv*disfint       
	     while(min(disf)<0){ 
	       for(i in 1:numage){
		        disf[i]<-rnorm(1,disfint[i],disfsd[i])}}  # EINAR - BUG, removed fmult
                  
	    #Natural mortality
	     m<--mint
	     msd<-mcv*mint
	     while(min(m)<0){
	       for(i in 1:numage){
		        m[i]<-rnorm(1,mint[i],msd[i])}}

	    # New bar - calculated by taking the mean of f over the age groups
      #           defined by the parameters fbarmin and fbarmax
	    newfbar<-mean(f[(fbarmin-minage+1):(fbarmax-minage+1)])
      if (debug==1) {cat("ftac..")}


		### 4a. Calculate Fay if F-based simulation  #############################################
    #   
    # Apply F multiplier to F vectors (only required if simulation is based on f). The
		# specified level of F given by ftac is altered by possible bias (overfishing) given
		# by varbias and then randomised by drawing from a Normal distribution. The randomised
		# value of F (freq) is the required fishing mortality for this year. A multiplier, fmult,
		# is calculated from newfbar so that when multiplied by the current F vector it will give
		# the required value of freq. Finally, the F vector f is multiplied by this multiplier
		# along with the discard F vector disf. In reality, discard F may not change in the same
		# way as F when catches are reduced.
    #      
	    if(variable==1){
	       fnewval <- ftac * newvarbias # EINAR- replaced newfbias with newvarbias	       
	       nf<--1        
	       while(nf<0){nf<-rnorm(1,fnewval,fnewval*newvarcv)}   #randomise fnewval 	       
	       freq<-nf                           #this is the required f vector
	       fmult<-freq/newfbar                #calculate f multiplier
         f<-fmult*f                         #apply multiplier to f
	       disf<-disf*fmult                   #apply multiplier to discard f
	    }



    ### 4a. Calculate Fay if TAC-based simulation  ###########################################
    #
    # If using a TAC, calculate the appropriate F multiplier. The specifie level of TAC given
		# by FTAC is altered by possible bias (overfishing) given by varbias and then randomised
		# (this occurs each year) by drawing from a Normal distribution. The randomised value of
		# TAC given by tac is the required catch for this year. Function ffactor is then used to
		# calculate an F multiplier, ffac, that when applied to the current F vector f, will
		# produce the required catch equal to the TAC (so that fishing mortality in the simulation
		# is always actually calculated using F even when the virtual fishery uses TAC). Finally,
	  #the F vector f is multiplied by this multiplier along with the discard F vector disf.

	    if(variable %in% c(0,2)){                       # EINAR - iCod adaptation
	       tacval<-ftac*newvarbias                          #apply bias      
	       ntac<--1                                         
	       while(ntac<0){ntac<-rnorm(1,tacval,tacval*newvarcv)}    #randomise
	       tac<-ntac                                        #the requied tac vector
	       ffac<-ffactor(tac,pop,f,disf,catweight,m,numage) #calculate f vector
	       f<-f*ffac                                        #apply multipler to f
	       disf<-disf*ffac                                  #apply multiplier to discard f
	       fmult<-ffac
	    }



	  #Update fishing mortality and fishing mortality multiplier arrays
	    fishingmortalityarray[,year,1,1,iter]<-f
	    fishingmortalitymultarray[,year,1,1,iter]<-fmult
    
    #
    # END: UPDATING AGE-BASED PARAMETERS
    ############################################################################






    ############################################################################
	  # POPULATION DYNAMICS
    #
    # The steps are:
    #   1. Calculate population size and hence ssb at spawning time
    #   2. Estimates recruitment based on a user specified recruitment model.
    #    2.1 Obtain new recruits from a model (may or may not be used in the
    #        next step.
    #    2.1 Decistion algorithm that speciefies
    #        a) Should recruitement be entered into the population
    #           immediately (only needed if fishing occurs on age 0)
    #        b) Should one obtain recruitment be obtained from historical
    #           data or should on simulate recruitment based on one
    #           of the user specifed recruitment above (alrady done in
    #           step 2.1)
    #   3. Calculate the catch annual catch
    #   4. Calculate the population size at the end of the simulation year

    ### 1. SSB - based on population numbers at spawning time ##################
	    if (debug==1) {cat("Dyn at spawn..")}       

      fbef<-(f+disf)*fprop            # Fishing mortality prior to spawning
      faft<-(f+disf)*(1-fprop)        # Fishing mortality after spawning
	    mbef<-m*mprop                   # Natural mortality prior to spawning
	    maft<-m-mbef                    # Natural mortality after spawning
	    if (debug==1) {cat("fbef,mbef =",fbef,mbef,"..")}
	    newstock<-(pop*exp(-mbef-fbef)) # Population numbers at spawning time
	    newspawnpop<-(newstock*mature)  # Mature population number at spawn. time      
	    newspawnmass<-newspawnpop*spwnweight # Mature biomass at spawn. time
	    newspawnmassarray[,year,1,1,iter]<-newspawnmass  # store biomass
	    ssb<-sum(newspawnmass)
 
    ### 2. RECRUITMENT #########################################################
	    if (debug==1) {cat("Recruit..")}        

      # 2.1 Recruitment model
	    recruitsnew <- switch(rec+1,
                            recruit0(recmean),
                            recruit1(recmean,reccv),
                            recruit2(spwnfnyr,spwnfnrec),
                            recruit3(ssb,spwnfnyr,spwnfnrec,spwnfnssb,ssbcut),
                            recruit4(ssb,spwnfnrec,spwnfnssb),
                            recruit5(ssb,spwnfnrec,spwnfnssb),
                            recruit6(ssb,ssbcut,recmean,seggrad),
                            recruit7(ssb,ssbcut,recmean,seggrad,reccv),
                            recruit8(ssb,reccv))

	    # 2.2. Entering recruitment or store for later retrieval
      #
      #   If the minimum age is zero then the fish enter the fishery from age 0 
	    if(minage==0){
          if(simyear > maxrecyr){
            # If the current simulation year is greater than the oldest year in
            # the recruitment data file, then set 
            # the recruitment (frec) = recruitsnew
            frec<-recruitsnew
          } else {
            #if the current simulation year is contained in the recruitment
            # data file then the expected recruitment is set to the 
            # corresponding value given in the file
            for(i in 1:lenrecyr){
              if(recyear[i]==simyear){num<-i}
            }
            #randomise the number of recruits
            frec<--1
            while(frec<0){frec<-rnorm(1,recr[num],recr[num]*histreccv)}
          }
          #assign the new recruits to the first population vector element
          newstock[1]<-frec 
          yearrecruits<-frec
          #write data to local recruitsarray
          recruitsarray[1,year,1,1,iter]<-yearrecruits
	    } else {
          # the value recruitsnew applies to a future year write this into
          # a future slot in the recruitsarray (provided there is one -
          # no point in writing beyond end of simulation period)
          if ((year+minage) <= years) {
            recruitsarray[1,year+minage,1,1,iter]<-recruitsnew
          }
	    }
	    if (debug==1) {cat("Removing Catch..")}

	  ### 3. TAKE THE CATCH ######################################################
	    fbarz<-c()
	    for(i in (fbarmin-minage+1):(fbarmax-minage+1)){
	       fbarz<-c(fbarz,f[i])
	    }
      fbar<-mean(fbarz)
      #update local array
	    fbararray[1,year,1,1,iter]<-fbar
      #calculate the catch in number
	    catch<-(pop*f/(f+disf+m+0.00001)*(1-exp(-f-disf-m)))
      #calculate the catch weight
	    catchwght<-catch*catweight
      #update local array
	    catchweightarray[,year,1,1,iter]<-catchwght
      if (debug==1) {cat("Dyn After Spawn\n")}
      
      if(year>1 & debug==2) {print(paste(myText,"fbar=",round(fbar,2)))}

		### 4. POPULATION SIZE IN THE END OF THE YEAR ##############################
	    
      # calculate the year end population by applying the fishing and
      # natural mortality that occurs after spawning
	    yearendstock<-newstock*exp(-maft-faft)
      
	    #update local arrays
	    yearendstockarray[,year,1,1,iter]<-yearendstock
	    poparray[,year,1,1,iter]<-pop
	    catcharray[,year,1,1,iter]<-catch
	    farray[,year,1,1,iter]<-f
      
	    #plus group
	    yearplus1<-0
	    for(i in 1:(numage-2)){
	       yearplus1<-c(yearplus1,yearendstock[i])
	    }
      
	    #add on the plus group to the oldest age (last spaces)
	    yearplus1<-c(yearplus1, yearendstock[numage-1]+yearendstock[numage])
      #EINAR: Calculate the new bio
      newbio <- (yearplus1*c(0,0,0,rep(1,11)))
      newbiomass <- newbio*catweight
      #update the local array with the new biomass for this iteration/year
	    newbiomassarray[,year,1,1,iter]<-newbiomass
	    bio <- sum(newbiomass)
	    #save vals in temp vars for initialisation of population in next year
	    newyearplus1<-yearplus1

	    # Note that the output has original input variances
      # NOT new variances calculated from the data
    
	    ftac<-origftac
     
	 }    
	 ###########################################################
	 #end of year loop##########################################
	 ###########################################################

      }   
      ##########################################################
      #end of main iterative loop###############################
      ##########################################################
 






      #Save data
      #Create FLQuant objects
      #FLQuant() is the creator function for FLQuant objects
      CatchWeight<-FLQuant(catchweightarray,units='Kgs')
      NewSpawnMass<-FLQuant(newspawnmassarray,units='Kgs')
      FBar<-FLQuant(fbararray,units='F')
      Recruits<-FLQuant(recruitsarray,units='000s')
      YearEndStock<-FLQuant(yearendstockarray,units='Kgs')
      Pop<-FLQuant(poparray,units='Kgs')
      Catch<-FLQuant(catcharray,units='Kgs')
      FishingMortality<-FLQuant(fishingmortalityarray,units='F')
      FishingMortalityMult<-FLQuant(fishingmortalitymultarray,units='F')
      F<-FLQuant(farray,units='F')
      FTac<-FLQuant(ftacarray,units='ftac')
      FTacMult<-FLQuant(ftacmultarray,units='mult')

      #save specified objects
      if (substr(outdata.path,nchar(outdata.path),nchar(outdata.path))=="\\") {
	 outfile<-paste(outdata.path,FLRfiles[res+1],sep="") } else
      {
	 outfile<-paste(outdata.path,"\\",FLRfiles[res+1],sep="")
      }

      save(list=savedobjs,file=outfile)

   }     
   ############################################################
   #end of resolution loop#####################################
   ############################################################

   #some end logging
   print(Sys.time())
   #calculate the end time and the difference with the starttime and
   #print duration of run to screen
   enddate<-as.POSIXlt(Sys.time(),Sys.timezone())
   diff<-difftime(enddate,startdate,tz="GMT",units="secs")
   cat("Execution Time:",diff[[1]]," secs", "\n")

   #restore working directory
   setwd(currwd)

# EOF
}

Adaptations of FPRESS to the iCod HCR evaluation

Background

As is always the case, the iCod dynamics and HCR has some specifics that may not be available in any off-the-shelf frameworks. So far the following have been identified, with regards to the generic FPRESS:

HCR rule and inter-annual constraint

The key controlling variables in regards to the fisheries in FPRESS are: