Example #1
0
        /// <summary>
        /// Clears the transition patches for the specified transition group
        /// </summary>
        /// <param name="transitionGroup"></param>
        /// <remarks></remarks>
        private void ClearTransitionPatches(TransitionGroup transitionGroup)
        {
            Debug.Assert(this.IsSpatial);

            if (transitionGroup.PatchPrioritization != null)
            {
                transitionGroup.PatchPrioritization.TransitionPatches.Clear();
            }
        }
Example #2
0
        /// <summary>
        /// Calculates the spread distance for the specified criteria
        /// </summary>
        /// <param name="contagionCell"></param>
        /// <param name="tstValue"></param>
        /// <param name="spreadGroup"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        private double CalculateSpreadDistance(Cell contagionCell, int tstValue, TransitionGroup spreadGroup, int iteration, int timestep)
        {
            Debug.Assert(tstValue > 0);
            Debug.Assert(this.IsSpatial);

            double SpreadDistance = 0.0;

            for (int tstval = 1; tstval <= tstValue; tstval++)
            {
                double rand = this.m_RandomGenerator.GetNextDouble();
                double PreviousCumulativeProportion = 0.0;
                double CumulativeProportion         = 0.0;

                List <TransitionSpreadDistribution> lst = spreadGroup.TransitionSpreadDistributionMap.GetDistributionList(contagionCell.StratumId, contagionCell.StateClassId, iteration, timestep);

                if (lst == null)
                {
                    continue;
                }

                foreach (TransitionSpreadDistribution tsd in lst)
                {
                    PreviousCumulativeProportion = CumulativeProportion;
                    CumulativeProportion        += tsd.Proportion;

                    if (CumulativeProportion > rand)
                    {
                        double diff1 = (rand - PreviousCumulativeProportion);

                        if (diff1 == 0.0)
                        {
                            SpreadDistance += tsd.MinimumDistance;
                        }
                        else
                        {
                            double diff2 = (CumulativeProportion - PreviousCumulativeProportion);
                            Debug.Assert(diff2 >= diff1);

                            if (diff1 == diff2)
                            {
                                SpreadDistance += tsd.MaximumDistance;
                            }
                            else
                            {
                                double diff3 = (tsd.MaximumDistance - tsd.MinimumDistance);
                                SpreadDistance += (tsd.MinimumDistance + ((diff1 / diff2) * diff3));
                            }
                        }

                        break;
                    }
                }
            }

            return(SpreadDistance);
        }
        private int GetMaxOrderIndex(double order)
        {
            for (int Index = this.m_ShufflableTransitionGroups.Count - 1; Index >= 0; Index--)
            {
                TransitionGroup tg = this.m_ShufflableTransitionGroups[Index];

                if (tg.Order == order)
                {
                    return(Index);
                }
            }

            throw new InvalidOperationException("Cannot find maximum transition order!");
        }
