예제 #1
0
        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]);
        }
예제 #2
0
    public void RemoveHero(ProfileCell profileCell)
    {
        var deckCell = Array.Find(heroDeckCells, cell => cell.CellCharacter?.index == profileCell.HeroInfo.index);

        deckCell.Init();
        profileCell.IsOn = false;
    }
예제 #3
0
        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");
        }
예제 #4
0
        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");
        }
예제 #5
0
        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");
        }
예제 #6
0
        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");
        }
예제 #7
0
    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";
    }
예제 #8
0
 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;
         }
     }
 }
예제 #9
0
        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");
        }
예제 #10
0
        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");
        }
예제 #11
0
        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);
        }
예제 #12
0
        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");
        }
예제 #13
0
        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");
        }
예제 #14
0
        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);
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
        /// <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);
        }
예제 #17
0
        /// <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);
            }
        }