Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions Tasha/StationAccess/ComputeStationCapacityFactor.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2014 Travel Modelling Group, Department of Civil Engineering, University of Toronto
Copyright 2014-2025 Travel Modelling Group, Department of Civil Engineering, University of Toronto

This file is part of XTMF.

Expand Down Expand Up @@ -73,29 +73,32 @@ public sealed class TimePeriod : IModule

[SubModelInformation(Required = true, Description = "The location of the demand matrix to process. (.mtx file format)")]
public FileLocation DemandMatrix;

[SubModelInformation(Required = true, Description = "The location to save the new Capacity Factors for each station.")]
public FileLocation CapacityFactorOutput;

[RunParameter("Peak Hour Factor", 1.0f, "A factor to counteract demand matrices that have previously been factored into peak-hour matrices.")]
public float PeakHourFactor;

private float[] CapacityFactors;

internal void Execute(int iteration)
internal void Execute(int iteration, float[] previousIterationStationCounts)
{
BinaryHelpers.ExecuteReader(this, (reader) =>
{
EmmeMatrix matrix = new(reader);
switch (matrix.Type)
{
case EmmeMatrix.DataType.Float:
ProcessData(matrix.FloatData, iteration);
ProcessData(matrix.FloatData, iteration, previousIterationStationCounts);
break;
default:
throw new XTMFRuntimeException(this, "In '" + Name + "' the data type for the file '" + DemandMatrix + "' was not float!");
}
}, DemandMatrix);
}

private void ProcessData(float[] autoTripMatrix, int iteration)
private void ProcessData(float[] autoTripMatrix, int iteration, float[] previousIterationStationCounts)
{
var zones = Root.ZoneSystem.ZoneArray.GetFlatData();
int[] zoneIndexForStation = Parent.AccessZoneIndexes;
Expand All @@ -106,9 +109,12 @@ private void ProcessData(float[] autoTripMatrix, int iteration)
(i, state, threadLocalStationAccessCounts) =>
{
var iOffset = i * zones.Length;
var invPHF = 1.0f / PeakHourFactor;
for (int j = 0; j < zoneIndexForStation.Length; j++)
{
threadLocalStationAccessCounts[j] += autoTripMatrix[iOffset + zoneIndexForStation[j]];
var inbound = autoTripMatrix[iOffset + zoneIndexForStation[j]];
var outbound = Parent.CascadingDemand ? autoTripMatrix[zoneIndexForStation[j] * zones.Length + i] : 0.0f;
threadLocalStationAccessCounts[j] += invPHF * (inbound - outbound);
}
return threadLocalStationAccessCounts;
},
Expand All @@ -118,10 +124,12 @@ private void ProcessData(float[] autoTripMatrix, int iteration)
{
for (int i = 0; i < accessStationCounts.Length; i++)
{
accessStationCounts[i] += threadLocalAccessStationCounts[i];
accessStationCounts[i] += previousIterationStationCounts[i] + threadLocalAccessStationCounts[i];
}
}
});
// Copy the updated access counts.
Array.Copy(accessStationCounts, previousIterationStationCounts, accessStationCounts.Length);
var capacity = Parent.Capacity.GetFlatData();
if (CapacityFactors == null || iteration == 0)
{
Expand Down Expand Up @@ -230,6 +238,9 @@ internal static int[] GetStationZones(RangeSet stationRanges, float[] capacity,
[SubModelInformation(Required = false, Description = "Used to process each time period.")]
public TimePeriod[] TimePeriods;

[RunParameter("Enable cascading demand", false, "Allow the demand from one time period to influence the next time period. Leave false for model systems before XTMF 1.15.")]
public bool CascadingDemand;

public void Execute(int iterationNumber, int totalIterations)
{
// if we are
Expand All @@ -238,11 +249,16 @@ public void Execute(int iterationNumber, int totalIterations)
LoadStationCapacity();
LoadAccessZones();
}
// compute everything in parallel
Parallel.ForEach(TimePeriods, (period) =>
// Process each time period
float[] autoCount = new float[AccessZoneIndexes.Length];
foreach(var period in TimePeriods)
{
period.Execute(iterationNumber);
});
period.Execute(iterationNumber, autoCount);
if(!CascadingDemand)
{
Array.Clear(autoCount, 0, autoCount.Length);
}
}
}

public void Load(IConfiguration config, int totalIterations)
Expand Down