Ejemplo n.º 1
0
        /// <summary>
        /// Executes the progressive volumes computation returning a ProgressiveVolumesResponse with the results
        /// </summary>
        public async Task <ProgressiveVolumesResponse> ExecuteAsync()
        {
            var volumesResult         = new ProgressiveVolumesResponse();
            var resultBoundingExtents = BoundingWorldExtent3D.Null();
            var requestDescriptor     = Guid.NewGuid(); // TODO ASNodeImplInstance.NextDescriptor;

            _log.LogInformation($"#In# Performing {nameof(ComputeProgressiveVolumes_Coordinator)}.Execute for DataModel:{SiteModelID}");

            try
            {
                try
                {
                    ApplicationServiceRequestStatistics.Instance.NumProgressiveVolumeRequests.Increment();

                    // Prepare filter for use in the request
                    var resultStatus = FilterUtilities.PrepareFiltersForUse(new[] { Filter, AdditionalSpatialFilter }, SiteModelID);
                    if (resultStatus != RequestErrorStatus.OK)
                    {
                        return(volumesResult);
                    }

                    // Obtain the site model context for the request
                    _siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(SiteModelID);

                    if (_siteModel == null)
                    {
                        return(volumesResult);
                    }

                    // Determine the number of progressions that are required and establish the required aggregation states in the aggregator
                    var numProgressions = (int)((EndDate.Ticks - StartDate.Ticks) / Interval.Ticks);
                    if ((EndDate.Ticks - StartDate.Ticks) % Interval.Ticks == 0)
                    {
                        numProgressions++;
                    }

                    if (VolumeType == VolumeComputationType.Between2Filters)
                    {
                        // One fewer progressions will be calculated as each volume in the progression is computed across the interval of two
                        // surfaces derived from production data.
                        numProgressions--;
                    }

                    if (numProgressions > ClientProgressiveHeightsLeafSubGrid.MaxNumberOfHeightLayers)
                    {
                        throw new ArgumentException($"No more than {ClientProgressiveHeightsLeafSubGrid.MaxNumberOfHeightLayers} height layers may be requested at one time");
                    }

                    // Create and configure the aggregator that contains the business logic for the underlying volume calculation
                    Aggregator = new ProgressiveVolumesCalculationsAggregator
                    {
                        SiteModel         = _siteModel,
                        LiftParams        = _liftParams,
                        CellSize          = _siteModel.CellSize,
                        VolumeType        = VolumeType,
                        CutTolerance      = CutTolerance,
                        FillTolerance     = FillTolerance,
                        AggregationStates = Enumerable
                                            .Range(VolumeType == VolumeComputationType.Between2Filters ? 1 : 0, numProgressions)
                                            .Select(x => StartDate + x * Interval)
                                            .Select(d => new ProgressiveVolumeAggregationState(_siteModel.CellSize)
                        {
                            Date          = d,
                            CutTolerance  = CutTolerance,
                            FillTolerance = FillTolerance
                        }).ToArray()
                    };

                    // Create and configure the volumes calculation engine
                    var computeVolumes = new ProgressiveVolumesCalculator
                    {
                        RequestDescriptor = requestDescriptor,
                        SiteModel         = _siteModel,
                        Aggregator        = Aggregator,
                        Filter            = Filter,
                        VolumeType        = VolumeType,
                        LiftParams        = _liftParams,
                        StartDate         = StartDate,
                        EndDate           = EndDate,
                        Interval          = Interval
                    };

                    InitialiseVolumesCalculator(computeVolumes);

                    // Perform the volume computation
                    if (computeVolumes.ComputeVolumeInformation())
                    {
                        resultStatus = RequestErrorStatus.OK;
                    }
                    else
                    {
                        resultStatus = computeVolumes.AbortedDueToTimeout ? RequestErrorStatus.AbortedDueToPipelineTimeout : RequestErrorStatus.Unknown;
                    }

                    if (resultStatus != RequestErrorStatus.OK)
                    {
                        _log.LogInformation($"Progressive volume result: Failure, error = {resultStatus}");

                        // Send the (empty) results back to the caller
                        return(volumesResult);
                    }

                    // Instruct the Aggregator to perform any finalization logic before reading out the results
                    Aggregator.Finalise();

                    var noProductionDataCount   = 0;
                    var invalidPlanExtentsCount = 0;

                    foreach (var state in Aggregator.AggregationStates)
                    {
                        _log.LogInformation($"#Result# Progressive volume result: Cut={state.CutFillVolume.CutVolume:F3}, Fill={state.CutFillVolume.FillVolume:F3}, Area={state.CoverageArea:F3}");

                        if (!state.BoundingExtents.IsValidPlanExtent)
                        {
                            if (state.CoverageArea == 0 && state.CutFillVolume.CutVolume == 0 && state.CutFillVolume.FillVolume == 0)
                            {
                                noProductionDataCount++;
                            }
                            else
                            {
                                invalidPlanExtentsCount++;
                            }
                        }
                    }

                    if (noProductionDataCount == Aggregator.AggregationStates.Length)
                    {
                        resultStatus = RequestErrorStatus.NoProductionDataFound;
                    }
                    else if (invalidPlanExtentsCount == Aggregator.AggregationStates.Length)
                    {
                        resultStatus = RequestErrorStatus.InvalidPlanExtents;
                    }

                    if (resultStatus == RequestErrorStatus.NoProductionDataFound || resultStatus == RequestErrorStatus.InvalidPlanExtents)
                    {
                        _log.LogInformation($"Progressive volume invalid plan extents or no data found: {resultStatus}");
                    }

                    volumesResult.ResultStatus = resultStatus;

                    if (resultStatus == RequestErrorStatus.OK)
                    {
                        volumesResult.Volumes = Aggregator.AggregationStates.Select(aggregator => new ProgressiveVolumeResponseItem
                        {
                            Date   = aggregator.Date,
                            Volume = new SimpleVolumesResponse
                            {
                                Cut  = aggregator.CutFillVolume.CutVolume,
                                Fill = aggregator.CutFillVolume.FillVolume,
                                TotalCoverageArea  = aggregator.CoverageArea,
                                CutArea            = aggregator.CutArea,
                                FillArea           = aggregator.FillArea,
                                BoundingExtentGrid = aggregator.BoundingExtents,
                                BoundingExtentLLH  = resultBoundingExtents
                            }
                        }).ToArray();
                    }
                }
                finally
                {
                    ApplicationServiceRequestStatistics.Instance.NumProgressiveVolumeRequestsCompleted.Increment();
                    if (volumesResult.ResultStatus != RequestErrorStatus.OK)
                    {
                        ApplicationServiceRequestStatistics.Instance.NumProgressiveVolumeRequestsFailed.Increment();
                    }
                }
            }
            catch (Exception e)
            {
                _log.LogError(e, $"Failed to compute the progressive volumes. Site Model ID: {SiteModelID}");
            }

            return(volumesResult);
        }
Ejemplo n.º 2
0
        public void Finalise_NoFailWithNoAggregators()
        {
            var aggr = new ProgressiveVolumesCalculationsAggregator();

            aggr.Finalise();
        }