Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🧹 Chore: Better understand Emme's Drive Access to Transit Path Building Assumptions #129

Closed
1 of 3 tasks
DavidOry opened this issue Jan 24, 2024 · 8 comments
Closed
1 of 3 tasks
Labels
chore overhead: doesn't add additional functionality, change performance, or refactor code

Comments

@DavidOry
Copy link
Collaborator

DavidOry commented Jan 24, 2024

To create drive access to transit paths in Emme, the roadway network is used. This line obtains the drive time and distance. But it's not clear what these values include. The comment in lines 547 and 548 state that the values include perceived drive time and a toll penalty, but do not point the reader to where the expression lives that determines this definition.

So the first chore is to understand what is included in DTIME. If DTIME is a generalized cost, it should be relabeled as such to avoid additional confusion. Once we understand what is going on, we'll create new Issues and connect them here to do that work. Also, I recall from previous conversations that the skim values are from the single best path (between origin and to the location of first transit boarding), rather than a composite best path. We should confirm and document here.

The second chore is understand if distance is included in the generalized cost values captured by DTIME. The above referenced line of code suggests the distance is being recorded. I believe that this is the distance of the single best path. But if it's the best path per a generalized cost, we need to know if the generalized cost includes distance. If so, it may be better to use, for example, the ratio of the generalized cost between (a) the origin and the drive access to transit location and (b) the origin and the destination, rather than the ratios of the distances. If not, we should understand why we have a generalized cost that excludes distance. But before doing that we need to understand the first chore. Issues will be created if needed.

Progress:

  • Sufficiently defined
  • Approach decided
  • Implemented

Considerations

Based on your conversations on Jan 24, 2024. FYI @e-lo, @lmz, @gregerhardt, @inrokevin, @arashasadabadi, @yueshuaing, @i-am-sijia

@DavidOry DavidOry added the chore overhead: doesn't add additional functionality, change performance, or refactor code label Jan 24, 2024
@i-am-sijia
Copy link
Collaborator

"type": "MATRIX_CALCULATION",
"constraint": None,
"result": f'mf"{_tp_tclass}_DTIME"',
"expression": f'mf"{_tp_tclass}_DTIME" - 60*mf"{_tp_tclass}_DTOLL"/{vot}',
},

Is the calculation for converting TOLL to TIME correct here? The VOT should be in $. What about the DTOLL skim? If it is in cents, then instead of 60 it should be 0.6.

@DavidOry
Copy link
Collaborator Author

"type": "MATRIX_CALCULATION",
"constraint": None,
"result": f'mf"{_tp_tclass}_DTIME"',
"expression": f'mf"{_tp_tclass}_DTIME" - 60*mf"{_tp_tclass}_DTOLL"/{vot}',
},

Is the calculation for converting TOLL to TIME correct here? The VOT should be in $. What about the DTOLL skim? If it is in cents, then instead of 60 it should be 0.6.

Good point that we should check the units of DTOLL. In TM1.5 (and the Link21 model), prices are expressed in cents. So:

DTOLL (cents) / VOT (dollars per hour) --> (hours * cents / dollars) * (1 dollar / 100 cents) * (60 minutes / 1 hour) --> 0.60

But in TM2, prices should be expressed in dollars. So:

DTOLL (dollars) / VOT (dollars per hour) --> (hours) * (60 minutes / 1 hour) --> 60

So this appears to be a correct translation. But we need to find out where the DTIME generalized cost expression is to confirm. @yueshuaing, @inrokevin: do either of you know?

@inrokevin
Copy link
Collaborator

The values for DTIME will be embedded in the definition of the drive aux transit mode, with (most likely) a calculation expression used to assign the value. The speed factor will either be a constant (for a constant speed, which should not be the case for the drive mode) or a simple expression as keyword*factor, where keyword is one of timau, ul1, ul2 or ul3, and factor is a float between 0.01 and 999.99, which results in the travel time / gen cost per link.

@inrokevin
Copy link
Collaborator

Found this section here which appears to be the calculation of time in data1 (ul1) including a toll value, which is the same one skimmed with DTOLL

@i-am-sijia
Copy link
Collaborator

Perhaps we have some inconsistencies in the implementation -

  • The snippet of code Kevin found shows the toll value is from highway link toll, which is calculated as below. The highway tolls are in cents. The *100 converts tolls to cents (same as BART). We need to remove the *100.

link[f"@valuetoll_{dst_veh}"] = (
float(data_row[f"toll{time_period.lower()}_{src_veh}"])
* link.length
* 100
)

  • Then in the highway assignment setting, we need to change 0.6 to 60

class_spec = {
"mode": self.class_config.mode_code,
"demand": demand_matrix,
"generalized_cost": {
"link_costs": f"@cost_{self.name.lower()}", # cost in $0.01
# $/hr -> min/$0.01
"perception_factor": 0.6 / self.class_config.value_of_time,
},
"results": {
"link_volumes": f"@flow_{self.name.lower()}",
"od_travel_times": {
"shortest_paths": f"mf{self.time_period}_{self.name}_time"
},
},
"path_analyses": self.emme_class_analysis,
}

A few other things to check:

  • Highway toll skims. This should be consistent with the toll unit.
  • Mode choice UECs. Are they using cents or dollars?

@yueshuaing
Copy link
Collaborator

In the older versions, we used @valuetoll_dam for computing the drive toll, where @valuetoll_dam represented the toll cost in cents per mile. We converted this value to dollar since we also need to skim drive tolls in dollar. The formula we used was toll_per_mile*link_length/100, as indicated in the commented-out line 179.

As highlighted by @i-am-sijia, @valuetoll_{dst_veh} is calculated by the expression toll*length*100 in the highway network. To ensure consistency in the toll calculations across the networks, we will need to either remove *100 in highway link toll calculation, or add /100 to the transit.

for _link_id in _highway_link_dict.keys() & _transit_link_dict.keys():
auto_time = _highway_link_dict[_link_id].auto_time
area_type = _highway_link_dict[_link_id]["@area_type"]
# use @valuetoll_dam (cents/mile) here to represent the drive alone toll
#sov_toll_per_mile = _highway_link_dict[_link_id]['@valuetoll_dam']
link_length = _transit_link_dict[_link_id].length
facility_type = _transit_link_dict[_link_id]['@ft']
#sov_toll = sov_toll_per_mile * link_length/100
# using the @valuetoll_da to get drive alone toll
sov_toll = _highway_link_dict[_link_id]['@valuetoll_da']
_transit_link_dict[_link_id]["@drive_toll"] = sov_toll

@DavidOry
Copy link
Collaborator Author

Thanks everyone. So, it appears:

  1. We have confirmed that the DTIME value is a generalized cost that includes automobile time and toll values. This means we can continue to use distance in the utility expressions without double counting. @inrokevin: can you please confirm that the skimmed value is for a single shortest path?
  2. Let's take this opportunity to confirm that all prices in the model are represented as dollars, not cents.
  3. @AshishKuls: I've assigned this issue (🧹 Chore: Confirm that Link21 Improvements are Representing Prices in Dollars rather than Cents #131) for you to confirm that the prices are in dollars and that both the highway and transit networks are treating prices that way. Please set up a call with myself and @yueshuaing next week to go through the details.

After hearing back from @inrokevin on 1. above, I'll close this issue.

@DavidOry
Copy link
Collaborator Author

@inrokevin has confirmed that all the paths skimmed for the drive access modes are a single, best path. We have also opened #130 to change the DTIME label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore overhead: doesn't add additional functionality, change performance, or refactor code
Projects
None yet
Development

No branches or pull requests

4 participants