示例#1
0
        private void GenerateTrees(int amountOfTrees)
        {
            int    treeCounter = 0;
            Random r           = new Random();

            for (int i = 0; i < amountOfTrees; i++)
            {
                int  random1 = r.Next(1, Xmax - 1);
                int  random2 = r.Next(1, Ymax - 1);
                Tree newTree = new Tree {
                    Id = treeCounter++, X = random1, Y = random2
                };

                if (!Trees.Contains(newTree))
                {
                    Global.Log.TaskList.Add(Task.Run(() => Global.Log.TreeLog(this, newTree)));
                    Console.WriteLine($"[{Id}]: Creating tree at {newTree.X},{newTree.Y} with ID: {newTree.Id}");
                    Trees.Add(newTree);
                }
                else
                {
                    i--;
                }
            }
            Console.WriteLine($"[{Id}]: Generated forest with {Trees.Count} amount of trees with ID: {Id}");
            Global.Log.CreateBitmap(this);
        }
示例#2
0
文件: PspStand.cs 项目: OSU-MARS/SEEM
        public void AddIngrowth(int year, OrganonStand stand, OrganonStandDensity standDensity)
        {
            List <int> remainingIngrowthYears = this.IngrowthByYear.Keys.Where(key => key > this.yearOfMostRecentIngrowthAdded).ToList();

            if ((remainingIngrowthYears.Count < 1) || (remainingIngrowthYears[0] > year))
            {
                // no ingrowth in this simulation step
                return;
            }
            int ingrowthYear = remainingIngrowthYears[0];

            Debug.Assert((remainingIngrowthYears.Count == 1) || (remainingIngrowthYears[1] > year)); // for now, assume only one ingrowth measurement per simulation timestep

            float fixedPlotExpansionFactor = this.GetTreesPerAcreExpansionFactor();

            foreach (PspTreeMeasurementSeries tree in this.IngrowthByYear[ingrowthYear])
            {
                Trees treesOfSpecies = stand.TreesBySpecies[tree.Species];
                Debug.Assert(treesOfSpecies.Capacity > treesOfSpecies.Count);

                float dbhInInches  = Constant.InchesPerCentimeter * tree.DbhInCentimetersByYear.Values[0];
                float heightInFeet = TestConstant.FeetPerMeter * TreeRecord.EstimateHeightInMeters(tree.Species, dbhInInches);
                treesOfSpecies.Add(tree.Tag, dbhInInches, heightInFeet, tree.EstimateInitialCrownRatio(standDensity), fixedPlotExpansionFactor);
            }

            this.yearOfMostRecentIngrowthAdded = ingrowthYear;
        }
