private void ExtractByResourceUnit(Model model, bool bySpecies, SqliteCommand insertRow) { if (this.mFieldList.Count == 0) { return; // nothing to do if no fields to log } List <double> data = new(); //statistics data SummaryStatistics fieldStatistics = new(); // statistcs helper class TreeWrapper treeWrapper = new(model); ResourceUnitWrapper ruWrapper = new(model); this.mResourceUnitfilter.Wrapper = ruWrapper; Expression fieldExpression = new(); foreach (ResourceUnit ru in model.Landscape.ResourceUnits) { if (ru.EnvironmentID == -1) { continue; // do not include if out of project area } // test filter if (this.mResourceUnitfilter.IsEmpty == false) { ruWrapper.ResourceUnit = ru; if (this.mResourceUnitfilter.Execute() == 0.0) { continue; } } foreach (ResourceUnitTreeSpecies ruSpecies in ru.Trees.SpeciesAvailableOnResourceUnit) { if (bySpecies && ruSpecies.Statistics.TreeCount == 0) { continue; } // dynamic calculations int columnIndex = 0; foreach (DynamicOutputField field in this.mFieldList) { if (String.IsNullOrEmpty(field.Expression) == false) { // setup dynamic dynamic expression if present fieldExpression.SetExpression(field.Expression); fieldExpression.Wrapper = treeWrapper; } data.Clear(); bool hasTrees = false; Trees treesOfSpecies = ru.Trees.TreesBySpeciesID[ruSpecies.Species.ID]; treeWrapper.Trees = treesOfSpecies; for (int treeIndex = 0; treeIndex < treesOfSpecies.Count; ++treeIndex) { if (bySpecies && treesOfSpecies.Species.Index != ruSpecies.Species.Index) { continue; } if (treesOfSpecies.IsDead(treeIndex)) { continue; } treeWrapper.TreeIndex = treeIndex; // apply tree filter if (!this.mTreeFilter.IsEmpty) { this.mTreeFilter.Wrapper = treeWrapper; if (this.mTreeFilter.Execute() == 0.0) { continue; } } hasTrees = true; if (field.VariableIndex >= 0) { data.Add(treeWrapper.GetValue(field.VariableIndex)); } else { data.Add(fieldExpression.Execute()); } } // do nothing if no trees are avaiable if (hasTrees == false) { continue; } if (columnIndex == 0) { insertRow.Parameters[0].Value = model.CurrentYear; insertRow.Parameters[1].Value = ru.ResourceUnitGridIndex; insertRow.Parameters[2].Value = ru.EnvironmentID; if (bySpecies) { insertRow.Parameters[3].Value = ruSpecies.Species.ID; } else { insertRow.Parameters[3].Value = String.Empty; } columnIndex = 3; } // calculate statistics fieldStatistics.SetData(data); double value = field.AggregationIndex switch { 0 => fieldStatistics.Mean, 1 => fieldStatistics.Sum, 2 => fieldStatistics.Min, 3 => fieldStatistics.Max, 4 => fieldStatistics.GetPercentile25(), 5 => fieldStatistics.GetMedian(), 6 => fieldStatistics.GetPercentile75(), 7 => fieldStatistics.GetPercentile(5), 8 => fieldStatistics.GetPercentile(10), 9 => fieldStatistics.GetPercentile(90), 10 => fieldStatistics.GetPercentile(95), 11 => fieldStatistics.GetStandardDeviation(), _ => 0.0, }; // add current value to output insertRow.Parameters[++columnIndex].Value = value; } // foreach field if (columnIndex > 0) { insertRow.ExecuteNonQuery(); } if (!bySpecies) { break; } } // foreach tree species } // foreach resource unit }