Пример #1
0
        public TreeQuantiles(TestStand stand, PspStand pspStand, int measurementYear)
            : this()
        {
            float perTreeExpansionFactor = pspStand.GetTreesPerHectareExpansionFactor();

            foreach (KeyValuePair <FiaCode, int[]> initialDbhQuantile in stand.InitialDbhQuantileBySpecies)
            {
                // accumulate stand state into quantiles
                int[]   speciesQuantileCounts = new int[TestConstant.DbhQuantiles];
                float[] speciesQuantileLiveExpansionFactor = new float[TestConstant.DbhQuantiles];
                float[] speciesQuantileMaxDbh  = new float[TestConstant.DbhQuantiles];
                float[] speciesQuantileMeanDbh = new float[TestConstant.DbhQuantiles];
                float[] speciesQuantileMinDbh  = Enumerable.Repeat(Constant.CentimetersPerInch * TestConstant.Maximum.DiameterInInches, TestConstant.DbhQuantiles).ToArray();

                Trees treesOfSpecies = stand.TreesBySpecies[initialDbhQuantile.Key];
                for (int treeIndex = 0; treeIndex < treesOfSpecies.Count; ++treeIndex)
                {
                    int quantile = initialDbhQuantile.Value[treeIndex];
                    int tag      = treesOfSpecies.Tag[treeIndex];
                    PspTreeMeasurementSeries measurementSeries = pspStand.MeasurementsByTag[tag];
                    if (measurementSeries.DbhInCentimetersByYear.TryGetValue(measurementYear, out float dbh))
                    {
                        speciesQuantileCounts[quantile] += 1;
                        speciesQuantileLiveExpansionFactor[quantile] += perTreeExpansionFactor;
                        speciesQuantileMaxDbh[quantile]   = MathF.Max(speciesQuantileMaxDbh[quantile], dbh);
                        speciesQuantileMeanDbh[quantile] += dbh;
                        speciesQuantileMinDbh[quantile]   = MathF.Min(speciesQuantileMinDbh[quantile], dbh);
                    }
                }

                for (int quantile = 0; quantile < TestConstant.DbhQuantiles; ++quantile)
                {
                    int quantileCount = speciesQuantileCounts[quantile];
                    if (quantileCount > 0)
                    {
                        speciesQuantileMeanDbh[quantile] = speciesQuantileMeanDbh[quantile] / (float)quantileCount;

                        Debug.Assert(speciesQuantileMinDbh[quantile] / speciesQuantileMaxDbh[quantile] < 1.0001);
                        Debug.Assert(speciesQuantileMinDbh[quantile] / speciesQuantileMeanDbh[quantile] < 1.0001);
                        Debug.Assert(speciesQuantileMeanDbh[quantile] / speciesQuantileMaxDbh[quantile] < 1.0001);
                    }
                }

                FiaCode species = initialDbhQuantile.Key;
                this.DeadExpansionFactorBySpecies.Add(species, new float[TestConstant.DbhQuantiles]);
                this.LiveExpansionFactorBySpecies.Add(species, speciesQuantileLiveExpansionFactor);
                this.MaxDbhInCmBySpecies.Add(species, speciesQuantileMaxDbh);
                this.MeanCrownRatioBySpecies.Add(species, new float[TestConstant.DbhQuantiles]);
                this.MeanDbhInCmBySpecies.Add(species, speciesQuantileMeanDbh);
                this.MeanHeightInMetersBySpecies.Add(species, new float[TestConstant.DbhQuantiles]);
                this.MinDbhInCmBySpecies.Add(species, speciesQuantileMinDbh);
            }
        }
Пример #2
0
        private void ParseRow(int rowIndex, string[] rowAsStrings)
        {
            if ((rowIndex == 0) || (rowAsStrings[Constant.Psp.ColumnIndex.Tag] == null))
            {
                return;
            }

            int plot = Int32.Parse(rowAsStrings[Constant.Psp.ColumnIndex.Plot]);

            this.plotCount = Math.Max(this.plotCount, plot);

            int tag = Int32.Parse(rowAsStrings[Constant.Psp.ColumnIndex.Tag]);

            if (this.MeasurementsByTag.TryGetValue(tag, out PspTreeMeasurementSeries? tree) == false)
            {
                FiaCode species = FiaCodeExtensions.Parse(rowAsStrings[Constant.Psp.ColumnIndex.Species]);
                if (species == FiaCode.Alnus)
                {
                    // remap Alnus viridis ssp sinuata to Alnus rubra as no Organon variant has support
                    species = FiaCode.AlnusRubra;
                }
                tree = new PspTreeMeasurementSeries(tag, species);
                this.MeasurementsByTag.Add(tag, tree);
            }

            int status = Int32.Parse(rowAsStrings[Constant.Psp.ColumnIndex.Status]);
            int year   = Int32.Parse(rowAsStrings[Constant.Psp.ColumnIndex.Year]);

            if (status < Constant.Psp.TreeStatus.Dead) // dead or not found trees lack diameter measurements
            {
                float dbhInCentimeters = float.Parse(rowAsStrings[Constant.Psp.ColumnIndex.Dbh]);
                Debug.Assert(dbhInCentimeters >= 5.0F);
                if (tree.DbhInCentimetersByYear.TryAdd(year, dbhInCentimeters) == false)
                {
                    // in case of a conflict, use whichever DBH comes last for consistency with the code above.
                    // For example, tree 8824 in RS39 has two 2013 records.
                    tree.DbhInCentimetersByYear[year] = dbhInCentimeters;
                }
            }

            this.MeasurementYears.Add(year);
        }