示例#3
0
        public void VolumeFia()
        {
            int treeCount = 42;

            // TODO: TSHE, THPL, ...
            Trees trees = new Trees(FiaCode.PseudotsugaMenziesii, treeCount, Units.English);

            float[] fiaMerchantableCubicFeetPerAcre      = new float[treeCount];
            float[] fiaScribnerBoardFeetPerAcre          = new float[treeCount];
            float   merchantableCubicFeetPerAcre         = 0.0F;
            float   merchantableCubicMetersPerHectare    = 0.0F;
            float   totalCylinderCubicMeterVolumePerAcre = 0.0F;
            float   totalScribnerBoardFeetPerAcre        = 0.0F;

            for (int treeIndex = 0; treeIndex < treeCount; ++treeIndex)
            {
                // create trees with a range of expansion factors to catch errors in expansion factor management
                float      treeRatio = (float)treeIndex / (float)treeCount;
                TreeRecord tree      = new TreeRecord(treeIndex, trees.Species, (float)treeIndex, 1.0F - 0.75F * treeRatio, 0.6F + treeIndex);
                trees.Add(tree.Tag, tree.DbhInInches, tree.HeightInFeet, tree.CrownRatio, tree.LiveExpansionFactor);

                float dbhInMeters    = TestConstant.MetersPerInch * tree.DbhInInches;
                float heightInMeters = Constant.MetersPerFoot * tree.HeightInFeet;
                float treeSizedCylinderCubicMeterVolumePerAcre = tree.LiveExpansionFactor * 0.25F * MathF.PI * dbhInMeters * dbhInMeters * heightInMeters;

                fiaMerchantableCubicFeetPerAcre[treeIndex] = tree.LiveExpansionFactor * FiaVolume.GetMerchantableCubicFeet(trees, treeIndex);
                merchantableCubicFeetPerAcre          += fiaMerchantableCubicFeetPerAcre[treeIndex];
                fiaScribnerBoardFeetPerAcre[treeIndex] = tree.LiveExpansionFactor * FiaVolume.GetScribnerBoardFeet(trees, treeIndex);
                totalScribnerBoardFeetPerAcre         += fiaScribnerBoardFeetPerAcre[treeIndex];

                merchantableCubicMetersPerHectare += OsuVolume.GetCubicVolume(trees, treeIndex);

                // taper coefficient should be in the vicinity of 0.3 for larger trees, but this is not well defined for small trees
                // Lower bound can be made more stringent if necessary.
                Assert.IsTrue(fiaMerchantableCubicFeetPerAcre[treeIndex] >= 0.0);
                Assert.IsTrue(fiaMerchantableCubicFeetPerAcre[treeIndex] <= 0.4 * Constant.CubicFeetPerCubicMeter * treeSizedCylinderCubicMeterVolumePerAcre);

                Assert.IsTrue(fiaScribnerBoardFeetPerAcre[treeIndex] >= 0.0);
                Assert.IsTrue(fiaScribnerBoardFeetPerAcre[treeIndex] <= 6.5 * 0.4 * Constant.CubicFeetPerCubicMeter * treeSizedCylinderCubicMeterVolumePerAcre);
                totalCylinderCubicMeterVolumePerAcre += treeSizedCylinderCubicMeterVolumePerAcre;
            }

            float totalCylinderCubicFeetVolumePerAcre = Constant.CubicFeetPerCubicMeter * totalCylinderCubicMeterVolumePerAcre;

            Assert.IsTrue(merchantableCubicFeetPerAcre >= 0.05 * totalCylinderCubicFeetVolumePerAcre);
            Assert.IsTrue(merchantableCubicFeetPerAcre <= 0.35 * totalCylinderCubicFeetVolumePerAcre);
            Assert.IsTrue(merchantableCubicFeetPerAcre >= 0.5 * Constant.HectaresPerAcre * Constant.CubicFeetPerCubicMeter * merchantableCubicMetersPerHectare);

            Assert.IsTrue(merchantableCubicMetersPerHectare <= 0.35 * Constant.AcresPerHectare * totalCylinderCubicMeterVolumePerAcre);

            Assert.IsTrue(totalScribnerBoardFeetPerAcre >= 1.75 * 0.35 * totalCylinderCubicFeetVolumePerAcre);
            Assert.IsTrue(totalScribnerBoardFeetPerAcre <= 6.5 * 0.40 * totalCylinderCubicFeetVolumePerAcre);

            // check SIMD 128 result against scalar
            float totalScribnerBoardFeetPerAcre128 = FiaVolume.GetScribnerBoardFeetPerAcre(trees);
            float simdScalarScribnerDifference     = totalScribnerBoardFeetPerAcre - totalScribnerBoardFeetPerAcre128;

            Assert.IsTrue(MathF.Abs(simdScalarScribnerDifference) < 0.004 * totalScribnerBoardFeetPerAcre);
        }
示例#4
0
 public void OutputTreeFunction()
 {
     Trees.Clear();
     foreach (var tree in CurrenteLocation.Trees)
     {
         Trees.Add(tree);
     }
 }
示例#5
0
 public void AddTree(IDecisionTree tree)
 {
     Trees.Add(tree);
     RefreshTree(tvDecisionTree);
     tree.RootNode.UpdatedAndRefresh += UpdateAdRefresh;
     tree.UpdatedAndRefresh          += UpdateAdRefresh;
     App.SelectedTree = tree.RootNode.Nodes.Count > 1 ? tree : null;
 }
示例#6
0
        public Tree AddTree(float x, float y, int layers, float size)
        {
            var tree = new Tree(HipsterEngine, x, y, 40, layers, size);

            Trees.Add(tree);

            return(tree);
        }
示例#7
0
 public override void CreateGarden()
 {
     Trees.Add(new AppleTree());
     Trees.Add(new CherryTree());
     Trees.Add(new PeachTree());
     Trees.Add(new OakTree());
     Trees.Add(new WillowTree());
     Trees.Add(new BirchTree());
 }
示例#8
0
        public void Add(TreeInfo treeInfo)
        {
            string name = treeInfo.name;

            if (!Trees.Any(t => t.Name == name))
            {
                Trees.Add(new Tree(treeInfo));
            }
        }
示例#9
0
        private void PopulateState(BaseItem item)
        {
            if (item is Empty empty)
            {
                EmptyItems.Add(empty);
                return;
            }

            if (item is AiTank aiTank)
            {
                AiTanks.Add(aiTank);

                if (item is AiPrizeTank aiPrizeTank)
                {
                    AiPrizeTanks.Add(aiPrizeTank);
                }

                return;
            }

            if (item is EnemyTank enemyTank)
            {
                EnemyTanks.Add(enemyTank);
                return;
            }

            if (item is MyTank myTank)
            {
                MyTank = myTank;
                return;
            }

            if (item is Bullet bullet)
            {
                Bullets.Add(bullet);
                return;
            }

            if (item is River river)
            {
                Rivers.Add(river);
                return;
            }

            if (item is Tree tree)
            {
                Trees.Add(tree);
                return;
            }

            if (item is Ice ice)
            {
                Ice.Add(ice);
                return;
            }
        }
示例#10
0
        public void GenerateForest()
        {
            Random r = new Random();

            for (int i = 0; i < 500; i++)
            {
                Tree newTree = new Tree(Trees.Count, r.Next(xmin, xmax), r.Next(ymin, ymax));
                Trees.Add(newTree);
            }
        }
示例#11
0
        public void Tally(IPlotDataService dataService, IFixCNTTallyBucket tallyBucket)
        {
            var tree = dataService.CreateNewTreeEntry(this, tallyBucket.TallyPopulation.SampleGroup,
                                                      tallyBucket.TallyPopulation.TreeDefaultValue, false);

            tallyBucket.TallyPopulation.TallyClass.SetTreeFieldValue(tree, tallyBucket);
            if (tree.TrySave())
            {
                Trees.Add(tree);
            }

            NotifyTallyCountChanged(tallyBucket);
        }
示例#12
0
 private void SetupTrees()
 => Enumerable.Range(0, Settings.TreeCount)
 .ToList()
 .ForEach(_ => {
     var tree = Instantiate(
         Resources.Load("Trees/" + Settings.MapType.ToString() + "/Tree_" + UnityEngine.Random.Range(1, 5)),
         GetFixedPosition(GetValidPosition(), -1.0f),
         Quaternion.Euler(0, UnityEngine.Random.Range(0, 360), 0)) as GameObject;
     tree.transform.parent     = TreeParentGameObject;
     tree.transform.localScale = UnityEngine.Random.Range(0.5f, 1.5f) * Vector3.one;
     tree.transform.GetComponent <Obstacles.Tree>().InitialScaling = tree.transform.localScale.x;
     Trees.Add(tree.transform);
 });
示例#13
0
        public void VolumePerformance()
        {
            int iterations = 1025; // 5 warmup run + measured runs
            int treeCount  = 100 * 1000;

            #if DEBUG
            iterations = 25; // do only functional validation of test on DEBUG builds to reduce test execution time
            treeCount  = 125;
            #endif

            Trees trees           = new Trees(FiaCode.PseudotsugaMenziesii, treeCount, Units.English);
            float expansionFactor = 0.5F;
            for (int treeIndex = 0; treeIndex < treeCount; ++treeIndex)
            {
                float dbhInInches = (float)(treeIndex % 36 + 4);
                trees.Add(treeIndex, dbhInInches, 16.0F * MathF.Sqrt(dbhInInches) + 4.5F, 0.01F * (float)(treeIndex % 100), expansionFactor);
            }
            FiaVolume volume = new FiaVolume();

            Stopwatch runtime = new Stopwatch();
            float     accumulatedBoardFeetPerAcre = 0.0F;
            for (int iteration = 0; iteration < iterations; ++iteration)
            {
                if (iteration > 20)
                {
                    // skip first few runs as warmup runs
                    runtime.Start();
                }

                // 1000 runs * 10,000 trees = 10M volumes on i7-3770
                // .NET standard 2.0 + MathF: 12.854s -> 686k trees/core-s
                //      RS616 pow() -> exp(): 13.254s -> 754k
                //              MathV scalar:  9.451s -> 1.06M
                //          reuse log10(DBH):  8.897s -> 1.12M
                //       aggressive inlining:  7.998s -> 1.20M
                //             internal loop:  7.785s -> 1.28M
                //            single species:  7.619s -> 1.31M
                //                   VEX 128:  2.063s -> 4.85M
                float standBoardFeetPerAcre = FiaVolume.GetScribnerBoardFeetPerAcre(trees);
                #if DEBUG
                Assert.IsTrue(standBoardFeetPerAcre > 35.0F * 1000.0F * expansionFactor);
                Assert.IsTrue(standBoardFeetPerAcre < 40.0F * 1000.0F * expansionFactor);
                #endif
                accumulatedBoardFeetPerAcre += standBoardFeetPerAcre;
            }
            runtime.Stop();

            this.TestContext !.WriteLine(runtime.Elapsed.TotalSeconds.ToString());
        }
示例#14
0
    private void SpawnTreeAt(int type, Vector3 pos)
    {
        var size     = UnityEngine.Random.Range(0.75f, 1.25f);
        var position = GetFixedPosition(pos);
        var path     = "Trees/" + Settings.MapType.ToString() + "/Tree_" + type;

        var treeObject = Instantiate(Resources.Load(path), position, Quaternion.Euler(0, pos.y, 0), TreeParentGameObject) as GameObject;

        treeObject.transform.localScale = size * Vector3.one;

        var tree = treeObject.GetComponent <Obstacles.Tree>();

        tree.InitialScaling = size;
        Trees.Add(treeObject.transform);
    }
示例#15
0
 public void Build(IEnumerable <string> roots)
 {
     foreach (var t in roots)
     {
         if (string.IsNullOrEmpty(t))
         {
             Errors.Add(new BuilderError(t, "Target specification was null or empty."));
             continue;
         }
         if (!Directory.Exists(t))
         {
             Errors.Add(new BuilderError(t, "The specified target directory does not exist."));
         }
         var tree = new ParameterFileTree(t);
         Trees.Add(t, tree);
     }
 }
示例#16
0
        public void TraverseAndCountTrees(Vector <double> slope)
        {
            ResetPositionAndTrees();

            while (Y < Height)
            {
                //< Move the position
                if (!MoveWithOverflow(slope))
                {
                    break;
                }
                //< Check if we a tree mafk
                else if (IsTree(Position))
                {
                    Trees.Add(Position.Clone());
                }
            }
        }
示例#17
0
        private void CreateTree(object obj)
        {
            View.CreateTreeWindow createTreeWindow = new View.CreateTreeWindow();

            if (createTreeWindow.ShowDialog() == true)
            {
                Trees.Add(new Tree(createTreeWindow.Doubles, createTreeWindow.Name));
                MessageBox.Show("Your tree has created succesfully!", "Succes", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else if (createTreeWindow.DialogResult.HasValue && !createTreeWindow.DialogResult.Value)
            {
                return;
            }
            else
            {
                MessageBox.Show("Creating failed", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
示例#18
0
文件: TreeTest.cs 项目: OSU-MARS/SEEM
        public void RemoveZeroExpansionFactorTrees()
        {
            int   treeCount = 147;
            Trees trees     = new Trees(FiaCode.PseudotsugaMenziesii, treeCount, Units.Metric);

            for (int treeIndex = 0; treeIndex < treeCount; ++treeIndex)
            {
                float treeIndexAsFloat = (float)treeIndex;
                float crownRatio       = 0.5F;
                float expansionFactor  = treeIndexAsFloat;
                if (treeIndex % 2 == 0)
                {
                    crownRatio      = 0.01F;
                    expansionFactor = 0.0F;
                }
                trees.Add(treeIndex, treeIndexAsFloat, treeIndexAsFloat, crownRatio, expansionFactor);
                trees.DbhGrowth[treeIndex]           = treeIndexAsFloat;
                trees.DeadExpansionFactor[treeIndex] = treeIndexAsFloat;
                trees.HeightGrowth[treeIndex]        = treeIndexAsFloat;
            }
            Assert.IsTrue(trees.Count == treeCount);

            trees.RemoveZeroExpansionFactorTrees();
            Assert.IsTrue(trees.Count == treeCount / 2);
            for (int treeIndex = 0; treeIndex < trees.Count; ++treeIndex)
            {
                int   tag        = 2 * treeIndex + 1;
                float tagAsFloat = (float)tag;
                Assert.IsTrue(trees.CrownRatio[treeIndex] == 0.5F);
                Assert.IsTrue(trees.Dbh[treeIndex] == tagAsFloat);
                Assert.IsTrue(trees.DbhGrowth[treeIndex] == tagAsFloat);
                Assert.IsTrue(trees.DeadExpansionFactor[treeIndex] == tagAsFloat);
                Assert.IsTrue(trees.Height[treeIndex] == tagAsFloat);
                Assert.IsTrue(trees.HeightGrowth[treeIndex] == tagAsFloat);
                Assert.IsTrue(trees.LiveExpansionFactor[treeIndex] == tagAsFloat);
            }
            for (int treeIndex = trees.Count; treeIndex < trees.Capacity; ++treeIndex)
            {
                Assert.IsTrue(trees.LiveExpansionFactor[treeIndex] == 0.0F);
            }
        }
示例#19
0
            public Map(string input)
            {
                string[][] mapArr = input.Split(Environment.NewLine).Select(x => x.ToArray().Select(y => y.ToString()).ToArray()).ToArray();

                MapHeight = mapArr.Length;

                for (int y = 0; y < mapArr.Length; y++)
                {
                    for (int x = 0; x < mapArr[y].Length; x++)
                    {
                        if (mapArr[y][x] == "#")
                        {
                            for (int i = 0; i < 100; i++)
                            {
                                var xCoord = x + (mapArr[y].Length * i);
                                Trees.Add(new Tree(xCoord, y));
                            }
                        }
                    }
                }
            }
        private void createForest()
        {
            Random random = new Random();

            for (int i = 0; i < AmountOfTrees; i++)
            {
                string name = $"Forest: Tree #{i + 1}";
                bool   flag = false;
                //on some data sets RegressionTree.dll doesn`t create a rule and then make an exception
                while (!flag)
                {
                    try
                    {
                        Test testSample = createRandomDataSample(random);
                        Trees.Add(createTree(name, testSample));
                        flag = true;
                    }
                    catch { }
                }
            }
        }
示例#21
0
        static int debugcalls    = 0;      //to prevent stack overflow

        private static void CreateNewTree(Vector3 pPoint)
        {
            if (treeIndex == 24 && debugcalls < 1)
            {
                //CDebug.WriteLine("");
                if (debugNewTree)
                {
                    debugcalls++;
                    AddPoint(pPoint, -1);
                    return;
                }
            }
            CTree newTree = new CTree(pPoint, treeIndex, TREE_POINT_EXTENT);

            Trees.Add(newTree);
            treeIndex++;

            CProjectData.Points.OnTreeCreated(newTree, pPoint);

            if (newTree.GetTreeHeight() > MaxTreeHeight)
            {
                MaxTreeHeight = newTree.GetTreeHeight();
            }
        }
示例#22
0
 public void Enqueue(Huffman.BinaryTree tree)
 {
     Trees.Add(tree);
     MinHeapify(Trees.Count - 1);
 }
示例#23
0
        public void EnqueueNew(int priority, char?data)
        {
            Trees.Add(new Huffman.BinaryTree(priority, data));

            MinHeapify(Trees.Count - 1);
        }
示例#24
0
 public virtual void AddTree(Tree tree)
 {
     Trees.Add(tree);
     tree.Site = this;
 }
示例#25
0
 public void AddTree(ITree newTree)
 {
     Trees.Add(newTree);
 }
示例#26
0
 public override void CreateGarden()
 {
     Trees.Add(new OakTree());
     Trees.Add(new WillowTree());
     Trees.Add(new BirchTree());
 }
示例#27
0
 public void AddTree(Tree tree)
 {
     tree.SetSprite(m_treeRenderer);
     Trees.Add(tree);
 }
示例#28
0
 public void AddTree(Tree t)
 {
     Trees.Add(t);
 }
示例#29
0
文件: PspStand.cs 项目: OSU-MARS/SEEM
        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);
        }
示例#30
0
        public void VolumeTaper()
        {
            List <ExpectedTreeVolume> trees = new List <ExpectedTreeVolume>()
            {
                // trees very near height and diameter class breaks may estimate differently between metric and English due to numerical precision
                new ExpectedTreeVolume()
                {
                    Species         = FiaCode.PseudotsugaMenziesii,
                    Dbh             = 19.4F,
                    Height          = 21.2F,
                    ExpansionFactor = 1.0F,
                    MinimumMerchantableStemVolumeFraction = 0.51F,
                    MinimumRegenVolumeCubic    = 0.172F,
                    MinimumRegenVolumeScribner = 29.999F,
                    MinimumThinVolumeCubic     = 0.154F,
                    MinimumThinVolumeScribner  = 29.999F
                },
                new ExpectedTreeVolume()
                {
                    Species         = FiaCode.PseudotsugaMenziesii,
                    Dbh             = 30.01F,
                    Height          = 30.01F,
                    ExpansionFactor = 0.36F,
                    MinimumMerchantableStemVolumeFraction = 0.91F,
                    MinimumRegenVolumeCubic    = 0.860F,
                    MinimumRegenVolumeScribner = 119.999F,
                    MinimumThinVolumeCubic     = 0.839F,
                    MinimumThinVolumeScribner  = 119.999F
                },
                new ExpectedTreeVolume()
                {
                    Species         = FiaCode.PseudotsugaMenziesii,
                    Dbh             = 46.2F,
                    Height          = 41.8F,
                    ExpansionFactor = 4.34F,
                    MinimumMerchantableStemVolumeFraction = 0.95F,
                    MinimumRegenVolumeCubic    = 2.64F,
                    MinimumRegenVolumeScribner = 419.999F,
                    MinimumThinVolumeCubic     = 2.66F,
                    MinimumThinVolumeScribner  = 469.999F
                }
            };

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            TimberValue timberValue = new TimberValue(false);

            stopwatch.Stop();
            TimeSpan timberValueTabulationTime = stopwatch.Elapsed;

            this.TestContext !.WriteLine("tabulation: {0:s\\.fff}s", timberValueTabulationTime);

            float volumeTolerance = 1.01F;

            foreach (ExpectedTreeVolume tree in trees)
            {
                float dbhInCentimeters = tree.Dbh;
                float heightInMeters   = tree.Height;
                Trees psmeEnglish      = new Trees(FiaCode.PseudotsugaMenziesii, 1, Units.English);
                psmeEnglish.Add(1, Constant.InchesPerCentimeter * dbhInCentimeters, Constant.FeetPerMeter * heightInMeters, 0.5F, tree.ExpansionFactor);
                Trees psmeMetric = new Trees(FiaCode.PseudotsugaMenziesii, 1, Units.Metric);
                psmeMetric.Add(1, dbhInCentimeters, heightInMeters, 0.5F, tree.ExpansionFactor);

                timberValue.ScaledVolumeRegenerationHarvest.GetScribnerVolume(psmeEnglish, out double regenScribner2SawEnglish, out double regenScribner3SawEnglish, out double regenScribner4SawEnglish);
                double regenScribnerEnglish = regenScribner2SawEnglish + regenScribner3SawEnglish + regenScribner4SawEnglish;
                timberValue.ScaledVolumeRegenerationHarvest.GetGradedVolume(psmeEnglish, out double regenCubic2SawEnglish, out double regenCubic3SawEnglish, out double regenCubic4SawEnglish, out regenScribner2SawEnglish, out regenScribner3SawEnglish, out regenScribner4SawEnglish);
                double regenCubicEnglish         = regenCubic2SawEnglish + regenCubic3SawEnglish + regenCubic4SawEnglish;
                double regenScribnerEnglishCheck = regenScribner2SawEnglish + regenScribner3SawEnglish + regenScribner4SawEnglish;

                timberValue.ScaledVolumeRegenerationHarvest.GetScribnerVolume(psmeMetric, out double regenScribner2SawMetric, out double regenScribner3SawMetric, out double regenScribner4SawMetric);
                double regenScribnerMetric = regenScribner2SawMetric + regenScribner3SawMetric + regenScribner4SawMetric;
                timberValue.ScaledVolumeRegenerationHarvest.GetGradedVolume(psmeMetric, out double regenCubic2SawMetric, out double regenCubic3SawMetric, out double regenCubic4SawMetric, out regenScribner2SawMetric, out regenScribner3SawMetric, out regenScribner4SawMetric);
                double regenCubicMetric         = regenCubic2SawMetric + regenCubic3SawMetric + regenCubic4SawMetric;
                double regenScribnerMetricCheck = regenScribner2SawMetric + regenScribner3SawMetric + regenScribner4SawMetric;

                timberValue.ScaledVolumeThinning.GetScribnerVolume(psmeEnglish, out double thinScribner2SawEnglish, out double thinScribner3SawEnglish, out double thinScribner4SawEnglish);
                double thinScribnerEnglish = thinScribner2SawEnglish + thinScribner3SawEnglish + thinScribner4SawEnglish;
                timberValue.ScaledVolumeThinning.GetGradedVolume(psmeEnglish, out double thinCubic2SawEnglish, out double thinCubic3SawEnglish, out double thinCubic4SawEnglish, out thinScribner2SawEnglish, out thinScribner3SawEnglish, out thinScribner4SawEnglish);
                double thinCubicEnglish         = thinCubic2SawEnglish + thinCubic3SawEnglish + thinCubic4SawEnglish;
                double thinScribnerEnglishCheck = thinScribner2SawEnglish + thinScribner3SawEnglish + thinScribner4SawEnglish;

                timberValue.ScaledVolumeThinning.GetScribnerVolume(psmeMetric, out double thinScribner2SawMetric, out double thinScribner3SawMetric, out double thinScribner4SawMetric);
                double thinScribnerMetric = thinScribner2SawMetric + thinScribner3SawMetric + thinScribner4SawMetric;
                timberValue.ScaledVolumeThinning.GetGradedVolume(psmeMetric, out double thinCubic2SawMetric, out double thinCubic3SawMetric, out double thinCubic4SawMetric, out thinScribner2SawMetric, out thinScribner3SawMetric, out thinScribner4SawMetric);
                double thinCubicMetric         = thinCubic2SawMetric + thinCubic3SawMetric + thinCubic4SawMetric;
                double thinScribnerMetricCheck = thinScribner2SawMetric + thinScribner3SawMetric + thinScribner4SawMetric;

                Assert.IsTrue(regenCubicEnglish == regenCubicMetric);
                Assert.IsTrue(regenScribnerEnglish == regenScribnerMetric);
                Assert.IsTrue(Math.Abs(regenScribnerEnglish - regenScribnerEnglishCheck) < 0.0001);
                Assert.IsTrue(Math.Abs(regenScribnerMetric - regenScribnerMetricCheck) < 0.0001);
                Assert.IsTrue(thinCubicEnglish == thinCubicMetric);
                Assert.IsTrue(thinScribnerEnglish == thinScribnerMetric);
                Assert.IsTrue(Math.Abs(thinScribnerEnglish - thinScribnerEnglishCheck) < 0.0001);
                Assert.IsTrue(Math.Abs(thinScribnerMetric - thinScribnerMetricCheck) < 0.0001);

                regenCubicMetric    /= tree.ExpansionFactor;
                regenScribnerMetric /= tree.ExpansionFactor;
                thinCubicMetric     /= tree.ExpansionFactor;
                thinScribnerMetric  /= tree.ExpansionFactor;

                Assert.IsTrue(thinCubicMetric >= tree.MinimumThinVolumeCubic);
                Assert.IsTrue(thinScribnerMetric >= tree.MinimumThinVolumeScribner);
                Assert.IsTrue(thinCubicMetric < volumeTolerance * tree.MinimumThinVolumeCubic);
                Assert.IsTrue(thinScribnerMetric < volumeTolerance * tree.MinimumThinVolumeScribner);

                Assert.IsTrue(regenCubicMetric >= tree.MinimumRegenVolumeCubic);
                Assert.IsTrue(regenScribnerMetric >= tree.MinimumRegenVolumeScribner);
                Assert.IsTrue(regenCubicMetric < volumeTolerance * tree.MinimumRegenVolumeCubic);
                Assert.IsTrue(regenScribnerMetric < volumeTolerance * tree.MinimumRegenVolumeScribner);

                // ratios must be greater than zero in principle but scaling and CVTS regression error allow crossover
                float poudelTotalCubic = OsuVolume.GetCubicVolume(psmeMetric, 0);
                poudelTotalCubic /= tree.ExpansionFactor;
                Assert.IsTrue(regenCubicMetric / poudelTotalCubic > tree.MinimumMerchantableStemVolumeFraction);
                Assert.IsTrue(thinCubicMetric / poudelTotalCubic > tree.MinimumMerchantableStemVolumeFraction);
                Assert.IsTrue(regenCubicMetric / poudelTotalCubic < 1.0F);
                Assert.IsTrue(thinCubicMetric / poudelTotalCubic < 1.0F);
            }
        }