public void Test_SubGridTreeBitmapSubGridBitsTests_Fill() { SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled); Assert.True(bits.IsEmpty(), "Bits not empty"); bits.Fill(); Assert.True(bits.IsFull(), "Bits not empty after performing a Fill()"); }
public void Test_SubGridTreeBitmapSubGridBitsTests_RowToString() { SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled); string s = bits.RowToString(0); Assert.True(s == " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"); bits.Fill(); string s2 = bits.RowToString(0); Assert.True(s2 == " 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"); }
public void Test_SubGridTreeBitmapSubGridBitsTests_BitSet_Uint() { // Test testing a bit is on or off, at two corners to test boundary conditions SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled); Assert.False(bits.BitSet(0, 0U)); Assert.False(bits.BitSet(31, 31U)); bits.Fill(); Assert.True(bits.BitSet(0, 0U)); Assert.True(bits.BitSet(31, 31U)); }
public void Test_SubGridTreeBitmapSubGridBitsTests_SumBitRows() { SubGridTreeBitmapSubGridBits bits = new SubGridTreeBitmapSubGridBits(SubGridBitsCreationOptions.Unfilled); Assert.Equal(0, bits.SumBitRows()); bits[0, 0] = true; Assert.NotEqual(bits.SumBitRows(), (1 << SubGridTreeConsts.SubGridTreeDimension) - 1); bits[0, SubGridTreeConsts.SubGridTreeDimensionMinus1] = true; Assert.NotEqual(bits.SumBitRows(), (1 << SubGridTreeConsts.SubGridTreeDimension)); bits.Fill(); Assert.Equal(bits.SumBitRows(), SubGridTreeBitmapSubGridBits.SumBitRowsFullCount); }
public static void ConstructSubgridSpatialAndPositionalMask(ILeafSubGrid SubGridAsLeaf, ISiteModel SiteModel, ICombinedFilter Filter, bool AHasOverrideSpatialCellRestriction, BoundingIntegerExtent2D AOverrideSpatialCellRestriction, SubGridTreeBitmapSubGridBits PDMask, SubGridTreeBitmapSubGridBits FilterMask) { if (Filter == null || !Filter.SpatialFilter.HasSpatialOrPositionalFilters) { PDMask.Fill(); FilterMask.Fill(); return; } var originX = SubGridAsLeaf.OriginX; var originY = SubGridAsLeaf.OriginY; var cellSize = SiteModel.CellSize; // Get the world location of the origin position SiteModel.Grid.GetCellCenterPosition(originX, originY, out var OX, out var OY); var SpatialFilter = Filter.SpatialFilter; // Attempt to satisfy the calculation below on the basis of the sub grid wholly residing in the override and filter spatial restrictions if (SpatialFilter.Fence.IncludesExtent(new BoundingWorldExtent3D(OX, OY, OX + cellSize * SubGridTreeConsts.SubGridTreeDimension, OY + cellSize * SubGridTreeConsts.SubGridTreeDimension))) { // The extent of the sub grid is wholly contained in the filter, therefore there is no need to iterate though all the cells // individually... FilterMask.Fill(); // ... unless there is an override spatial cell restriction that does not enclose the extent of the sub grid if (AHasOverrideSpatialCellRestriction && !AOverrideSpatialCellRestriction.Encloses(new BoundingIntegerExtent2D((int)originX, (int)originY, (int)originX + SubGridTreeConsts.SubGridTreeDimension, (int)originY + SubGridTreeConsts.SubGridTreeDimension))) { for (byte I = 0; I < SubGridTreeConsts.SubGridTreeDimension; I++) { for (byte J = 0; J < SubGridTreeConsts.SubGridTreeDimension; J++) { if (!AOverrideSpatialCellRestriction.Includes(originX + I, originY + J)) { FilterMask.ClearBit(I, J); } } } } } else { // Perform the calculation the long hand way // ... Idea: Invert row and column order of calculation below to get and set bits based on an entire column of bits FilterMask.Clear(); // Construct the filter mask based on the spatial and location (square/circle/polygonal) filtering double CX = OX; for (byte I = 0; I < SubGridTreeConsts.SubGridTreeDimension; I++) { int OriginXPlusI = originX + I; double CY = OY; // Set to the first row in the column about to be processed for (byte J = 0; J < SubGridTreeConsts.SubGridTreeDimension; J++) { if (AHasOverrideSpatialCellRestriction && !AOverrideSpatialCellRestriction.Includes((int)OriginXPlusI, (int)(originY + J))) { // Do nothing } else { // SiteModel.Grid.GetCellCenterPosition(OriginXPlusI, originY + J, out CX, out CY); if (SpatialFilter.IsCellInSelection(CX, CY)) { FilterMask.SetBit(I, J); } } CY += cellSize; // Move to next row } CX += cellSize; // Move to next column } } }
/// <summary> /// Orchestrates the mainline work of analyzing cell and cell pass information to create a client sub grid (heights, CMV, MDP etc) /// based on filter and other information established in the class /// </summary> /// <param name="clientGrid"></param> /// <param name="cellOverrideMask"></param> /// <returns></returns> public virtual ServerRequestResult RetrieveSubGrid(IClientLeafSubGrid clientGrid, SubGridTreeBitmapSubGridBits cellOverrideMask, out bool sieveFilterInUse, Func <ServerRequestResult> computeSpatialFilterMaskAndClientProdDataMap) { sieveFilterInUse = false; if (!Utilities.DerivedGridDataTypesAreCompatible(_gridDataType, clientGrid.GridDataType)) { throw new TRexSubGridProcessingException($"Grid data type of client leaf sub grid [{clientGrid.GridDataType}] is not compatible with the grid data type of retriever [{_gridDataType}]"); } var result = ServerRequestResult.UnknownError; // SIGLogMessage.PublishNoODS(Nil, Format('In RetrieveSubGrid: Active pass filters = %s, Active cell filters = %s', [PassFilter.ActiveFiltersText, CellFilter.ActiveFiltersText])); // Set up class local state for other methods to access _clientGrid = clientGrid; _clientGridAsLeaf = clientGrid as ClientLeafSubGrid; _canUseGlobalLatestCells &= !(_gridDataType == GridDataType.CCV || _gridDataType == GridDataType.CCVPercent) && _liftParams.CCVSummaryTypes != CCVSummaryTypes.None && !(_gridDataType == GridDataType.MDP || _gridDataType == GridDataType.MDPPercent) && _liftParams.MDPSummaryTypes != MDPSummaryTypes.None && !(_gridDataType == GridDataType.CCA || _gridDataType == GridDataType.CCAPercent) && !(_gridDataType == GridDataType.CellProfile || _gridDataType == GridDataType.PassCount || _gridDataType == GridDataType.CellPasses || _gridDataType == GridDataType.MachineSpeed || _gridDataType == GridDataType.CCVPercentChange || _gridDataType == GridDataType.MachineSpeedTarget || _gridDataType == GridDataType.CCVPercentChangeIgnoredTopNullValue); // Support for lazy construction of any required profiling infrastructure if (_clientGrid.WantsLiftProcessingResults() && _profiler == null) { // Some display types require lift processing to be able to select the // appropriate cell pass containing the filtered value required. _profiler = DIContext.Obtain <IProfilerBuilder <ProfileCell> >(); //TODO: should referenceDesignWrapper be null here or be passed through from args? _profiler.Configure(ProfileStyle.CellPasses, _siteModel, _pdExistenceMap, _gridDataType, new FilterSet(_filter), null, _populationControl, new CellPassFastEventLookerUpper(_siteModel), VolumeComputationType.None, _overrides, _liftParams); _cellProfile = new ProfileCell(); // Create and configure the assignment context which is used to contain // a filtered pass and its attendant machine events and target values // prior to assignment to the client sub grid. _assignmentContext.CellProfile = _cellProfile; } try { // Ensure pass type filter is set correctly if (_filter.AttributeFilter.HasPassTypeFilter) { if ((_filter.AttributeFilter.PassTypeSet & (PassTypeSet.Front | PassTypeSet.Rear)) == PassTypeSet.Front) { _filter.AttributeFilter.PassTypeSet |= PassTypeSet.Rear; // these two types go together as half passes } } // ... unless we can use the last pass grid to satisfy the query if (_canUseGlobalLatestCells && !_filter.AttributeFilter.HasElevationRangeFilter && !_clientGrid.WantsLiftProcessingResults() && !_filter.AttributeFilter.HasElevationMappingModeFilter && !(_filter.AttributeFilter.HasElevationTypeFilter && (_filter.AttributeFilter.ElevationType == ElevationType.Highest || _filter.AttributeFilter.ElevationType == ElevationType.Lowest)) && !(_gridDataType == GridDataType.PassCount || _gridDataType == GridDataType.Temperature || _gridDataType == GridDataType.CellProfile || _gridDataType == GridDataType.CellPasses || _gridDataType == GridDataType.MachineSpeed)) { _useLastPassGrid = true; } // First get the sub grid we are interested in // SIGLogMessage.PublishNoODS(Nil, Format('Begin LocateSubGridContaining at %dx%d', [clientGrid.OriginX, clientGrid.OriginY])); _subGrid = SubGridTrees.Server.Utilities.SubGridUtilities.LocateSubGridContaining(_storageProxy, _siteModel.Grid, clientGrid.OriginX, clientGrid.OriginY, _siteModel.Grid.NumLevels, false, false); // SIGLogMessage.PublishNoODS(Nil, Format('End LocateSubGridContaining at %dx%d', [clientGrid.OriginX, clientGrid.Origin])); if (_subGrid == null) // This should never really happen, but we'll be polite about it { Log.LogWarning( $"Sub grid address (CellX={clientGrid.OriginX}, CellY={clientGrid.OriginY}) passed to LocateSubGridContaining() from RetrieveSubGrid() did not match an existing sub grid in the data model. Returning SubGridNotFound as response with a null sub grid reference."); return(ServerRequestResult.SubGridNotFound); } // Now process the contents of that sub grid into the sub grid to be returned to the client. if (!_subGrid.IsLeafSubGrid()) { Log.LogInformation("Requests of node sub grids in the server sub grid are not yet supported"); return(result); } if (!(_subGrid is IServerLeafSubGrid)) { Log.LogError($"_SubGrid {_subGrid.Moniker()} is not a server grid leaf node"); return(result); } // SIGLogMessage.PublishNoODS(Nil, Format('Getting sub grid leaf at %dx%d', [clientGrid.OriginX, clientGrid.OriginY])); _subGridAsLeaf = (IServerLeafSubGrid)_subGrid; _globalLatestCells = _subGridAsLeaf.Directory.GlobalLatestCells; if (PruneSubGridRetrievalHere()) { return(ServerRequestResult.NoError); } // SIGLogMessage.PublishNoODS(Nil, Format('Setup for stripe iteration at %dx%d', [clientGrid.OriginX, clientGrid.OriginY])); SetupForCellPassStackExamination(); // Determine if a sieve filter is required for the sub grid where the sieve matches // the X and Y pixel world size (used for WMS tile computation) _subGrid.CalculateWorldOrigin(out var subGridWorldOriginX, out var subGridWorldOriginY); sieveFilterInUse = _areaControlSet.UseIntegerAlgorithm ? GridRotationUtilities.ComputeSieveBitmaskInteger(subGridWorldOriginX, subGridWorldOriginY, _subGrid.Moniker(), _areaControlSet, _siteModel.CellSize, out _sieveBitmask) : GridRotationUtilities.ComputeSieveBitmaskFloat(subGridWorldOriginX, subGridWorldOriginY, _areaControlSet, _siteModel.CellSize, _assignmentContext, out _sieveBitmask); //if (Debug_ExtremeLogSwitchC) Log.LogDebug($"Performing stripe iteration at {clientGrid.OriginX}x{clientGrid.OriginY}"); if (computeSpatialFilterMaskAndClientProdDataMap != null) { _clientGrid.ProdDataMap.Assign(_subGridAsLeaf.Directory.GlobalLatestCells.PassDataExistenceMap); var innerResult = computeSpatialFilterMaskAndClientProdDataMap(); if (innerResult != ServerRequestResult.NoError) { return(innerResult); } } // Before iterating over stripes of this sub grid, compute a scan map detailing to the best of our current // knowledge, which cells need to be visited so that only cells the filter wants and which are actually // present in the data set are requested. If the intent is to store the result in a cache then ensure the // entire content is requested for the sub grid. if (_prepareGridForCacheStorageIfNoSieving) { _aggregatedCellScanMap.Fill(); } else { _aggregatedCellScanMap.OrWith(_globalLatestCells.PassDataExistenceMap); if (sieveFilterInUse) { _aggregatedCellScanMap.AndWith(_sieveBitmask); // ... and which are required by any sieve mask } _aggregatedCellScanMap.AndWith(_clientGridAsLeaf.ProdDataMap); // ... and which are in the required production data map _aggregatedCellScanMap.AndWith(_clientGridAsLeaf.FilterMap); // ... and which are in the required filter map } // Iterate over the stripes in the sub grid processing each one in turn. for (byte i = 0; i < SubGridTreeConsts.SubGridTreeDimension; i++) { RetrieveSubGridStripe(i); } //if Debug_ExtremeLogSwitchC then Log.LogDebug($"Stripe iteration complete at {clientGrid.OriginX}x{clientGrid.OriginY}"); result = ServerRequestResult.NoError; } catch (Exception e) { Log.LogError(e, $"Exception occurred in {nameof(RetrieveSubGrid)}"); throw; } return(result); }