Skip to content

Semantic mismatch for reduction in RemoveCohort and ReduceCohort #4

@bahaelaila7

Description

@bahaelaila7

Here's the TLDR:

  • RemoveCohort and ReduceCohort both bundle reduction to MortalityEventArgs but with two different meanings: for the earlier, it's ratio (value of 1.0), for the latter it's absolute biomass passed by the called to ReduceCohort (called in MarkCohorts ).
  • MarkCohorts, is in turn called by ReduceOrKillCohorts.
  • RemoveCohort is also called within GrowCohort
  • Extension-Biomass-Succession calls GrowCohort, while extensions Extension-Base-Wind and Extension-Base-Fire do call ReduceOrKillCohorts .
  • Since RemoveCohort and ReduceCohort reduce to MortalityEventArgs, the only distinction would be within distrubanceType, but disturbanceType is not always null when issued by RemoveCohort (case in point when MarkCohorts determines the disturbed biomass being equal or greater to the cohort biomass).
  • Therefore there is no direct way to make the distinction on the meaning of reduction whether it is a fraction or an absolute biomass.

Details:
There are two methods in Universal-Cohort that emit the MortalityEvent and attach MortalityEventArgs which bundles reduction, namely RemoveCohort and ReduceCohort.

As I alluded earlier, RemoveCohort sets reduction=1, while ReduceCohort expects reduction and bundles it as is in MortalityEventArgs.

RemoveCohort and ReduceCohort:

public void RemoveCohort(int index,
ICohort cohort,
ActiveSite site,
ExtensionType disturbanceType)
{
if (isDebugEnabled)
log.DebugFormat(" cohort removed: {0}, {1} yrs, {2} Mg/ha ({3})",
cohort.Species.Name, cohort.Data.Age, cohort.Data.Biomass,
disturbanceType != null
? disturbanceType.Name
: cohort.Data.Age >= species.Longevity
? "senescence"
: cohort.Data.Biomass == 0
? "attrition"
: "UNKNOWN");
cohortData.RemoveAt(index);
Cohort.CohortMortality(this, cohort, site, disturbanceType, 1);
}
//---------------------------------------------------------------------
private void ReduceCohort(//int index,
ICohort cohort,
ActiveSite site,
ExtensionType disturbanceType, float reduction)
{
Cohort.CohortMortality(this, cohort, site, disturbanceType, reduction);
}

Cohort.CohortMortality just fires the event as is:

public static void CohortMortality(object sender,
ICohort cohort,
ActiveSite site,
ExtensionType disturbanceType,
float reduction)
{
if (MortalityEvent != null)
MortalityEvent(sender, new MortalityEventArgs(cohort, site, disturbanceType, reduction));
}

However,
$MarkCohort$ in Universal-Cohort uses both depending if the raw biomass reduction exceeds cohort biomass. But it does pass raw biomass reduction (not fraction) to ReduceCohort:

public int MarkCohorts(IDisturbance disturbance)
{
// Go backwards through list of cohort data, so the removal of an
// item doesn't mess up the loop.
isMaturePresent = false;
int totalReduction = 0;
for (int i = cohortData.Count - 1; i >= 0; i--) {
Cohort cohort = new Cohort(species, cohortData[i], cohortData[i].AdditionalParameters);
int reduction = disturbance.ReduceOrKillMarkedCohort(cohort);
//Console.WriteLine(" Reduction: {0}, {1} yrs, {2} Mg/ha, reduction={3}", cohort.Species.Name, cohort.Age, cohort.Biomass, reduction);
if (reduction > 0) {
totalReduction += reduction;
if (reduction < cohort.Biomass) {
ReduceCohort(cohort, disturbance.CurrentSite, disturbance.Type, reduction);
cohort.ChangeBiomass(-reduction);
cohortData[i] = cohort.Data;
//Console.WriteLine(" Partial Reduction: {0}, {1} yrs, {2} Mg/ha", cohort.Species.Name, cohort.Age, cohort.Biomass);
}
else {
RemoveCohort(i, cohort, disturbance.CurrentSite,
disturbance.Type);
cohort = null;
}
}
if (cohort != null && cohort.Age >= species.Maturity)
isMaturePresent = true;
}
return totalReduction;
}

I think a fix to MarkCohorts is definitely needed since there is no distinction in the semantics of reduction between ReduceCohort and RemoveCohort, since both get reduced to emitting MortalityEventArgs with disturbanceType not mutually exclusive in the two cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions