public void OrganonStandGrowthApi() { TestStand.WriteTreeHeader(this.TestContext !); foreach (OrganonVariant variant in TestConstant.Variants) { OrganonConfiguration configuration = OrganonTest.CreateOrganonConfiguration(variant); // check crown competition API TestStand stand = OrganonTest.CreateDefaultStand(configuration); float crownCompetitionFactor = OrganonStandDensity.GetCrownCompetitionByHeight(variant, stand)[0]; Assert.IsTrue(crownCompetitionFactor >= 0.0F); Assert.IsTrue(crownCompetitionFactor <= TestConstant.Maximum.CrownCompetitionFactor); OrganonTest.Verify(ExpectedTreeChanges.NoDiameterOrHeightGrowth | ExpectedTreeChanges.NoDiameterOrHeightGrowth, stand, variant); // recalculate heights and crown ratios for all trees Dictionary <FiaCode, SpeciesCalibration> calibrationBySpecies = configuration.CreateSpeciesCalibration(); foreach (Trees treesOfSpecies in stand.TreesBySpecies.Values) { OrganonGrowth.SetIngrowthHeightAndCrownRatio(variant, stand, treesOfSpecies, treesOfSpecies.Count, calibrationBySpecies); } OrganonTest.Verify(ExpectedTreeChanges.NoDiameterOrHeightGrowth | ExpectedTreeChanges.NoDiameterOrHeightGrowth, stand, variant); // run Organon growth simulation stand = OrganonTest.CreateDefaultStand(configuration); if (configuration.IsEvenAge) { // stand error if less than one year to grow to breast height stand.AgeInYears = stand.BreastHeightAgeInYears + 2; } stand.SetQuantiles(); stand.WriteTreesAsCsv(this.TestContext !, variant, 0, false); TestStand initialStand = new TestStand(stand); TreeLifeAndDeath treeGrowth = new TreeLifeAndDeath(); for (int simulationStep = 0; simulationStep < TestConstant.Default.SimulationCyclesToRun; ++simulationStep) { OrganonGrowth.Grow(simulationStep, configuration, stand, calibrationBySpecies); treeGrowth.AccumulateGrowthAndMortality(stand); OrganonTest.Verify(ExpectedTreeChanges.DiameterGrowth | ExpectedTreeChanges.HeightGrowth, OrganonWarnings.LessThan50TreeRecords, stand, variant); stand.WriteTreesAsCsv(this.TestContext !, variant, variant.GetEndYear(simulationStep), false); } OrganonTest.Verify(ExpectedTreeChanges.DiameterGrowth | ExpectedTreeChanges.HeightGrowth, treeGrowth, initialStand, stand); OrganonTest.Verify(calibrationBySpecies); } }
public TestStand ToStand(OrganonConfiguration configuration, float siteIndex) { int firstPlotMeasurementYear = this.GetFirstMeasurementYear(); // populate Organon version of stand // Currently, PSP stands are assumed to have IsEvenAge = false, which causes Organon to require a stand age of // zero years be passed. TestStand stand = new TestStand(configuration.Variant, 0, siteIndex) { NumberOfPlots = this.plotCount }; foreach (KeyValuePair <FiaCode, int> speciesCount in this.CountTreesBySpecies()) { // skip any unsupported species as they should be remapped in following loops if (configuration.Variant.IsSpeciesSupported(speciesCount.Key) == false) { continue; } // metric PSP data is converted to English units for Organon below stand.TreesBySpecies.Add(speciesCount.Key, new Trees(speciesCount.Key, speciesCount.Value, Units.English)); } float fixedPlotExpansionFactor = this.GetTreesPerAcreExpansionFactor(); foreach (PspTreeMeasurementSeries tree in this.MeasurementsByTag.Values) { int firstTreeMeasurementYear = tree.GetFirstMeasurementYear(); Debug.Assert(firstTreeMeasurementYear >= firstPlotMeasurementYear); if (firstTreeMeasurementYear != firstPlotMeasurementYear) { // tree is ingrowth List <PspTreeMeasurementSeries> ingrowthForYear = this.IngrowthByYear.GetOrAdd(firstTreeMeasurementYear); ingrowthForYear.Add(tree); continue; } FiaCode species = PspStand.MaybeRemapToSupportedSpecies(tree.Species, configuration.Variant); Trees treesOfSpecies = stand.TreesBySpecies[species]; Debug.Assert(treesOfSpecies.Capacity > treesOfSpecies.Count); float dbhInInches = TestConstant.InchesPerCm * tree.DbhInCentimetersByYear[firstPlotMeasurementYear]; float heightInFeet = TreeRecord.EstimateHeightInFeet(species, dbhInInches); treesOfSpecies.Add(tree.Tag, dbhInInches, heightInFeet, TestConstant.Default.CrownRatio, fixedPlotExpansionFactor); } // estimate crown ratios OrganonStandDensity standDensity = new OrganonStandDensity(stand, configuration.Variant); Dictionary <FiaCode, int> indexBySpecies = new Dictionary <FiaCode, int>(); foreach (PspTreeMeasurementSeries tree in this.MeasurementsByTag.Values) { int firstTreeMeasurementYear = tree.GetFirstMeasurementYear(); if (firstTreeMeasurementYear != firstPlotMeasurementYear) { continue; } if (indexBySpecies.TryGetValue(tree.Species, out int treeIndex) == false) { treeIndex = 0; indexBySpecies.Add(tree.Species, treeIndex); } FiaCode species = PspStand.MaybeRemapToSupportedSpecies(tree.Species, configuration.Variant); Trees treesOfSpecies = stand.TreesBySpecies[species]; treesOfSpecies.CrownRatio[treeIndex] = tree.EstimateInitialCrownRatio(standDensity); indexBySpecies[tree.Species] = ++treeIndex; } // complete stand initialization stand.EnsureSiteIndicesSet(configuration.Variant); stand.SetQuantiles(); stand.SetRedAlderSiteIndexAndGrowthEffectiveAge(); stand.SetSdiMax(configuration); return(stand); }