mareframe / mfdbatlantis

MareFrame Atlantis routines
GNU General Public License v3.0
1 stars 2 forks source link

Getting age data with atlantis_fisheries_catch() #6

Open pfrater opened 7 years ago

pfrater commented 7 years ago

Is it possible to get the number caught per age group using atlantis_fisheries_catch()? I've been informed that this information is in the .nc file used by this function. It would be really useful to have this for setting up mock commercial catch sampling for use in gadget likelihoods.

lentinj commented 7 years ago

Yep, there's also "Catch of age class 6 Gadus morhua" (tonnes) for the taking. I'm not sure if this is all FCD6 caught by any predator/fishery, or everything that FCD6 had consumed.

Assuming the former, then you could use the relative quantities to scale the total output, but that doesn't sound very realistic, since it will be combining several predator/fisheries habits. Using a suitability vector like in atlantis_tracer_survey_select to model the gear selectivity seems more reasonable. Or can you think of something more sensible to do?

pfrater commented 7 years ago

I think using something like atlantis_tracer_survey_select() would do just fine. I really only need the landings as they currently are, but also parsed out to age, similar to the output of atlantis_fg_tracer(). I'm assuming you could probably just recycle the code from that function, but haven't looked to make sure.

lentinj commented 7 years ago

I don't think atlantis_tracer_survey_select() is directly useful, since it's scaling already divided data with a selectivity vector. A function to break up the total tonnage into buckets based on a selectivity vector would be pretty easy though.

However we could be a bit more accurate (I think) by taking the tracer values into account too, for example use atlantis_fg_tracer/atlantis_tracer_add_lengthgroups/atlantis_tracer_survey_select as with a survey, then scale the end result by the tonnage caught. It's not necessarily a realistic model of how a fleet works, but at least stops the results from saying nonexistent fish were caught (because there weren't any of that size in the box, e.g.). Sound good, or getting carried away?

Finally it might be worth approaching Beth to see if we can get more detail out of Atlantis, we shouldn't need to guess here, Atlantis will know. Me/Chris/Erla did talk about this at some point, but I don't think we got as far as e-mailing Beth.

pfrater commented 7 years ago

I think something like this should work. This just pulls the number of fish caught from each age class, which is found in the OutCATCH.nc file. We can then pair this with atlantis_tracer_add_lengthgroups() and atlantis_tracer_survey_select() to get an index for how many fish of each age class/length group are caught each year/month/area/etc.

The following only works for one species and one gear type at a time. I just haven't taken the time to generalize it.

Edited on Nov. 2 to update code.

commCatchAges <- function (adir, area_data, fg_group, fishery) 
{
    nc_out <- ncdf4::nc_open(attr(adir, "nc_catch"))
    age_vars <- list_nc_variables(nc_out, paste0(fg_group$Name, '[0-9]'))
    age_vars <- grep('Catch', age_vars, value=T)
    catch_by_age <- fetch_nc_variables(nc_out, age_vars)
    ann_area_age_catch <- apply(catch_by_age, 3, function(x) as.numeric(x))
    dims <- expand.grid(area = as.character(area_data$name), 
                        time = nc_out$dim$t$vals, 
                        functional_group = fg_group$GroupCode,
                        stringsAsFactors = TRUE)
    df_base <- data.frame(area = dims$area, time = dims$time, 
                         year = mfdbatlantis:::atlantis_time_to_years(dims$time) + 
                             attr(adir, "start_year"), 
                         month = mfdbatlantis:::atlantis_time_to_months(dims$time), 
                         fishery = fishery$Code, 
                         functional_group = dims$functional_group,
                         stringsAsFactors = TRUE)
    df_out <- do.call('rbind', apply(ann_area_age_catch, 2, FUN=function(x) {
                    temp <- df_base;
                    temp$count <- x;
                    return(temp);
    }))
    rownames(df_out) <- 1:nrow(df_out)
    cohorts <- as.numeric(as.character(fg_group$NumCohorts))
    age_class_size <- as.numeric(as.character(fg_group$NumAgeClassSize))
    df_out$cohort <- sort(rep(1:cohorts, nrow(df_base)))
    df_out$age <- (df_out$cohort * age_class_size) - (age_class_size%/%2 + 1)
}