Example #4
0
        /// <summary>
        /// Grows a transition patch
        /// </summary>
        /// <param name="transitionedCells"></param>
        /// <param name="patchCells"></param>
        /// <param name="initiationCell"></param>
        /// <param name="patch"></param>
        /// <param name="transitionGroup"></param>
        /// <param name="iteration"></param>
        /// <param name="timestep"></param>
        /// <remarks></remarks>
        private void GrowTransitionPatch(
            Dictionary <int, Cell> transitionedCells, Dictionary <int, Cell> patchCells, Cell initiationCell,
            TransitionPatch patch, TransitionGroup transitionGroup, int iteration, int timestep)
        {
            double                 PatchSize   = 0.0;
            Queue <Cell>           PatchQueue  = new Queue <Cell>();
            Dictionary <int, Cell> QueuedCells = new Dictionary <int, Cell>();

            PatchQueue.Enqueue(initiationCell);
            QueuedCells.Add(initiationCell.CellId, initiationCell);

            while (PatchQueue.Count > 0)
            {
                Cell CurrentCell = PatchQueue.Dequeue();

                Debug.Assert(!patchCells.ContainsKey(CurrentCell.CellId));
                Debug.Assert(!patch.AllCells.ContainsKey(CurrentCell.CellId));

                patchCells.Add(CurrentCell.CellId, CurrentCell);
                patch.AllCells.Add(CurrentCell.CellId, CurrentCell);

                PatchSize += this.m_AmountPerCell;

                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellNorth(CurrentCell), transitionGroup, iteration, timestep);
                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellNortheast(CurrentCell), transitionGroup, iteration, timestep);
                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellEast(CurrentCell), transitionGroup, iteration, timestep);
                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellSoutheast(CurrentCell), transitionGroup, iteration, timestep);
                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellSouth(CurrentCell), transitionGroup, iteration, timestep);
                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellSouthwest(CurrentCell), transitionGroup, iteration, timestep);
                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellWest(CurrentCell), transitionGroup, iteration, timestep);
                this.AddNeighboringPatchCell(transitionedCells, patchCells, QueuedCells, PatchQueue, this.GetCellNorthwest(CurrentCell), transitionGroup, iteration, timestep);
            }

            patch.Size = PatchSize;

            foreach (var PatchCell in patch.AllCells.Values)
            {
                if (this.IsPatchEdgeCell(PatchCell, patch))
                {
                    patch.EdgeCells.Add(PatchCell.CellId, PatchCell);
                }
            }

            Debug.Assert(patch.EdgeCells.Count() > 0);
            Debug.Assert(patch.AllCells.Count() > 0);
            Debug.Assert(patch.AllCells.Count() >= patch.EdgeCells.Count());
        }
Example #5
0
        /// <summary>
        /// Updates the patch membership for the specified transition group and cell
        /// </summary>
        /// <param name="transitionGroupId"></param>
        /// <param name="cell"></param>
        /// <remarks>
        /// This function will also remove a patch if its cell collection becomes empty.
        /// </remarks>
        private void UpdateCellPatchMembership(int transitionGroupId, Cell cell)
        {
            TransitionGroup TransitionGroup = this.m_TransitionGroups[transitionGroupId];

            if (TransitionGroup.PatchPrioritization != null)
            {
                TransitionPatch Patch = null;

                if (
                    TransitionGroup.PatchPrioritization.PatchPrioritizationType == PatchPrioritizationType.Smallest ||
                    TransitionGroup.PatchPrioritization.PatchPrioritizationType == PatchPrioritizationType.SmallestEdgesOnly)
                {
                    Patch = TransitionGroup.PatchPrioritization.TransitionPatches.First();
                }
                else
                {
                    Patch = TransitionGroup.PatchPrioritization.TransitionPatches.Last();
                }

                if (Patch.AllCells.ContainsKey(cell.CellId))
                {
                    Patch.AllCells.Remove(cell.CellId);
                }

                if (Patch.EdgeCells.ContainsKey(cell.CellId))
                {
                    Patch.EdgeCells.Remove(cell.CellId);
                }

                if (
                    TransitionGroup.PatchPrioritization.PatchPrioritizationType == PatchPrioritizationType.LargestEdgesOnly ||
                    TransitionGroup.PatchPrioritization.PatchPrioritizationType == PatchPrioritizationType.SmallestEdgesOnly)
                {
                    if (Patch.EdgeCells.Count() == 0)
                    {
                        TransitionGroup.PatchPrioritization.TransitionPatches.Remove(Patch);
                    }
                }
                else if (Patch.AllCells.Count() == 0)
                {
                    Debug.Assert(Patch.EdgeCells.Count() == 0);
                    TransitionGroup.PatchPrioritization.TransitionPatches.Remove(Patch);
                }
            }
        }
Example #6
0
        /// <summary>
        /// Selects a patch initiation cell
        /// </summary>
        /// <param name="transitionGroup"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        private Cell SelectPatchInitiationCell(TransitionGroup transitionGroup)
        {
            Debug.Assert(this.IsSpatial);

            PatchPrioritization    pp      = transitionGroup.PatchPrioritization;
            List <TransitionPatch> patches = pp.TransitionPatches;

            if (patches.Count == 0)
            {
                return(null);
            }

            TransitionPatch Patch = patches[0];

            if (pp.PatchPrioritizationType == PatchPrioritizationType.Largest ||
                pp.PatchPrioritizationType == PatchPrioritizationType.LargestEdgesOnly)
            {
                Patch = patches[patches.Count - 1];
            }

            if (pp.PatchPrioritizationType == PatchPrioritizationType.SmallestEdgesOnly ||
                pp.PatchPrioritizationType == PatchPrioritizationType.LargestEdgesOnly)
            {
                if (Patch.EdgeCells.ContainsKey(Patch.SeedCell.CellId))
                {
                    return(Patch.SeedCell);
                }
                else
                {
                    return(Patch.EdgeCells.Values.ElementAt(0));
                }
            }
            else
            {
                if (Patch.AllCells.ContainsKey(Patch.SeedCell.CellId))
                {
                    return(Patch.SeedCell);
                }
                else
                {
                    return(Patch.AllCells.Values.ElementAt(0));
                }
            }
        }
Example #7
0
        /// <summary>
        /// Fills the transition patches for the specified transition group
        /// </summary>
        /// <param name="transitionedCells"></param>
        /// <param name="stratum"></param>
        /// <param name="transitionGroup"></param>
        /// <param name="iteration"></param>
        /// <param name="timestep"></param>
        /// <remarks></remarks>
        private void FillTransitionPatches(
            Dictionary <int, Cell> transitionedCells, Stratum stratum,
            TransitionGroup transitionGroup, int iteration, int timestep)
        {
            Debug.Assert(this.IsSpatial);

            if (transitionGroup.PatchPrioritization == null)
            {
                return;
            }

            Debug.Assert(transitionGroup.PatchPrioritization.TransitionPatches.Count == 0);

            Dictionary <int, Cell> patchCells = new Dictionary <int, Cell>();

            foreach (Cell SimulationCell in stratum.Cells.Values)
            {
                Debug.Assert(SimulationCell.StratumId != 0);
                Debug.Assert(SimulationCell.StateClassId != 0);

                if (patchCells.ContainsKey(SimulationCell.CellId) | transitionedCells.ContainsKey(SimulationCell.CellId))
                {
                    continue;
                }

                if (this.SelectTransitionPathway(SimulationCell, transitionGroup.TransitionGroupId, iteration, timestep) == null)
                {
                    continue;
                }

                TransitionPatch Patch = new TransitionPatch(SimulationCell);

                this.GrowTransitionPatch(transitionedCells, patchCells, SimulationCell, Patch, transitionGroup, iteration, timestep);

                transitionGroup.PatchPrioritization.TransitionPatches.Add(Patch);
            }

            transitionGroup.PatchPrioritization.TransitionPatches.Sort((TransitionPatch p1, TransitionPatch p2) =>
            {
                return(p1.Size.CompareTo(p2.Size));
            });
        }
Example #8
0
        /// <summary>
        /// Initializes the transition spread groups
        /// </summary>
        /// <remarks></remarks>
        private void InitializeTransitionSpreadGroups()
        {
#if DEBUG
            Debug.Assert(this.IsSpatial);
            Debug.Assert(this.m_TransitionSpreadGroups.Count == 0);

            foreach (TransitionGroup t in this.m_TransitionGroups)
            {
                Debug.Assert(t.TransitionSpreadCells.Count == 0);
            }
#endif

            //Get a unique list of transition groups from the spread distribution records
            Dictionary <int, TransitionSpreadDistribution> dict = new Dictionary <int, TransitionSpreadDistribution>();

            foreach (TransitionSpreadDistribution t in this.m_TransitionSpreadDistributions)
            {
                if (!dict.ContainsKey(t.TransitionGroupId))
                {
                    dict.Add(t.TransitionGroupId, t);
                }
            }

            foreach (TransitionSpreadDistribution t in dict.Values)
            {
                this.m_TransitionSpreadGroups.Add(this.m_TransitionGroups[t.TransitionGroupId]);
            }

            //Associate each spread distribution with its transition spread group
            foreach (TransitionSpreadDistribution t in this.m_TransitionSpreadDistributions)
            {
                TransitionGroup tg = this.m_TransitionGroups[t.TransitionGroupId];
                tg.TransitionSpreadDistributionMap.AddItem(t);
            }

            foreach (TransitionGroup tg in this.m_TransitionSpreadGroups)
            {
                tg.TransitionSpreadDistributionMap.Normalize();
            }
        }
Example #9
0
        /// <summary>
        /// Adds a neighboring patch cell
        /// </summary>
        /// <param name="transitionedCells"></param>
        /// <param name="patchCells"></param>
        /// <param name="queuedCells"></param>
        /// <param name="patchQueue"></param>
        /// <param name="neighborCell"></param>
        /// <param name="transitionGroup"></param>
        /// <param name="iteration"></param>
        /// <param name="timestep"></param>
        /// <remarks></remarks>
        private void AddNeighboringPatchCell
            (Dictionary <int, Cell> transitionedCells, Dictionary <int, Cell> patchCells, Dictionary <int, Cell> queuedCells,
            Queue <Cell> patchQueue, Cell neighborCell, TransitionGroup transitionGroup, int iteration, int timestep)
        {
            if (neighborCell != null)
            {
                if (
                    queuedCells.ContainsKey(neighborCell.CellId) ||
                    patchCells.ContainsKey(neighborCell.CellId) ||
                    transitionedCells.ContainsKey(neighborCell.CellId))
                {
                    return;
                }

                if (this.SelectTransitionPathway(neighborCell, transitionGroup.TransitionGroupId, iteration, timestep) == null)
                {
                    return;
                }

                queuedCells.Add(neighborCell.CellId, neighborCell);
                patchQueue.Enqueue(neighborCell);
            }
        }
