/// <summary> /// Executor that implements requesting and rendering sub grid information to create the cell datum /// </summary> public async Task <CellDatumResponse_ClusterCompute> ExecuteAsync(CellDatumRequestArgument_ClusterCompute arg, SubGridSpatialAffinityKey key) { Log.LogInformation($"Performing Execute for DataModel:{arg.ProjectID}, Mode={arg.Mode}"); var result = new CellDatumResponse_ClusterCompute { ReturnCode = CellDatumReturnCode.UnexpectedError }; var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(arg.ProjectID); if (siteModel == null) { Log.LogError($"Failed to locate site model {arg.ProjectID}"); return(result); } IDesignWrapper cutFillDesign = null; if (arg.ReferenceDesign != null && arg.ReferenceDesign.DesignID != Guid.Empty) { var design = siteModel.Designs.Locate(arg.ReferenceDesign.DesignID); if (design == null) { throw new ArgumentException($"Design {arg.ReferenceDesign.DesignID} not a recognized design in project {arg.ProjectID}"); } cutFillDesign = new DesignWrapper(arg.ReferenceDesign, design); } await GetProductionData(siteModel, cutFillDesign, result, arg); return(result); }
/// <summary> /// For each point in the list, get the sub grid and extract productionData at the station/offset i.e pointOfInterest /// This could be optimized to get any poi from each sub grid before disposal /// </summary> private StationOffsetReportRequestResponse_ClusterCompute GetProductionData() { var result = new StationOffsetReportRequestResponse_ClusterCompute { ResultStatus = RequestErrorStatus.Unknown }; IDesignWrapper cutFillDesignWrapper = null; if (requestArgument.ReferenceDesign != null && requestArgument.ReferenceDesign.DesignID != Guid.Empty) { var cutFillDesign = siteModel.Designs.Locate(requestArgument.ReferenceDesign.DesignID); if (cutFillDesign == null) { throw new ArgumentException($"Design {requestArgument.ReferenceDesign.DesignID} not a recognized design in project {requestArgument.ProjectID}"); } cutFillDesignWrapper = new DesignWrapper(requestArgument.ReferenceDesign, cutFillDesign); } var existenceMap = siteModel.ExistenceMap; var utilities = DIContext.Obtain <IRequestorUtilities>(); var requestors = utilities.ConstructRequestors(null, siteModel, requestArgument.Overrides, requestArgument.LiftParams, utilities.ConstructRequestorIntermediaries(siteModel, requestArgument.Filters, true, GridDataType.CellProfile), AreaControlSet.CreateAreaControlSet(), existenceMap); // Obtain the primary partition map to allow this request to determine the elements it needs to process bool[] primaryPartitionMap = ImmutableSpatialAffinityPartitionMap.Instance().PrimaryPartitions(); SubGridTreeBitmapSubGridBits cellOverrideMask = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled); foreach (var point in requestArgument.Points) { // Determine the on-the-ground cell siteModel.Grid.CalculateIndexOfCellContainingPosition(point.Easting, point.Northing, out int OTGCellX, out int OTGCellY); var thisSubGridOrigin = new SubGridCellAddress(OTGCellX, OTGCellY); if (!primaryPartitionMap[thisSubGridOrigin.ToSpatialPartitionDescriptor()]) { continue; } // Get the sub grid relative cell location int cellX = OTGCellX & SubGridTreeConsts.SubGridLocalKeyMask; int cellY = OTGCellY & SubGridTreeConsts.SubGridLocalKeyMask; // Reach into the sub-grid request layer and retrieve an appropriate sub-grid cellOverrideMask.Clear(); cellOverrideMask.SetBit(cellX, cellY); requestors[0].CellOverrideMask = cellOverrideMask; // using the cell address get the index of cell in clientGrid var requestSubGridInternalResult = requestors[0].RequestSubGridInternal( thisSubGridOrigin, true, true); if (requestSubGridInternalResult.requestResult != ServerRequestResult.NoError) { Log.LogError($"Request for sub grid {thisSubGridOrigin} request failed with code {result}"); result.StationOffsetRows.Add(new StationOffsetRow(point.Station, point.Offset, point.Northing, point.Easting)); continue; } var hydratedPoint = ExtractRequiredValues(cutFillDesignWrapper, point, requestSubGridInternalResult.clientGrid as ClientCellProfileLeafSubgrid, cellX, cellY); result.StationOffsetRows.Add(hydratedPoint); } result.ResultStatus = RequestErrorStatus.OK; return(result); }
/// <summary> /// Executes the profiler logic in the cluster compute context where each cluster node processes its fraction of the work and returns the /// results to the application service context /// </summary> public async Task <ProfileRequestResponse <T> > ExecuteAsync() { LiftParams.CCVSummaryTypes |= CCVSummaryTypes.Compaction; LiftParams.MDPSummaryTypes |= MDPSummaryTypes.Compaction; ProfileRequestResponse <T> Response = null; try { var ProfileCells = new List <T>(INITIAL_PROFILE_LIST_SIZE); try { // Note: Start/end point lat/lon fields have been converted into grid local coordinate system by this point if (NEECoords.Length > 1) { Log.LogInformation($"#In#: DataModel {ProjectID}, Vertices:{NEECoords[0]} -> {NEECoords[1]}"); } else { Log.LogWarning($"#In#: DataModel {ProjectID}, Note! vertices list has insufficient vertices (min of 2 required)"); } SiteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(ProjectID); if (SiteModel == null) { Log.LogWarning($"Failed to locate site model {ProjectID}"); return(Response = new ProfileRequestResponse <T> { ResultStatus = RequestErrorStatus.NoSuchDataModel }); } // Obtain the sub grid existence map for the project var ProdDataExistenceMap = SiteModel.ExistenceMap; var PopulationControl = new FilteredValuePopulationControl(); PopulationControl.PreparePopulationControl(ProfileTypeRequired, LiftParams, Filters.Filters[0].AttributeFilter); IDesignWrapper designWrapper = null; if (Design != null && Design.DesignID != Guid.Empty) { var design = SiteModel.Designs.Locate(Design.DesignID); if (design == null) { throw new ArgumentException($"Design {Design.DesignID} is unknown in project {SiteModel.ID}"); } designWrapper = new DesignWrapper(Design, design); } Log.LogInformation("Creating IProfileBuilder"); var Profiler = DIContext.Obtain <IProfilerBuilder <T> >(); if (Profiler == null) { Log.LogWarning($"Failed to create IProfileBuilder via DI"); return(Response = new ProfileRequestResponse <T> { ResultStatus = RequestErrorStatus.FailedOnRequestProfile }); } Profiler.Configure(ProfileStyle, SiteModel, ProdDataExistenceMap, ProfileTypeRequired, Filters, designWrapper, PopulationControl, new CellPassFastEventLookerUpper(SiteModel), VolumeType, Overrides, LiftParams); Log.LogInformation("Building cell profile"); if (Profiler.CellProfileBuilder.Build(NEECoords, ProfileCells)) { SetupForCellPassStackExamination(Filters.Filters[0].AttributeFilter); Log.LogInformation("Building lift profile"); if (Profiler.CellProfileAnalyzer.Analyze(ProfileCells, CellPassIterator)) { Log.LogInformation("Lift profile building succeeded"); // Remove null cells in the profiles list. NUll cells are defined by cells with null CellLastHeight. // All duplicate null cells will be replaced by a by single null cell entry var ThinnedProfileCells = ProfileCells.Where((x, i) => i == 0 || !ProfileCells[i].IsNull() || (ProfileCells[i].IsNull() && !ProfileCells[i - 1].IsNull())).ToList(); Response = new ProfileRequestResponse <T> { ProfileCells = ThinnedProfileCells, ResultStatus = RequestErrorStatus.OK }; return(Response); } Log.LogInformation("Lift profile building failed"); } } finally { Log.LogInformation($"#Out# Execute: DataModel {ProjectID} complete for profile line. #Result#:{Response?.ResultStatus ?? RequestErrorStatus.Exception} with {Response?.ProfileCells?.Count ?? 0} vertices"); } } catch (Exception E) { Log.LogError(E, "Execute: Exception:"); } return(new ProfileRequestResponse <T>()); }