gadget-framework / mfdb

Data management for fisheries model creation
http://gadget-framework.github.io/mfdb/
4 stars 4 forks source link

Import Atlantis output #20

Closed lentinj closed 8 years ago

lentinj commented 8 years ago

Interpret the output of an Atlantis run and import into MFDB.

lentinj commented 8 years ago

@bthe Do you have any preferences for data to import at this stage? Ages/lengths/weights seem the obvious choice.

bthe commented 8 years ago

This sounds good, but also by stock/maturity.

lentinj commented 8 years ago

@cddesja Is there any concept of Maturity in Atlantis, or would we have to derive from Age/Weight?

Stocks we would define outside Atlantis too, but that's no different to normal, if I remember correctly.

cddesja commented 8 years ago

There is a concept of maturity in Atlantis. Each age class has a proportion of that age class that is considered mature. This can be obtained from the biology model. Each age class will have the same age and weight and each functional group consists of a single stock (but may consist of multiple species).

lentinj commented 8 years ago

I see FLAG_AGE_MAT / "First mature age class", which presumably tells me that Cod2 onwards are mature? Doesn't sound quite the same as what you describe.

cddesja commented 8 years ago

SPP_AGE_MAT tells you the first mature age class. So for FCD_AGE_MAT (Cod), this is 2. But age class of 2 doesn't mean 2 years, it means ages 3 - 4. SPP_AgeClassSize tells you how many years are in an age class (where you would substitute SPP for the functional group name (e.g. FCD). This is because the length of an age class depends on the longevity of a species.

I meant to say "proportion of the population (per age) spawning" above. These are the FSPB_SPP flag. So for FCD this is a 1d array with a length of 10.

FSPB_FCD 10
0 0.004137931 0.12775861 0.579644172 0.820862069 0.95793103 0.990517241 1 1 1

I am guessing you could assume, @bthe tell me if this is wrong, that if you aren't spawning you're not really mature.

lentinj commented 8 years ago

Aha, this makes sense. I'm looking at the output XML files rather than the input PRM file, but it's easy enough to find where the equivalents live.

Re: not spawning implying immature, surely it's more a question of what Atlantis implements (e.g. if it models some environmental pressure that stops fish spawning), than whether it's a reasonable guess in reality?

bthe commented 8 years ago

Not much of a biologist but this seems to be on the right track. I guess that the population per age group spawning indicates the potential spawners when the conditions are "right".

cddesja commented 8 years ago

This flag is literally the proportion of each age class that is always spawning each year. This is static and gets multiplied by the amount of spawn produced per individual times the number of individuals in an age class. What can change is the amount of spawn produced by one individual as this is a function of their fat (i.e. reserve weight, RN). If they are too thin, they won't reproduce. The amount of spawn produced by an individual will be 0 and that flag will be multiplied by 0.

So, it probably isn't a good idea to use that flag.

On second thought, SPP_AGE_MAT is the right flag to use for determining if they are juvenile or not. The model uses this flag for determining if they are juvenile or not for various processes (e.g. migration). There is also min_li_mat_SPP which will determine if an age class is large enough to spawn. At present, this is set to 0, so individuals in an age class older than the year set by the SPP_AGE_MAT are all capable of spawning if they are fat enough and the proportion that will spawn is determined by the aforementioned flag.

tl;dr - Use SPP_AGE_MAT

bthe commented 8 years ago

I assume SPP_AGE_MAT is the age when they become mature?

cddesja commented 8 years ago

Yeah, it's the first mature age class.

cddesja commented 8 years ago

Oh and @lentinj, my original comment about "each age class has a proportion of that age class that is considered mature" that should have been "each age class has proportion of that age class that is spawning".

lentinj commented 8 years ago

In case you're curious, you can see how far I've got here: https://github.com/mareframe/mfdb/blob/import-atlantis-output-20/demo/example-atlantis.R

lentinj commented 8 years ago

Today's question: Time/Calendar handling.

cddesja commented 8 years ago

Good questions.

  1. For the startyear, there is nowhere in Atlantis that you tell Atlantis what year you start. So the modeller needs to to tell create_vat() what year the model run started. Atlantis by default starts on day 0 which is January 1 of year whatever.
  2. An Atlantis year is always 365 days. There are no leap years in Atlantis.
  3. You would need to set toutinc/toutfinc to a different day in the run.prm file if you want monthly output rather than yearly output. So you would set the following in run.prm
toutinc 30 day
toutfinc 30 day

This can easily be done but must be done at the time of the model run. Would @bthe want that?

I'll take a look at your R stuff today. You are quite fast :)

bthe commented 8 years ago

Regarding the time resolution, I would rather have the output by month than year, and let the db-system handle the aggregations. Typically Gadget models have quarterly time-steps but this can vary depending on the application.

cddesja commented 8 years ago

OK, I forwarded that onto Erla.

lentinj commented 8 years ago

So if toutinc == "30 day", do you assume that years are 360 days long instead? I'm guessing that Atlantis will spit out results at an interval of 60 * 60 * 24 * 30 seconds.

However, it seems to know about seasons (for which I can't see a definition for), but it seems a reasonable guess that it does 365 / 4. In which will the monthly output drift out of sync with the seasons?

It'd be worth checking to see if there's a toutinc == "1 month" option that doesn't get ensnared by this.

cddesja commented 8 years ago

Years are 365. A month doesn't really mean anything in Atlantis. There are 4 seasons but the 4 seasons are not the same length. If you get 30 day summary output you will lose 5 days every year.

lentinj commented 8 years ago

Is toutinc == "2628000 second" or "730 hour" an option instead of "30 day"? I'm not sure we care so much about time of day.

cddesja commented 8 years ago

I don't believe so. I will check the source code but I think this stuff is just in days. While Atlantis can solve multiple times in a day, I don't believe it can output by second or hour. But I will check tomorrow.

cddesja commented 8 years ago

So it looks like you can specify by the second, hour, or day. The amount of output will be limited by what dt is set to. dt is the length of a time step. The model is set to solve every 12 hours in order to accommodate diurnal activities and plankton. So you can get:

toutinc toutfinc tsumout

output in either seconds, hour, or day. Now, I would imagine everyone who uses Atlantis just uses day (at it's the default unit for these things), so it's not inconceivable that using second or hour could result in unwanted bugs. But it should, in theory, be fine to use second or hour instead of day.

lentinj commented 8 years ago

Yeah, I can imagine if your hour unit isn't a multiple of dt/12 hours, that could result in hilarity.

Okay, I think I know how to do everything to drive mfdb_import_survey. Hopefully I've understood the structural Nitrogen --> length/weight conversions correctly. The only remaining questions are think are if there's anything we can fill in for sex (I don't think so?), and how Box(n) areas map to ICES gridcells. I presume that's what they are, but is there a mapping for ICES style names anywhere? Or would it be possible to give their correct name in the model?

Then it's on to fisheries data, I guess.

cddesja commented 8 years ago

Sex - no. ICES gridcells - No idea. Maybe @bthe knows how the dst2 rectangles map onto the ICES gridcells.

Structural weight is in mg N. To go to wet weight (in mg) from structural weight: wet weight (mg) = Structural Weight (mg N) * 416.1

The 416.1 comes from 3.65 (str wt -> ash free dry wt) * 5.7 (afdw -> carbon wt) * 20 (carbon wt -> wet wt).

Then you just need to convert mg to g.

lentinj commented 8 years ago

I think DST2 rectangles were the same thing, although possibly with a different naming convention.

However, atlantis_L93.bgm just calls the areas "Box1", versus things like 1021 which is what I'd expect. Is there a mapping somewhere to use? Or am I looking in the wrong place?

cddesja commented 8 years ago

OK, well there are a few options.

1) I could share with you a map with the Box IDs and if we had a similar map with the ICES rectangle, we could map them that way.

atlantis_boxes_numbers

2) In the bgm file, there are the all vertices of each box (e.g. all those lines in the file for box1.vert, box2.vert, etc) in the Lambert 1993 projection (that's the projection +proj= ... gunk at the top of the file). If we know the vertices of the ICES rectangle in the Lambert 1993 projection then we could map them that way. I assume they are probably just in WGS84 (i.e. just plain lat/long).

3) In the bgm file, there is a point inside each box (e.g. box1.inside), if we knew the ICES rectangles, again provided they are in Lambert 1993 projection, we could see if that point was within the ICES rectangle and then assign that Atlantis box to that ICES rectangle.

lentinj commented 8 years ago

I think it's up to @bthe really, if it's not a ~trivial mapping I'm not convinced it's worth the effort though. Probably worth just leaving

On a different note, Predator / Prey relationships. The greatest level of detail I can find (OutputNoFishDietCheck.txt) is consumption per second (I think?) by predator species, predator ageClass & prey species.

Ultimately gadget wants ratio of matching predator samples with matching prey samples (e.g. species at various lengths) in stomachs. I guess you could spread the total consumption based on the abundance of the predator ageClasses, but feels like too much guesswork.

Is there more data somewhere, and/or is it worth the effort?

bthe commented 8 years ago

The spatial division illustrated in @cddesja figure is what is called a subdivision in mfdb::reitamapping. That should be a trivial mapping, if more detail is needed I would suggest to assign the data to a random box within the subdivision.

cddesja commented 8 years ago

That is probably your best bet and yes that is suppose to be number of individuals consumed per individual or, in the case of a biomass pool (e.g. an invert), mg N consumed per second. There are some other files that you might take a look at that look at specific predator induced mortality. But I haven't figured out what the units are and the numbers look very strange.

lentinj commented 8 years ago

@bthe Would that be enough to work with? i.e. just getting ratio of stomachs containing a species, rather than species-at-length or anything else?

bthe commented 8 years ago

Yes, that would be sufficient, but more detail is always better;)

lentinj commented 8 years ago

Coming back to this, individuals consumed / sec will need a fair bit of interpretation anyway. Can we assume that any species ingests at a fixed rate (this doesn't seem something that Atlantis will tell us), so e.g. a cod's stomach content for one month can be (consumption/sec) * ingestion time. We could go further and break it up into digestion stages I guess.

lentinj commented 8 years ago

Closing this now. Makes more sense to have smaller issues on https://github.com/mareframe/mfdbatlantis/issues