Example #10
0
        private void ApplyTransitionSpread(Cell contagionCell, Cell neighboringCell, TransitionGroup spreadGroup, int iteration, int timestep, bool isDiagonal, CardinalDirection direction, Dictionary <int, double[]> rasterTransitionAttrValues, Dictionary <int, int[]> dictTransitionedPixels)
        {
            Debug.Assert(this.IsSpatial);

            //Get the cell probability.  If it is less than or equal to zero we don't need to continue

            //DEVTODO: LEO, is this OK with the new Transition Prioritization Code?

            double CellProbability = this.SpatialCalculateCellProbability(neighboringCell, spreadGroup.TransitionGroupId, iteration, timestep);

            if (CellProbability <= 0.0)
            {
                return;
            }

            //Get the transition pathway.  If there isn't one we don't need to continue
            Transition tr = this.SelectTransitionPathway(neighboringCell, spreadGroup.TransitionGroupId, iteration, timestep);

            if (tr == null)
            {
                return;
            }

            //Prepare a TST value with a default of 1.  If we can find a TST group for the contagion cell's stratum and transition type, and
            //the the contagion cells TST values contains that group, then use that TST value.

            int tstvalue = 1;

            TstTransitionGroup tstgroup = this.m_TstTransitionGroupMap.GetGroup(
                tr.TransitionTypeId, contagionCell.StratumId, contagionCell.SecondaryStratumId, contagionCell.TertiaryStratumId);

            if (tstgroup != null)
            {
                if (contagionCell.TstValues.Contains(tstgroup.TSTGroupId))
                {
                    tstvalue = contagionCell.TstValues[tstgroup.TSTGroupId].TstValue;
                }
            }

            if (tstvalue > 0)
            {
                double MinThreshold     = 0;
                double MaxThreshold     = 0;
                double SpreadDistance   = this.CalculateSpreadDistance(contagionCell, tstvalue, spreadGroup, iteration, timestep);
                double NeighborDistance = this.GetNeighborCellDistance(direction);
                double Slope            = GetSlope(contagionCell, neighboringCell, NeighborDistance);

                SpreadDistance *= this.m_TransitionDirectionMultiplierMap.GetDirectionMultiplier(spreadGroup.TransitionGroupId, contagionCell.StratumId, contagionCell.SecondaryStratumId, contagionCell.TertiaryStratumId, direction, iteration, timestep);
                SpreadDistance *= this.m_TransitionSlopeMultiplierMap.GetSlopeMultiplier(spreadGroup.TransitionGroupId, contagionCell.StratumId, contagionCell.SecondaryStratumId, contagionCell.TertiaryStratumId, iteration, timestep, Slope);

                if (isDiagonal)
                {
                    MinThreshold = this.m_InputRasters.GetCellSizeDiagonalMeters() / 2;
                    MaxThreshold = this.m_InputRasters.GetCellSizeDiagonalMeters() * 1.5;
                }
                else
                {
                    MinThreshold = this.m_InputRasters.GetCellSizeMeters() / 2;
                    MaxThreshold = this.m_InputRasters.GetCellSizeMeters() * 1.5;
                }

                if (SpreadDistance >= MinThreshold && SpreadDistance <= MaxThreshold)
                {
                    this.RecordSummaryTransitionOutput(neighboringCell, tr, iteration, timestep, null);
                    this.RecordSummaryTransitionByStateClassOutput(neighboringCell, tr, iteration, timestep);

                    this.ChangeCellForProbabilisticTransition(neighboringCell, tr, iteration, timestep, rasterTransitionAttrValues);
                    this.UpdateTransitionedPixels(neighboringCell, tr.TransitionTypeId, dictTransitionedPixels[spreadGroup.TransitionGroupId]);
                    this.FillProbabilisticTransitionsForCell(neighboringCell, iteration, timestep);
                }
                else if (SpreadDistance > MaxThreshold)
                {
                    int  randdirection = this.m_RandomGenerator.GetNextInteger(0, 360);
                    Cell DistantCell   = GetCellByDistanceAndDirection(contagionCell, randdirection, SpreadDistance);

                    if (DistantCell != null)
                    {
                        Transition DistantTransition = this.SelectTransitionPathway(DistantCell, spreadGroup.TransitionGroupId, iteration, timestep);

                        if (DistantTransition != null)
                        {
                            this.RecordSummaryTransitionOutput(DistantCell, DistantTransition, iteration, timestep, null);
                            this.RecordSummaryTransitionByStateClassOutput(DistantCell, DistantTransition, iteration, timestep);

                            this.ChangeCellForProbabilisticTransition(DistantCell, DistantTransition, iteration, timestep, rasterTransitionAttrValues);
                            this.UpdateTransitionedPixels(DistantCell, DistantTransition.TransitionTypeId, dictTransitionedPixels[spreadGroup.TransitionGroupId]);
                            this.FillProbabilisticTransitionsForCell(DistantCell, iteration, timestep);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Resets the transition target multipliers for this cell, iteration, timestep and explicit transition group
        /// </summary>
        /// <param name="iteration">The current iteration</param>
        /// <param name="timestep">The current timestep</param>
        /// <param name="explicitGroup">transition group must be provided if spatial - should be null if non spatial</param>
        /// <remarks></remarks>
        private void ResetTransitionTargetMultipliers(int iteration, int timestep, TransitionGroup explicitGroup)
        {
            Debug.Assert(explicitGroup != null);

            if (this.m_TransitionTargets.Count == 0)
            {
                return;
            }

            foreach (TransitionTarget tt in this.m_TransitionTargets)
            {
                if (!tt.IsDisabled)
                {
                    tt.Multiplier     = 1.0;
                    tt.ExpectedAmount = 0.0;

                    if (tt.HasPrioritizations)
                    {
                        List <TransitionTargetPrioritization> pl = tt.GetPrioritizations(iteration, timestep);

                        if (pl != null)
                        {
                            foreach (TransitionTargetPrioritization pri in pl)
                            {
                                pri.PossibleAmount           = 0.0;
                                pri.ExpectedAmount           = 0.0;
                                pri.DesiredAmount            = null;
                                pri.CumulativePossibleAmount = 0.0;
                                pri.ProbabilityMultiplier    = 1.0;
                                pri.ProbabilityOverride      = null;
                            }
                        }
                    }
                }
            }

            foreach (Cell simulationCell in this.m_Cells)
            {
                foreach (Transition tr in simulationCell.Transitions)
                {
                    TransitionType ttype = this.m_TransitionTypes[tr.TransitionTypeId];

                    if (this.IsSpatial)
                    {
                        if (!ttype.PrimaryTransitionGroups.Contains(explicitGroup.TransitionGroupId))
                        {
                            continue;
                        }
                    }

                    if (ttype.TransitionGroups.Count == 0)
                    {
                        continue;
                    }

                    double TransMult = this.GetTransitionMultiplier(tr.TransitionTypeId, iteration, timestep, simulationCell);
                    TransMult *= this.GetExternalTransitionMultipliers(tr.TransitionTypeId, iteration, timestep, simulationCell);

                    if (this.IsSpatial)
                    {
                        TransMult *= this.GetTransitionSpatialMultiplier(simulationCell, tr.TransitionTypeId, iteration, timestep);

                        foreach (TransitionGroup tg in ttype.TransitionGroups)
                        {
                            TransMult *= this.GetTransitionAdjacencyMultiplier(tg.TransitionGroupId, iteration, timestep, simulationCell);
                            TransMult *= this.GetExternalSpatialMultipliers(simulationCell, iteration, timestep, tg.TransitionGroupId);
                        }

                        Debug.Assert(TransMult >= 0.0);
                    }

                    if (TransMult == 0.0)
                    {
                        continue;
                    }

                    foreach (TransitionGroup tgroup in ttype.TransitionGroups)
                    {
                        TransitionTarget tt = this.m_TransitionTargetMap.GetTransitionTarget(
                            tgroup.TransitionGroupId, simulationCell.StratumId, simulationCell.SecondaryStratumId,
                            simulationCell.TertiaryStratumId, iteration, timestep);

                        if (tt != null && !tt.IsDisabled)
                        {
                            tt.ExpectedAmount += (tr.Probability * tr.Proportion * this.m_AmountPerCell * TransMult);
                            Debug.Assert(tt.ExpectedAmount >= 0.0);

                            if (tt.HasPrioritizations)
                            {
                                TransitionTargetPrioritization pri = tt.GetPrioritization(
                                    simulationCell.StratumId, simulationCell.SecondaryStratumId, simulationCell.TertiaryStratumId,
                                    simulationCell.StateClassId, iteration, timestep);

                                if (pri != null)
                                {
                                    pri.PossibleAmount += this.m_AmountPerCell;
                                    pri.ExpectedAmount += (tr.Probability * tr.Proportion * this.m_AmountPerCell * TransMult);
                                }
                            }
                        }
                    }
                }
            }

            foreach (TransitionTarget ttarg in this.m_TransitionTargets)
            {
                if (!ttarg.IsDisabled && ttarg.ExpectedAmount != 0)
                {
                    ttarg.Multiplier = ttarg.CurrentValue.Value / ttarg.ExpectedAmount;
                    Debug.Assert(ttarg.Multiplier >= 0.0);

                    if (ttarg.HasPrioritizations)
                    {
                        double PreviousCumulativeAmount      = 0.0;
                        double TotalCumulativePossibleAmount = 0.0;

                        List <TransitionTargetPrioritization> pl = ttarg.GetPrioritizations(iteration, timestep);

                        if (pl != null)
                        {
                            foreach (TransitionTargetPrioritization pri in pl)
                            {
                                TotalCumulativePossibleAmount += pri.PossibleAmount;
                                pri.CumulativePossibleAmount   = TotalCumulativePossibleAmount;

                                if (ttarg.CurrentValue >= pri.CumulativePossibleAmount)
                                {
                                    pri.ProbabilityOverride = 1.0;
                                }
                                else
                                {
                                    if (ttarg.CurrentValue > PreviousCumulativeAmount)
                                    {
                                        pri.DesiredAmount         = ttarg.CurrentValue - PreviousCumulativeAmount;
                                        pri.ProbabilityMultiplier = pri.DesiredAmount.Value / pri.ExpectedAmount;
                                    }
                                    else
                                    {
                                        pri.ProbabilityOverride = 0.0;
                                    }
                                }

                                PreviousCumulativeAmount = pri.CumulativePossibleAmount;
                            }
                        }
                    }
                }
            }
        }
        private void ResetTransitionAttributeTargetMultipliers(
            int iteration, int timestep, Dictionary <int, TransitionGroup> remainingTransitionGroups,
            MultiLevelKeyMap1 <Dictionary <int, TransitionAttributeTarget> > tatMap, TransitionGroup currentTransitionGroup)
        {
            if (this.m_TransitionAttributeTargets.Count == 0)
            {
                return;
            }

            foreach (TransitionAttributeTarget tat in this.m_TransitionAttributeTargets)
            {
                if (!tat.IsDisabled)
                {
                    tat.Multiplier     = 1.0;
                    tat.ExpectedAmount = 0.0;

                    if (tat.HasPrioritizations)
                    {
                        List <TransitionAttributeTargetPrioritization> pl = tat.GetPrioritizations(iteration, timestep);

                        if (pl != null)
                        {
                            foreach (TransitionAttributeTargetPrioritization pri in pl)
                            {
                                pri.PossibleAmount           = 0.0;
                                pri.ExpectedAmount           = 0.0;
                                pri.DesiredAmount            = null;
                                pri.CumulativePossibleAmount = 0.0;
                                pri.ProbabilityMultiplier    = 1.0;
                                pri.ProbabilityOverride      = null;
                            }
                        }
                    }
                }
            }

            foreach (Cell simulationCell in this.m_Cells)
            {
                //Only iterate over the transition attribute types that have a target associated with them in this timestep.

                foreach (int tatId in this.m_TransitionAttributeTypesWithTarget.Keys)
                {
                    TransitionAttributeType ta = this.m_TransitionAttributeTypes[tatId];

                    TransitionAttributeTarget Target = this.m_TransitionAttributeTargetMap.GetAttributeTarget(
                        ta.TransitionAttributeId, simulationCell.StratumId, simulationCell.SecondaryStratumId,
                        simulationCell.TertiaryStratumId, iteration, timestep);

                    if (Target == null || Target.IsDisabled)
                    {
                        continue;
                    }

                    foreach (Transition tr in simulationCell.Transitions)
                    {
                        TransitionType tt    = this.m_TransitionTypes[tr.TransitionTypeId];
                        bool           Found = false;

                        foreach (TransitionGroup rtg in remainingTransitionGroups.Values)
                        {
                            if (tt.PrimaryTransitionGroups.Contains(rtg.TransitionGroupId))
                            {
                                Found = true;
                                break;
                            }
                        }

                        if (!Found)
                        {
                            continue;
                        }

                        if (tt.TransitionGroups.Count == 0)
                        {
                            continue;
                        }

                        if ((tatMap != null) && (currentTransitionGroup != null))
                        {
                            if (tt.TransitionGroups.Contains(currentTransitionGroup.TransitionGroupId))
                            {
                                Dictionary <int, TransitionAttributeTarget> d = tatMap.GetItemExact(Target.StratumId);

                                if (d == null)
                                {
                                    d = new Dictionary <int, TransitionAttributeTarget>();
                                    tatMap.AddItem(Target.StratumId, d);
                                }

                                if (!d.ContainsKey(Target.TransitionAttributeTargetId))
                                {
                                    d.Add(Target.TransitionAttributeTargetId, Target);
                                }
                            }
                        }

                        double TransMult = this.GetTransitionMultiplier(tr.TransitionTypeId, iteration, timestep, simulationCell);
                        TransMult *= this.GetExternalTransitionMultipliers(tr.TransitionTypeId, iteration, timestep, simulationCell);

                        if (this.IsSpatial)
                        {
                            TransMult *= this.GetTransitionSpatialMultiplier(simulationCell, tr.TransitionTypeId, iteration, timestep);

                            foreach (TransitionGroup tg in tt.TransitionGroups)
                            {
                                TransMult *= this.GetTransitionAdjacencyMultiplier(tg.TransitionGroupId, iteration, timestep, simulationCell);
                                TransMult *= this.GetExternalSpatialMultipliers(simulationCell, iteration, timestep, tg.TransitionGroupId);
                            }

                            Debug.Assert(TransMult >= 0.0);
                        }

                        if (TransMult == 0.0)
                        {
                            continue;
                        }

                        foreach (TransitionGroup tg in tt.TransitionGroups)
                        {
                            if (this.IsSpatial)
                            {
                                if (!remainingTransitionGroups.ContainsKey(tg.TransitionGroupId))
                                {
                                    continue;
                                }
                            }

                            double?AttrValue = this.m_TransitionAttributeValueMap.GetAttributeValue(
                                ta.TransitionAttributeId, tg.TransitionGroupId, simulationCell.StratumId,
                                simulationCell.SecondaryStratumId, simulationCell.TertiaryStratumId,
                                simulationCell.StateClassId, iteration, timestep, simulationCell.Age,
                                simulationCell.TstValues);

                            if (AttrValue.HasValue)
                            {
                                double Expectation = tr.Probability * tr.Proportion * this.m_AmountPerCell * AttrValue.Value * TransMult;
                                Target.ExpectedAmount += Expectation;

                                Debug.Assert(Expectation >= 0.0);
                                Debug.Assert(Target.ExpectedAmount >= 0.0);

                                if (Target.HasPrioritizations)
                                {
                                    TransitionAttributeTargetPrioritization pri = Target.GetPrioritization(
                                        simulationCell.StratumId, simulationCell.SecondaryStratumId, simulationCell.TertiaryStratumId,
                                        tg.TransitionGroupId, simulationCell.StateClassId, iteration, timestep);

                                    if (pri != null)
                                    {
                                        pri.PossibleAmount += this.m_AmountPerCell * AttrValue.Value;
                                        pri.ExpectedAmount += Expectation;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            foreach (TransitionAttributeTarget tat in this.m_TransitionAttributeTargets)
            {
                if (!tat.IsDisabled && tat.ExpectedAmount != 0.0)
                {
                    tat.Multiplier = tat.TargetRemaining / tat.ExpectedAmount;
                    Debug.Assert(tat.Multiplier >= 0.0);

                    if (tat.HasPrioritizations)
                    {
                        double PreviousCumulativeAmount      = 0.0;
                        double TotalCumulativePossibleAmount = 0.0;

                        List <TransitionAttributeTargetPrioritization> pl = tat.GetPrioritizations(iteration, timestep);

                        if (pl != null)
                        {
                            foreach (TransitionAttributeTargetPrioritization pri in pl)
                            {
                                TotalCumulativePossibleAmount += pri.PossibleAmount;
                                pri.CumulativePossibleAmount   = TotalCumulativePossibleAmount;

                                if (tat.TargetRemaining >= pri.CumulativePossibleAmount)
                                {
                                    pri.ProbabilityOverride = 1.0;
                                }
                                else
                                {
                                    if (tat.TargetRemaining > PreviousCumulativeAmount)
                                    {
                                        pri.DesiredAmount         = tat.TargetRemaining - PreviousCumulativeAmount;
                                        pri.ProbabilityMultiplier = pri.DesiredAmount.Value / pri.ExpectedAmount;
                                    }
                                    else
                                    {
                                        pri.ProbabilityOverride = 0.0;
                                    }
                                }

                                PreviousCumulativeAmount = pri.CumulativePossibleAmount;
                            }
                        }
                    }
                }
            }
        }