public void BuildLiftsForSinglePassCell_CMVPercentChange(float[] heights, short[] cmvs) { var siteModel = DITAGFileAndSubGridRequestsWithIgniteFixture.NewEmptyModel(); var baseTime = DateTime.UtcNow; var cellPasses = new[] { new CellPass { Time = baseTime, Height = heights[0], CCV = cmvs[0] }, new CellPass { Time = baseTime.AddHours(1), Height = heights[1], CCV = cmvs[1] }, new CellPass { Time = baseTime.AddHours(2), Height = heights[2], CCV = cmvs[2] }, new CellPass { Time = baseTime.AddHours(3), Height = heights[3], CCV = cmvs[3] } }; DITAGFileAndSubGridRequestsFixture.AddSingleCellWithPasses (siteModel, SubGridTreeConsts.DefaultIndexOriginOffset, SubGridTreeConsts.DefaultIndexOriginOffset, cellPasses); IClientLeafSubGrid clientGrid = ClientLeafSubGridFactoryFactory.CreateClientSubGridFactory().GetSubGrid(GridDataType.CCVPercentChange) as ClientCMVLeafSubGrid; var serverGrid = TRex.SubGridTrees.Server.Utilities.SubGridUtilities.LocateSubGridContaining( siteModel.PrimaryStorageProxy, siteModel.Grid, SubGridTreeConsts.DefaultIndexOriginOffset, SubGridTreeConsts.DefaultIndexOriginOffset, siteModel.Grid.NumLevels, false, false) as IServerLeafSubGrid; var builder = new CellLiftBuilder(siteModel, GridDataType.CCVPercentChange, new FilteredValuePopulationControl(), new FilterSet(new CombinedFilter()), new CellPassFastEventLookerUpper(siteModel)); var cell = new ProfileCell(); var segmentIterator = new SubGridSegmentIterator(serverGrid, serverGrid.Directory, siteModel.PrimaryStorageProxy); var cellPassIterator = new SubGridSegmentCellPassIterator_NonStatic(segmentIterator); var filteredValueAssignmentContext = new FilteredValueAssignmentContext(); builder.Build(cell, new LiftParameters(), clientGrid, filteredValueAssignmentContext, cellPassIterator, true).Should().BeTrue(); cell.Layers.Count().Should().Be(1); cell.Layers[0].PassCount.Should().Be(4); filteredValueAssignmentContext.FilteredValue.FilteredPassData.FilteredPass.CCV.Should().Be(cmvs[cmvs.Length - 1]); filteredValueAssignmentContext.PreviousFilteredValue.FilteredPassData.FilteredPass.CCV.Should().Be(cmvs[cmvs.Length - 2]); }
public void RemoveHero(ProfileCell profileCell) { var deckCell = Array.Find(heroDeckCells, cell => cell.CellCharacter?.index == profileCell.HeroInfo.index); deckCell.Init(); profileCell.IsOn = false; }
public void Test_ProfileCell_AddLayer() { ProfileCell cell = new ProfileCell(); cell.AddLayer(new FilteredMultiplePassInfo(new[] { new FilteredPassData() })); Assert.True(1 == cell.Layers.Count(), "Layer count not one after adding layer"); }
public void Test_ProfileCell_Creation() { ProfileCell cell = new ProfileCell(); Assert.NotNull(cell); Assert.True(cell.Layers != null, "Cell profile layer not created"); Assert.True(cell.AttributeExistenceFlags == ProfileCellAttributeExistenceFlags.None, "Cell attribute flags not correctly initialsed"); }
public void Test_ProfileCell_ClearLayers() { ProfileCell cell = new ProfileCell(); cell.AddLayer(new FilteredMultiplePassInfo(new[] { new FilteredPassData() })); cell.ClearLayers(); Assert.True(cell.IsEmpty(), "Cell layers not empty after clear layers"); }
public void Test_ProfileCell_AnalyseSpeedTargets() { ProfileCell cell = new ProfileCell(); cell.AnalyzeSpeedTargets(25); cell.AnalyzeSpeedTargets(50); Assert.True(25 == cell.CellMinSpeed, "Miniumum speed is not 25 as expected"); Assert.True(50 == cell.CellMaxSpeed, "Maxiumum speed is not 50 as expected"); }
public void OnClickProfile(ProfileCell profileCell) { if (profileCell.HeroInfo == null) { return; } heroExplain.text = GameData.Instance.CharacterInfos[profileCell.HeroInfo.type].name; selectedHero = profileCell; addButtonText.text = profileCell.IsOn ? "Remove" : "Add"; }
public void AddHero(ProfileCell profileCell) { for (int i = 0; i < MAX_HERO; ++i) { if (heroDeckCells[i].CellCharacter == null) { profileCell.IsOn = true; heroDeckCells[i].SetInfo(profileCell.HeroInfo); break; } } }
public void Test_ProfileCell_Creation2_NoPasses() { ProfileCell cell = new ProfileCell(new FilteredMultiplePassInfo(), 1, 2, 3.0, 4.0, true); Assert.Equal(1, cell.OTGCellX); Assert.Equal(2, cell.OTGCellY); Assert.Equal(3.0, cell.Station); Assert.Equal(4.0, cell.InterceptLength); // ReSharper disable once UseMethodAny.2 Assert.True(cell.Layers.Count() == 0, "Layer count not zero after constructor creation from cell passes"); }
public void Test_ProfileCell_Creation2_WithPasses() { ProfileCell cell = new ProfileCell(new FilteredMultiplePassInfo(new [] { new FilteredPassData() }), 1, 2, 3.0, 4.0, true); Assert.Equal(1, cell.OTGCellX); Assert.Equal(2, cell.OTGCellY); Assert.Equal(3.0, cell.Station); Assert.Equal(4.0, cell.InterceptLength); Assert.True(cell.Layers.Count() == 1, "Layer count not one after constructor creation from cell passes"); }
public void BuildLiftsForMultiplePassCell(float height1, float height2, float height3, float first, float last, float lowest, float heighest) { var siteModel = DITAGFileAndSubGridRequestsWithIgniteFixture.NewEmptyModel(); var baseTime = DateTime.UtcNow; var cellPasses = new[] { new CellPass { Time = baseTime, Height = height1 }, new CellPass { Time = baseTime.AddHours(1), Height = height2 }, new CellPass { Time = baseTime.AddHours(2), Height = height3 } }; DITAGFileAndSubGridRequestsFixture.AddSingleCellWithPasses (siteModel, SubGridTreeConsts.DefaultIndexOriginOffset, SubGridTreeConsts.DefaultIndexOriginOffset, cellPasses); IClientLeafSubGrid clientGrid = ClientLeafSubGridFactoryFactory.CreateClientSubGridFactory().GetSubGrid(GridDataType.Height) as ClientHeightLeafSubGrid; var serverGrid = TRex.SubGridTrees.Server.Utilities.SubGridUtilities.LocateSubGridContaining( siteModel.PrimaryStorageProxy, siteModel.Grid, SubGridTreeConsts.DefaultIndexOriginOffset, SubGridTreeConsts.DefaultIndexOriginOffset, siteModel.Grid.NumLevels, false, false) as IServerLeafSubGrid; var builder = new CellLiftBuilder(siteModel, GridDataType.Height, new FilteredValuePopulationControl(), new FilterSet(new CombinedFilter()), new CellPassFastEventLookerUpper(siteModel)); var cell = new ProfileCell(); var segmentIterator = new SubGridSegmentIterator(serverGrid, serverGrid.Directory, siteModel.PrimaryStorageProxy); var cellPassIterator = new SubGridSegmentCellPassIterator_NonStatic(segmentIterator); builder.Build(cell, new LiftParameters(), clientGrid, new FilteredValueAssignmentContext(), cellPassIterator, false).Should().BeTrue(); cell.Layers.Count().Should().Be(1); cell.Layers[0].PassCount.Should().Be(3); cell.Layers[0].MinimumPassHeight.Should().Be(lowest); cell.Layers[0].MaximumPassHeight.Should().Be(heighest); cell.Layers[0].FirstPassHeight.Should().Be(first); cell.Layers[0].LastPassHeight.Should().Be(last); }
public void Test_ProfileCell_IsEmpty() { ProfileCell cell = new ProfileCell(); Assert.True(cell.IsEmpty(), "Cell not empty after construction"); cell.AddLayer(new FilteredMultiplePassInfo(new[] { new FilteredPassData() })); Assert.False(cell.IsEmpty(), "Cell empty after addition of a layer"); cell.ClearLayers(); Assert.True(cell.IsEmpty(), "Cell layers not empty after clear layers"); }
public void Test_ProfileCell_RequestNewLayer() { ProfileCell cell = new ProfileCell(); IProfileLayer layer = cell.RequestNewLayer(out int RecycledIndex); cell.Layers.Add(layer, RecycledIndex); Assert.True(layer != null, "RequestNewLayer did not return a new layer"); Assert.True(-1 == RecycledIndex, "Recycled index not -1 for new layer with no recyclbles available"); cell.ClearLayers(); layer = cell.RequestNewLayer(out RecycledIndex); Assert.True(layer != null, "RequestNewLayer did not return a new layer after recycling previous layer"); Assert.True(0 == RecycledIndex, "Recycled index not 0 for new layer with one recyclable available"); }
public void Test_ProfileRequestResponse() { var cell = new ProfileCell(new FilteredMultiplePassInfo(new [] { new FilteredPassData() }), 1, 2, 3.0, 4.0); var cells = new List <ProfileCell> { cell }; var response = new ProfileRequestResponse <ProfileCell> { ResultStatus = RequestErrorStatus.OK, ProfileCells = cells }; var result = SimpleBinarizableInstanceTester.TestClass(response, "Custom ProfileRequestResponse not same after round trip serialisation"); Assert.True(result != null); }
/// <summary> /// Get the profile elevation of the cell for the mode /// </summary> private double ProfileElevation(int mode, ProfileCell cell) { var elevation = 0.0; switch ((DisplayMode)mode) { case DisplayMode.CCV: case DisplayMode.CCVPercent: case DisplayMode.CCVPercentSummary: case DisplayMode.CCVPercentChange: case DisplayMode.CMVChange: elevation = cell.CellCCVElev; break; case DisplayMode.TemperatureSummary: case DisplayMode.TemperatureDetail: elevation = cell.CellMaterialTemperatureElev; break; case DisplayMode.MDPPercentSummary: elevation = cell.CellMDPElev; break; case DisplayMode.CutFill: elevation = cell.CellLastCompositeElev; break; case DisplayMode.PassCount: case DisplayMode.PassCountSummary: case DisplayMode.TargetSpeedSummary: case DisplayMode.Height: default: elevation = cell.CellLastElev; break; } return(elevation); }
/// <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); }
/// <summary> /// Get the profile value of this cell for the mode. /// </summary> private (int index, double value, double value2) ProfileValue(int mode, ProfileCell cell, OverrideParameters overrides) { var NULL_VALUE = (NO_INDEX, double.NaN, double.NaN); double value; int index; switch ((DisplayMode)mode) { case DisplayMode.CCV: if (cell.CellTargetCCV == 0 || cell.CellTargetCCV == CellPassConsts.NullCCV || cell.CellCCV == CellPassConsts.NullCCV) { return(NULL_VALUE); } return(NO_INDEX, cell.CellCCV / 10.0, 0); case DisplayMode.CCVPercent: case DisplayMode.CCVPercentSummary: if (cell.CellTargetCCV == 0 || cell.CellTargetCCV == CellPassConsts.NullCCV || cell.CellCCV == CellPassConsts.NullCCV) { return(NULL_VALUE); } value = (double)cell.CellCCV / (double)cell.CellTargetCCV * 100; index = value <overrides.CMVRange.Min?BELOW_TARGET : value> overrides.CMVRange.Max ? ABOVE_TARGET : ON_TARGET; return(index, value, 0); case DisplayMode.CMVChange: case DisplayMode.CCVPercentChange: if (cell.CellCCV == CellPassConsts.NullCCV) { return(NULL_VALUE); } value = cell.CellPreviousMeasuredCCV == CellPassConsts.NullCCV ? 100 : (double)(cell.CellCCV - cell.CellPreviousMeasuredCCV) / (double)cell.CellPreviousMeasuredCCV * 100; return(NO_INDEX, value, 0); case DisplayMode.PassCount: if (cell.TopLayerPassCount == CellPassConsts.NullPassCountValue) { return(NULL_VALUE); } return(NO_INDEX, cell.TopLayerPassCount, 0); case DisplayMode.PassCountSummary: if (cell.TopLayerPassCount == CellPassConsts.NullPassCountValue || cell.CellLastElev == CellPassConsts.NullHeight) { return(NULL_VALUE); } index = cell.TopLayerPassCount <cell.TopLayerPassCountTargetRangeMin?BELOW_TARGET : cell.TopLayerPassCount> cell.TopLayerPassCountTargetRangeMax ? ABOVE_TARGET : ON_TARGET; return(index, 0, 0); case DisplayMode.CutFill: if (cell.CellLastCompositeElev == CellPassConsts.NullHeight || cell.DesignElev == CellPassConsts.NullHeight) { return(NULL_VALUE); } value = cell.CellLastCompositeElev - cell.DesignElev; return(NO_INDEX, value, 0); case DisplayMode.TemperatureSummary: if (cell.CellMaterialTemperature == CellPassConsts.NullMaterialTemperatureValue || cell.CellMaterialTemperatureElev == CellPassConsts.NullHeight) { return(NULL_VALUE); } index = cell.CellMaterialTemperature <cell.CellMaterialTemperatureWarnMin?BELOW_TARGET : cell.CellMaterialTemperature> cell.CellMaterialTemperatureWarnMax ? ABOVE_TARGET : ON_TARGET; return(index, 0, 0); case DisplayMode.TemperatureDetail: if (cell.CellMaterialTemperature == CellPassConsts.NullMaterialTemperatureValue) { return(NULL_VALUE); } return(NO_INDEX, cell.CellMaterialTemperature / 10.0, 0); case DisplayMode.MDPPercentSummary: if (cell.CellTargetMDP == 0 || cell.CellTargetMDP == CellPassConsts.NullMDP || cell.CellMDP == CellPassConsts.NullMDP) { return(NULL_VALUE); } value = (double)cell.CellMDP / (double)cell.CellTargetMDP * 100; index = value <overrides.MDPRange.Min?BELOW_TARGET : value> overrides.MDPRange.Max ? ABOVE_TARGET : ON_TARGET; return(index, value, 0); case DisplayMode.TargetSpeedSummary: if (cell.CellMaxSpeed == CellPassConsts.NullMachineSpeed || cell.CellLastElev == CellPassConsts.NullHeight) { return(NULL_VALUE); } index = cell.CellMaxSpeed > overrides.TargetMachineSpeed.Max ? ABOVE_TARGET : //cell.CellMinSpeed < overrides.TargetMachineSpeed.Min && cell.CellMaxSpeed < overrides.TargetMachineSpeed.Min ? BELOW_TARGET : ON_TARGET; return(index, cell.CellMinSpeed / KM_HR_TO_CM_SEC, cell.CellMaxSpeed / KM_HR_TO_CM_SEC); case DisplayMode.Height: default: if (cell.CellLastElev == CellPassConsts.NullHeight) { return(NULL_VALUE); } return(NO_INDEX, cell.CellLastElev, 0); } }