1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 2# Copyright (C) 2016-2019 German Aerospace Center (DLR) and others. 3# SUMOPy module 4# Copyright (C) 2012-2017 University of Bologna - DICAM 5# This program and the accompanying materials 6# are made available under the terms of the Eclipse Public License v2.0 7# which accompanies this distribution, and is available at 8# http://www.eclipse.org/legal/epl-v20.html 9# SPDX-License-Identifier: EPL-2.0 10 11# @file virtualpop.py 12# @author Joerg Schweizer 13# @date 14# @version $Id$ 15 16import numpy as np 17from numpy import random 18import agilepy.lib_base.classman as cm 19import agilepy.lib_base.arrayman as am 20import agilepy.lib_base.xmlman as xm 21from agilepy.lib_base.misc import random_choice, get_inversemap 22from agilepy.lib_base.processes import Process 23 24# from coremodules.modules_common import * 25from coremodules.network.network import SumoIdsConf, MODES 26from coremodules.network import routing 27from coremodules.simulation import results as res 28from coremodules.demand.demandbase import * 29import virtualpop_results as res 30 31 32GENDERS = {'male': 0, 'female': 1, 'unknown': -1} 33 34OCCUPATIONS = {'unknown': -1, 35 'worker': 1, 36 'student': 2, 37 'employee': 3, 38 'public employee': 4, 39 'selfemployed': 5, 40 'pensioneer': 6, 41 'other': 7 42 } 43 44 45class Activities(am.ArrayObjman): 46 # http://www.sumo.dlr.de/userdoc/Networks/Building_Networks_from_own_XML-descriptions.html#Edge_Descriptions 47 def __init__(self, ident, virtualpop, **kwargs): 48 49 self._init_objman(ident=ident, parent=virtualpop, name='Activities', 50 info='Activity database of persons contains type, time, duration and location of activities.', 51 version=0.0, 52 **kwargs) 53 54 self._init_attributes() 55 56 def _init_attributes(self): 57 58 # activy types now in demand 59 activitytypes = self.parent.get_demand().activitytypes 60 self.add_col(am.IdsArrayConf('ids_activitytype', activitytypes, 61 groupnames=['parameters'], 62 choices=activitytypes.names.get_indexmap(), 63 name='Type', 64 info='Type of activity performed during the stop.', 65 #xmltag = 'actType', 66 #xmlmap = get_inversemap( activitytypes.names.get_indexmap()), 67 )) 68 69 # attention, this may cause trouble durung init if 70 # facilities are not yet initialized 71 self.add_col(am.IdsArrayConf('ids_facility', self.parent.get_scenario().landuse.facilities, 72 groupnames=['parameters'], 73 name='ID fac.', 74 info='Facility ID where activity takes place.', 75 #activitytype = 'home', 76 )) 77 78 # self.add_col(am.ArrayConf( 'descriptions', '', 79 # dtype = np.object, 80 # perm='rw', 81 # is_index = True, 82 # name = 'Description', 83 # info = 'Description of activity.', 84 # )) 85 86 # self.add_col(am.IdlistsArrayConf( 'ids_landusetypes', self.parent.get_landuse().landusetypes, 87 # name = 'Landuse types', 88 # info = "Landuse type IDs, eher this activity type can take place.", 89 # )) 90 91 self.add_col(am.ArrayConf('hours_begin_earliest', 0.0, 92 dtype=np.float32, 93 groupnames=['parameters'], 94 perm='rw', 95 name='Earliest hour begin', 96 unit='h', 97 info='Earliest hour when this activity can begin.', 98 )) 99 100 self.add_col(am.ArrayConf('hours_begin_latest', 1.0, 101 dtype=np.float32, 102 groupnames=['parameters'], 103 perm='rw', 104 name='Latest begin hour', 105 unit='h', 106 info='Latest hour when this activity can begin.', 107 )) 108 109 self.add_col(am.ArrayConf('durations_min', 6.0, 110 dtype=np.float32, 111 groupnames=['parameters'], 112 perm='rw', 113 name='Min. Duration', 114 unit='h', 115 info='Minimum activity duration for a person within a day.', 116 )) 117 118 self.add_col(am.ArrayConf('durations_max', 8.0, 119 dtype=np.float32, 120 groupnames=['parameters'], 121 perm='rw', 122 name='Max. Duration', 123 unit='h', 124 info='Maximum activity duration for a person within a day.', 125 )) 126 127 def get_hours_end_earliest(self, ids): 128 return self.hours_begin_earliest[ids]+self.durations_min[ids] 129 130 def get_hours_end_latest(self, ids): 131 return self.hours_begin_latest[ids]+self.durations_max[ids] 132 133 def get_durations(self, ids, pdf='unit'): 134 durations = np.zeros(len(ids), dtype=np.float32) 135 i = 0 136 for time_start, time_end in zip( 137 np.array(self.durations_min[ids]*3600, dtype=np.int32), 138 np.array(self.durations_max[ids]*3600, dtype=np.int32)): 139 140 durations[i] = np.random.randint(time_start, time_end, 1) 141 i += 1 142 return durations 143 144 def get_times_end(self, ids, pdf='unit'): 145 """ 146 Returns an array with activity ending time for the 147 given activity IDs. 148 The ending time is calculated by drawing random samples 149 from the departure interval. 150 The random samples are drawn according to the given probability 151 density function, pdf. 152 153 Input arguments: 154 ids: integer array with activity IDs 155 pdf: probability density function 'unit'|'normal' 156 157 Returned arguments: 158 times_end: integer array with departure times 159 """ 160 times_end = np.zeros(len(ids), dtype=np.float32) 161 i = 0 162 for time_start, time_end in zip( 163 np.array(self.get_hours_end_earliest(ids)*3600, dtype=np.int32), 164 np.array(self.get_hours_end_latest(ids)*3600, dtype=np.int32)): 165 166 times_end[i] = np.random.randint(time_start, time_end, 1) 167 i += 1 168 169 return times_end 170 171 def get_times_begin(self, ids, pdf='unit'): 172 """ 173 Returns an array with beginning time for the 174 given activity IDs. 175 The begin time is calculated by drawing random samples 176 from the departure interval. 177 The random samples are drawn according to the given probability 178 density function, pdf. 179 180 Input arguments: 181 ids: integer array with activity IDs 182 pdf: probability density function 'unit'|'normal' 183 184 Returned arguments: 185 times_begin: integer array with departure times 186 """ 187 times_begin = np.zeros(len(ids), dtype=np.float32) 188 i = 0 189 for time_start, time_end in zip( 190 np.array(self.get_hours_begin_earliest(ids)*3600, dtype=np.int32), 191 np.array(self.get_hours_begin_latest(ids)*3600, dtype=np.int32)): 192 193 times_begin[i] = np.random.randint(time_start, time_end, 1) 194 i += 1 195 196 return times_begin 197 198 199class IndividualAutos(am.ArrayObjman): 200 201 def __init__(self, ident, population, **kwargs): 202 # print 'individualvehicle vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1') 203 self._init_objman(ident=ident, 204 parent=population, 205 name='Indiv. Autos', 206 info='Individual auto database. These are privately owned autos.', 207 **kwargs) 208 209 self._init_attributes() 210 self._init_constants() 211 212 def _init_constants(self): 213 214 self.do_not_save_attrs(['mode', 'mode_prefix', 215 '_edges', '_lanes', '_individualvehicle', '_ids_vtype_sumo', '_ids_edge_sumo', 216 '_id_mode', '_get_laneid_allowed', '_get_sumoinfo_from_id_lane', 217 '_space_access', '_parking', '_time_after_unboarding', 218 ]) 219 220 def def_mode(self): 221 self.mode = 'passenger' 222 self.mode_prefix = 'iauto' 223 224 def _init_attributes(self): 225 vtypes = self.parent.get_demand().vtypes 226 self.def_mode() 227 228 ids_vtype = vtypes.select_by_mode(mode=self.mode) 229 230 self.add(cm.AttrConf('space_access', 0.5, 231 groupnames=['options'], 232 perm='rw', 233 name='Space access', 234 unit='m', 235 info='Space to access vehicles at parkings. This is typically less than the vehicle length.', 236 )) 237 238 self.add(cm.AttrConf('time_after_unboarding', 5, 239 groupnames=['options'], 240 perm='rw', 241 name='time after unboarding', 242 unit='s', 243 info='Time the vehicle waits before disappearing after unboarding.', 244 )) 245 246 self.add_col(am.IdsArrayConf('ids_vtype', vtypes, 247 id_default=ids_vtype[0], 248 groupnames=['state'], 249 name='Veh. type', 250 info='Vehicle type.', 251 #xmltag = 'type', 252 )) 253 254 self.add_col(am.IdsArrayConf('ids_person', self.parent, 255 groupnames=['state'], 256 name='ID person', 257 info='ID of person who ownes the vehicle.', 258 )) 259 260 self.add_col(am.ArrayConf('times_exec', 0.0, 261 name='Exec time', 262 info='Total route execution time from simulation run of last plan.', 263 unit='s', 264 )) 265 266 def get_virtualpop(self): 267 return self.parent 268 269 def get_ids_veh_pop(self): 270 """ 271 To be overridden by other individual vehicle types. 272 """ 273 return self.get_virtualpop().ids_iauto 274 275 def get_share(self, is_abs=False): 276 n_veh = len(self) 277 if is_abs: 278 return n_veh 279 else: 280 return float(n_veh)/float(len(self.get_virtualpop())) 281 282 def get_stagetable(self): 283 return self.parent.get_plans().get_stagetable('autorides') 284 285 def get_demand(self): 286 return self.parent.parent 287 288 def clear_vehicles(self): 289 self.get_ids_veh_pop()[self.ids_person.get_value()] = -1 290 self.clear() 291 292 def assign_to_persons(self, ids_person): 293 # print 'assign_to_persons',len(ids_person),self.mode 294 # self.clear_vehicles() 295 #ids_person_noveh = set(ids_person).difference(set(self.ids_person)) 296 n_new = len(ids_person) 297 # 298 # this call is selecting a veh id aof the specific mode 299 # according to its share within this mode 300 ids_vtype = self.get_demand().vtypes.generate_vtypes_for_mode(n_new, mode=self.mode) 301 302 # print ' ids_vtype',ids_vtype 303 ids_veh = self.add_rows(n=n_new, 304 ids_person=ids_person, 305 ids_vtype=ids_vtype, 306 ) 307 self.get_ids_veh_pop()[ids_person] = ids_veh 308 return ids_veh 309 310 def get_vtypes(self): 311 """ 312 Returns a set with all used vehicle types. 313 """ 314 # print 'Vehicles_individual.get_vtypes',self.cols.vtype 315 return set(self.ids_vtype.get_value()) 316 317 def get_id_veh_xml(self, id_veh, id_stage): 318 return self.mode_prefix + '.%s.%s' % (id_veh, id_stage) 319 320 def get_id_line_xml(self, id_veh): 321 return self.mode_prefix + '.%s' % (id_veh) 322 323 def get_id_from_id_sumo(self, id_veh_sumo): 324 # print 'get_id_from_id_sumo',id_veh_sumo,id_veh_sumo.split('.'),self.mode_prefix 325 if len(id_veh_sumo.split('.')) == 3: 326 prefix, id_veh, id_stage = id_veh_sumo.split('.') 327 if prefix == self.mode_prefix: 328 return int(id_veh) 329 else: 330 return -1 331 return -1 332 333 # def append_ride(self, id_veh, id_ride): 334 # ids_ride = self.ids_rides[id_veh] 335 # if ids_ride is None: 336 # self.ids_rides[id_veh] = [id_ride] 337 # else: 338 # ids_ride.append(id_ride) 339 def prepare_write_xml(self): 340 """ 341 Prepare xml export. Must return export function. 342 """ 343 virtualpop = self.get_virtualpop() 344 scenario = virtualpop.get_scenario() 345 #plans = virtualpop.get_plans() 346 347 self._rides = self.get_stagetable() 348 self._edges = scenario.net.edges 349 self._lanes = scenario.net.lanes 350 #self._individualvehicle = virtualpop.get_ibikes() 351 self._ids_vtype_sumo = scenario.demand.vtypes.ids_sumo 352 self._ids_edge_sumo = self._edges.ids_sumo 353 self._id_mode = scenario.net.modes.get_id_mode(self.mode) 354 self._get_laneid_allowed = self._edges.get_laneid_allowed 355 self._get_sumoinfo_from_id_lane = scenario.net.lanes.get_sumoinfo_from_id_lane 356 self._space_access = self.space_access.get_value() 357 #self._time_veh_wait_after_stop = 3600 358 self._parking = virtualpop.get_landuse().parking 359 self._time_after_unboarding = self.time_after_unboarding.get_value() 360 return self.write_xml 361 362 def get_id_veh(self, id_stage): 363 return self._rides.ids_iauto[id_stage] 364 365 def write_xml(self, fd, id_stage, time_begin, indent=2): 366 367 # TODO: actually this should go in individualvehicle 368 #time_veh_wait_after_stop = 3600 369 #plans = self.get_plans() 370 #walkstages = plans.get_stagetable('walks') 371 #rides = plans.get_stagetable('autorides') 372 #activitystages = plans.get_stagetable('activities') 373 374 rides = self._rides 375 #lanes = self._lanes 376 parking = self._parking 377 #net = self.get_net() 378 #lanes = net.lanes 379 #edges = net.edges 380 #ind_ride = rides.get_inds(id_stage) 381 id_veh = self.get_id_veh(id_stage) 382 #individualvehicle = self._iveh 383 id_vtype = self.ids_vtype[id_veh] 384 385 # id_veh_ride, 386 # ids_vtypes_iveh[id_veh], 387 # ids_edges_rides_arr[ind_ride], 388 # ids_parking_from_rides_arr[ind_ride], 389 # ids_parking_to_rides_arr[ind_ride], 390 391 id_parking_from = rides.ids_parking_from[id_stage] 392 id_lane_from = parking.ids_lane[id_parking_from] 393 #laneindex_from = self._lanes.indexes[id_lane_from] 394 pos_from = parking.positions[id_parking_from] 395 396 id_parking_to = rides.ids_parking_to[id_stage] 397 id_lane_to = parking.ids_lane[id_parking_to] 398 #laneindex_to = self._lanes.indexes[id_lane_to] 399 pos_to = parking.positions[id_parking_to] 400 401 # write unique veh ID to prevent confusion with other veh declarations 402 fd.write(xm.start('vehicle id="%s"' % self.get_id_veh_xml(id_veh, id_stage), indent+2)) 403 404 # get start time of first stage of the plan 405 #id_plan = rides.ids_plan[id_stage] 406 #stages0, id_stage0 = self.get_plans().stagelists[id_plan][0] 407 408 # this is the time when the vehicle appers in the scenario 409 fd.write(xm.num('depart', '%.d' % rides.times_init[id_stage])) 410 #fd.write(xm.num('depart', '%.d'%stages0.times_start[id_stage0])) 411 412 fd.write(xm.num('type', self._ids_vtype_sumo[id_vtype])) 413 fd.write(xm.num('line', self.get_id_line_xml(id_veh))) 414 fd.write(xm.num('departPos', pos_from)) 415 fd.write(xm.num('departLane', self._lanes.indexes[id_lane_from])) 416 417 fd.write(xm.stop()) 418 419 # write route 420 fd.write(xm.start('route', indent+4)) 421 # print ' edgeindex[ids_edge]',edgeindex[ids_edge] 422 fd.write(xm.arr('edges', self._ids_edge_sumo[rides.ids_edges[id_stage]])) 423 424 # does not seem to have an effect, always starts at base???? 425 #fd.write(xm.num('departPos', pos_from)) 426 #fd.write(xm.num('departLane', laneindex_from )) 427 fd.write(xm.stopit()) 428 429 # write depart stop 430 fd.write(xm.start('stop', indent+4)) 431 #id_lane = self._lanes.ids_edge[id_lane_from] 432 fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane_from))) 433 # in 0.31 the vehicle will wait until after this duration 434 # so it will be removed unless it will get a timeout function 435 #fd.write(xm.num('duration', time_veh_wait_after_stop)) 436 fd.write(xm.num('startPos', pos_from - parking.lengths[id_parking_from])) 437 fd.write(xm.num('endPos', pos_from)) 438 fd.write(xm.num('triggered', "True")) 439 440 # chrashes with parking=True in 0.30! 441 # however if not parked the vhcle is blocking the traffic 442 # while waiting: workaround: delay departure to be shure that person already arrived 443 444 fd.write(xm.num('parking', "True")) # in windows 0.30 parked vehicles do not depart!! 445 #fd.write(xm.num('parking', "False")) 446 fd.write(xm.stopit()) 447 448 # write arrival stop 449 fd.write(xm.start('stop', indent+4)) 450 fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane_to))) 451 fd.write(xm.num('duration', self._time_after_unboarding)) # for unboarding only 452 fd.write(xm.num('startPos', pos_to - parking.lengths[id_parking_to])) 453 fd.write(xm.num('endPos', pos_to)) 454 #fd.write(xm.num('triggered', "True")) 455 fd.write(xm.stopit()) 456 457 fd.write(xm.end('vehicle', indent+2)) 458 459 460class IndividualBikes(IndividualAutos): 461 462 def __init__(self, ident, population, **kwargs): 463 # print 'individualvehicle vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1') 464 self._init_objman(ident=ident, 465 parent=population, 466 name='Indiv. Bikes', 467 info='Individual bike database. These are privately owned bikes.', 468 **kwargs) 469 self._init_attributes() 470 self._init_constants() 471 472 def _init_attributes(self): 473 474 IndividualAutos._init_attributes(self) 475 476 def _init_constants(self): 477 478 self.do_not_save_attrs(['mode', 'mode_prefix', 479 '_edges', '_ids_vtype_sumo', '_ids_edge_sumo', 480 '_id_mode', '_get_laneid_allowed', '_get_sumoinfo_from_id_lane', 481 '_space_access', 482 ]) 483 484 def def_mode(self): 485 self.mode = 'bicycle' 486 self.mode_prefix = 'ibike' 487 488 def get_ids_veh_pop(self): 489 """ 490 To be overridden by other individual vehicle types. 491 """ 492 return self.parent.ids_ibike 493 494 def get_stagetable(self): 495 return self.parent.get_plans().get_stagetable('bikerides') 496 497 def get_id_veh(self, id_stage): 498 return self._rides.ids_ibike[id_stage] 499 500 def prepare_write_xml(self): 501 """ 502 Prepare xml export. Must return export function. 503 """ 504 virtualpop = self.get_virtualpop() 505 scenario = virtualpop.get_scenario() 506 #plans = virtualpop.get_plans() 507 self._rides = self.get_stagetable() 508 self._edges = scenario.net.edges 509 #self._individualvehicle = virtualpop.get_ibikes() 510 self._ids_vtype_sumo = scenario.demand.vtypes.ids_sumo 511 self._ids_edge_sumo = self._edges.ids_sumo 512 self._id_mode = scenario.net.modes.get_id_mode(self.mode) 513 self._get_laneid_allowed = self._edges.get_laneid_allowed 514 self._get_sumoinfo_from_id_lane = scenario.net.lanes.get_sumoinfo_from_id_lane 515 self._space_access = self.space_access.get_value() 516 return self.write_xml 517 518 # def _limit_pos(self,pos,id_edge): 519 520 def write_xml(self, fd, id_stage, time_begin, indent=2): 521 rides = self._rides 522 id_veh = self.get_id_veh(id_stage) 523 # print 'write_xml',id_stage, time_begin,self.get_id_veh_xml(id_veh, id_stage) 524 # print ' ids_edge_from,ids_edge_to',rides.ids_edge_from[id_stage],rides.ids_edge_to[id_stage],self._get_laneid_allowed( rides.ids_edge_from[id_stage], self._id_mode),self._get_laneid_allowed( rides.ids_edge_to[id_stage], self._id_mode) 525 526 # TODO: actually this should go in individualvehicle 527 #time_veh_wait_after_stop = 3600 528 #plans = self.get_plans() 529 #walkstages = plans.get_stagetable('walks') 530 #rides = plans.get_stagetable('bikerides') 531 #activitystages = plans.get_stagetable('activities') 532 533 # for debug only: 534 #virtualpop = self.get_virtualpop() 535 #ids_edge_sumo = virtualpop.get_net().edges.ids_sumo 536 537 #parking = self.get_landuse().parking 538 #net = self.get_net() 539 #lanes = net.lanes 540 #edges = net.edges 541 542 #ind_ride = rides.get_inds(id_stage) 543 544 #individualvehicle = self.get_ibikes() 545 id_vtype = self.ids_vtype[id_veh] 546 547 # id_veh_ride, 548 # ids_vtypes_iveh[id_veh], 549 # ids_edges_rides_arr[ind_ride], 550 # ids_parking_from_rides_arr[ind_ride], 551 # ids_parking_to_rides_arr[ind_ride], 552 553 #id_parking_from = rides.ids_parking_from[id_stage] 554 #id_lane_from = parking.ids_lane[id_parking_from] 555 #laneindex_from = lanes.indexes[id_lane_from] 556 #pos_from = parking.positions[id_parking_from] 557 558 #id_parking_to = rides.ids_parking_to[id_stage] 559 #id_lane_to = parking.ids_lane[id_parking_to] 560 #laneindex_to = lanes.indexes[id_lane_to] 561 #pos_to = parking.positions[id_parking_to] 562 563 # write unique veh ID to prevent confusion with other veh declarations 564 fd.write(xm.start('vehicle id="%s"' % self.get_id_veh_xml(id_veh, id_stage), indent+2)) 565 566 # get start time of first stage of the plan 567 #id_plan = rides.ids_plan[id_stage] 568 #stages0, id_stage0 = self.get_plans().stagelists[id_plan][0] 569 570 # this is the time when the vehicle appers in the scenario 571 #fd.write(xm.num('depart', '%.d'%rides.times_init[id_stage])) 572 fd.write(xm.num('depart', '%.d' % time_begin)) 573 fd.write(xm.num('type', self._ids_vtype_sumo[id_vtype])) 574 fd.write(xm.num('line', self.get_id_line_xml(id_veh))) 575 #fd.write(xm.num('departPos', pos_from)) 576 #fd.write(xm.num('departLane', laneindex_from )) 577 fd.write(xm.num('from', self._ids_edge_sumo[rides.ids_edge_from[id_stage]])) 578 pos_from = rides.positions_from[id_stage] 579 pos_to = rides.positions_to[id_stage] 580 fd.write(xm.num('departPos', pos_from)) 581 fd.write(xm.num('arrivalPos', pos_to)) 582 fd.write(xm.num('departLane', 'best')) 583 584 fd.write(xm.stop()) 585 586 # write route 587 fd.write(xm.start('route', indent+4)) 588 # print ' ids_edges',rides.ids_edges[id_stage] 589 # print ' ids_sumo',self._ids_edge_sumo[rides.ids_edges[id_stage]] 590 fd.write(xm.arr('edges', self._ids_edge_sumo[rides.ids_edges[id_stage]])) 591 # fd.write(xm.arr('edges',edges.ids_sumo[rides.ids_edges[id_stage]])) 592 593 # does not seem to have an effect, always starts at base???? 594 595 #id_edge = rides.ids_edge_from[id_stage] 596 # print ' id_lane',id_lane,self._get_sumoinfo_from_id_lane(id_lane),'id_edge',id_edge,ids_edge_sumo[id_edge] 597 598 fd.write(xm.stopit()) 599 600 # write depart stop 601 fd.write(xm.start('stop', indent+4)) 602 id_lane = self._get_laneid_allowed(rides.ids_edge_from[id_stage], self._id_mode) 603 fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane))) 604 # in 0.31 the vehicle will wait until after this duration 605 # so it will be removed unless it will get a timeout function 606 #fd.write(xm.num('duration', time_veh_wait_after_stop)) 607 if pos_from > self._space_access: 608 fd.write(xm.num('startPos', pos_from - self._space_access)) 609 fd.write(xm.num('endPos', pos_from+self._space_access)) 610 else: 611 fd.write(xm.num('startPos', 0.1*pos_from)) 612 fd.write(xm.num('endPos', pos_from+self._space_access)) 613 614 fd.write(xm.num('triggered', "True")) 615 616 # chrashes with parking=True in 0.30! 617 # however if not parked the vhcle is blocking the traffic 618 # while waiting: workaround: delay departure to be shure that person already arrived 619 620 fd.write(xm.num('parking', 'True')) # in windows 0.30 parked vehicles do not depart!! 621 #fd.write(xm.num('parking', "False")) 622 fd.write(xm.stopit()) 623 624 # write arrival stop 625 fd.write(xm.start('stop', indent+4)) 626 627 id_lane = self._get_laneid_allowed(rides.ids_edge_to[id_stage], self._id_mode) 628 #id_edge = rides.ids_edge_to[id_stage] 629 # print ' id_lane',id_lane,self._get_sumoinfo_from_id_lane(id_lane),'id_edge',id_edge,ids_edge_sumo[id_edge] 630 631 fd.write(xm.num('lane', self._get_sumoinfo_from_id_lane(id_lane))) 632 fd.write(xm.num('duration', 5)) # for unboarding only 633 if pos_to > self._space_access: 634 fd.write(xm.num('startPos', pos_to - self._space_access)) 635 fd.write(xm.num('endPos', pos_to)) 636 else: 637 fd.write(xm.num('startPos', 0.1*pos_to)) 638 fd.write(xm.num('endPos', pos_to)) 639 #fd.write(xm.num('triggered', "True")) 640 fd.write(xm.stopit()) 641 642 fd.write(xm.end('vehicle', indent+2)) 643 644 645class IndividualMotorcycles(IndividualBikes): 646 647 def __init__(self, ident, population, **kwargs): 648 # print 'individualvehicle vtype id_default',vtypes.ids_sumo.get_id_from_index('passenger1') 649 self._init_objman(ident=ident, 650 parent=population, 651 name='Indiv. Moto', 652 info='Individual Motorcycle/moped database. These are privately owned motorcycles.', 653 **kwargs) 654 IndividualBikes._init_attributes(self) 655 IndividualBikes._init_constants(self) 656 657 def def_mode(self): 658 self.mode = 'moped' 659 self.mode_prefix = 'imoto' 660 661 def get_ids_veh_pop(self): 662 """ 663 To be overridden by other individual vehicle types. 664 """ 665 return self.parent.ids_imoto 666 667 def get_stagetable(self): 668 return self.parent.get_plans().get_stagetable('motorides') 669 670 def get_id_veh(self, id_stage): 671 return self._rides.ids_imoto[id_stage] 672 673 674class StrategyMixin(cm.BaseObjman): 675 def __init__(self, ident, parent=None, 676 name='Strategy mixin', info='Info on strategy.', 677 **kwargs): 678 """ 679 To be overridden. 680 """ 681 # attention parent is the Strategies table 682 self._init_objman(ident, parent, **kwargs) 683 attrsman = self.set_attrsman(cm.Attrsman(self)) 684 685 def _init_attributes(self, **kwargs): 686 # print 'StrategyMixin._init_attributes' 687 attrsman = self.get_attrsman() 688 689 def get_id_strategy(self): 690 return self.parent.names.get_id_from_index(self.get_ident()) 691 692 def get_scenario(self): 693 return self.parent.parent.get_scenario() 694 695 def get_activities(self): 696 return self.parent.parent.get_activities() 697 698 def get_virtualpop(self): 699 return self.parent.parent 700 701 def get_plans(self): 702 return self.parent.parent.plans 703 704 def clip_positions(self, positions, ids_edge): 705 lengths = self.get_scenario().net.edges.lengths[ids_edge] 706 # print 'clip_positions',positions.shape,ids_edge.shape,lengths.shape 707 positions_clip = np.clip(positions, self.dist_node_min*np.ones(len(positions), 708 dtype=np.float32), lengths-self.dist_node_min) 709 inds = lengths < 2*self.dist_node_min 710 # print ' inds.shape',inds.shape,positions_clip.shape 711 positions_clip[inds] = 0.5*lengths[inds] 712 return positions_clip 713 714 def _init_attributes_strategy(self, **kwargs): 715 attrsman = self.get_attrsman() 716 self.dist_node_min = attrsman.add(cm.AttrConf('dist_node_min', kwargs.get('dist_node_min', 40.0), 717 groupnames=['options'], 718 perm='rw', 719 name='Min. dist to nodes', 720 unit='m', 721 info='Minimum distance between starting position and node center.', 722 )) 723 # def _init_constants_strategy(self): 724 # #print '_init_constants_strategy' 725 # modes = self.get_virtualpop().get_scenario().net.modes 726 # self._id_mode_bike = modes.get_id_mode('bicycle') 727 # self._id_mode_auto = modes.get_id_mode('passenger') 728 # self._id_mode_moto = modes.get_id_mode('motorcycle') 729 # self.get_attrsman().do_not_save_attrs([ 730 # '_id_mode_bike','_id_mode_auto','_id_mode_moto', 731 # ]) 732 # print ' _id_mode_auto',self._id_mode_auto 733 734 # def are_feasible(self, ids_person): 735 # """ 736 # Returns a bool vector, with True values for 737 # persons where this strategy can be applied. 738 # """ 739 # return [] 740 741 # def is_feasible(self, id_person): 742 # """ 743 # Returns True if this strategy is feasible for this person. 744 # Overriden by specific strategy. 745 # """ 746 # return False 747 748 def preevaluate(self, ids_person): 749 """ 750 Preevaluation strategies for person IDs in vector ids_person. 751 752 Returns a preevaluation vector with a preevaluation value 753 for each person ID. The values of the preevaluation vector are as follows: 754 -1 : Strategy cannot be applied 755 0 : Stategy can be applied, but the preferred mode is not used 756 1 : Stategy can be applied, and preferred mode is part of the strategy 757 2 : Strategy uses predomunantly preferred mode 758 759 """ 760 return zeros(len(ids_person), dtype=np.int32) 761 762 def plan(self, ids_person, logger=None): 763 """ 764 Generates a plan for these person according to this strategie. 765 Overriden by specific strategy. 766 """ 767 pass 768 769 770class NoneStrategy(StrategyMixin): 771 def __init__(self, ident, parent=None, 772 name='None strategy', 773 info='With this strategy, no mobility plan is generated.', 774 **kwargs): 775 776 self._init_objman(ident, parent, name=name, info=info, **kwargs) 777 attrsman = self.set_attrsman(cm.Attrsman(self)) 778 779 780class TransitStrategy(StrategyMixin): 781 def __init__(self, ident, parent=None, 782 name='Public Transport Strategy', 783 info='With this strategy, the person uses his private auto as main transport mode. He may accept passengers or public transport with P&R', 784 **kwargs): 785 786 self._init_objman(ident, parent, name=name, info=info, **kwargs) 787 attrsman = self.set_attrsman(cm.Attrsman(self)) 788 # specific init 789 self._init_attributes() 790 self._init_constants() 791 792 def _init_attributes(self): 793 # print 'StrategyMixin._init_attributes' 794 pass 795 796 def _init_constants(self): 797 #virtualpop = self.get_virtualpop() 798 #stagetables = virtualpop.get_stagetables() 799 800 #self._walkstages = stagetables.get_stagetable('walks') 801 #self._ridestages = stagetables.get_stagetable('rides') 802 #self._activitystages = stagetables.get_stagetable('activities') 803 804 #self._plans = virtualpop.get_plans() 805 # 806 # print 'AutoStrategy._init_constants' 807 # print dir(self) 808 # self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans']) 809 810 modes = self.get_virtualpop().get_scenario().net.modes 811 self._id_mode_bike = modes.get_id_mode('bicycle') 812 self._id_mode_auto = modes.get_id_mode('passenger') 813 self._id_mode_moto = modes.get_id_mode('motorcycle') 814 self._id_mode_bus = modes.get_id_mode('bus') 815 self.get_attrsman().do_not_save_attrs([ 816 '_id_mode_bike', '_id_mode_auto', '_id_mode_moto', '_id_mode_bus' 817 ]) 818 819 def preevaluate(self, ids_person): 820 """ 821 Preevaluation strategies for person IDs in vector ids_person. 822 823 Returns a preevaluation vector with a preevaluation value 824 for each person ID. The values of the preevaluation vector are as follows: 825 -1 : Strategy cannot be applied 826 0 : Stategy can be applied, but the preferred mode is not used 827 1 : Stategy can be applied, and preferred mode is part of the strategy 828 2 : Strategy uses predomunantly preferred mode 829 830 """ 831 n_pers = len(ids_person) 832 persons = self.get_virtualpop() 833 preeval = np.zeros(n_pers, dtype=np.int32) 834 835 # TODO: here we could exclude by age or distance facilities-stops 836 837 # put 0 for persons whose preference is not public transport 838 preeval[persons.ids_mode_preferred[ids_person] != self._id_mode_bus] = 0 839 840 # put 2 for persons with car access and who prefer cars 841 preeval[persons.ids_mode_preferred[ids_person] == self._id_mode_bus] = 2 842 843 print ' TransitStrategy.preevaluate', len(np.flatnonzero(preeval)) 844 return preeval 845 846 def plan(self, ids_person, logger=None): 847 """ 848 Generates a plan for these person according to this strategie. 849 Overriden by specific strategy. 850 """ 851 print 'TransitStrategy.pan', len(ids_person) 852 #make_plans_private(self, ids_person = None, mode = 'passenger') 853 # routing necessary? 854 virtualpop = self.get_virtualpop() 855 plans = virtualpop.get_plans() # self._plans 856 demand = virtualpop.get_demand() 857 ptlines = demand.ptlines 858 859 walkstages = plans.get_stagetable('walks') 860 transitstages = plans.get_stagetable('transits') 861 activitystages = plans.get_stagetable('activities') 862 863 activities = virtualpop.get_activities() 864 activitytypes = demand.activitytypes 865 landuse = virtualpop.get_landuse() 866 facilities = landuse.facilities 867 parking = landuse.parking 868 869 scenario = virtualpop.get_scenario() 870 net = scenario.net 871 edges = net.edges 872 lanes = net.lanes 873 modes = net.modes 874 875 ptstops = net.ptstops 876 877 # print ' demand',demand 878 # print ' demand.ptlines',demand.ptlines,dir(demand.ptlines) 879 # print ' demand.ptlines.get_ptlinks()',demand.ptlines.get_ptlinks() 880 # print ' demand.virtualpop',demand.virtualpop,dir(demand.virtualpop) 881 # print ' demand.trips',demand.trips,dir(demand.trips) 882 if len(ptlines) == 0: 883 print 'WARNING in TrasitStrategy.plan: no transit services available.' 884 return False 885 886 ptlinks = ptlines.get_ptlinks() 887 ptlinktypes = ptlinks.types.choices 888 type_enter = ptlinktypes['enter'] 889 type_transit = ptlinktypes['transit'] 890 type_board = ptlinktypes['board'] 891 type_alight = ptlinktypes['alight'] 892 type_transfer = ptlinktypes['transfer'] 893 type_walk = ptlinktypes['walk'] 894 type_exit = ptlinktypes['exit'] 895 896 ptfstar = ptlinks.get_fstar() 897 pttimes = ptlinks.get_times() 898 stops_to_enter, stops_to_exit = ptlinks.get_stops_to_enter_exit() 899 900 ids_stoplane = ptstops.ids_lane 901 ids_laneedge = net.lanes.ids_edge 902 903 times_est_plan = plans.times_est 904 # here we can determine edge weights for different modes 905 906 # this could be centralized to avoid redundance 907 plans.prepare_stagetables(['walks', 'transits', 'activities']) 908 909 ids_person_act, ids_act_from, ids_act_to\ 910 = virtualpop.get_activities_from_pattern(0, ids_person=ids_person) 911 912 if len(ids_person_act) == 0: 913 print 'WARNING in TrasitStrategy.plan: no eligible persons found.' 914 return False 915 916 # temporary maps from ids_person to other parameters 917 nm = np.max(ids_person_act)+1 918 map_ids_plan = np.zeros(nm, dtype=np.int32) 919 #ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy()) 920 map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy()) 921 922 map_times = np.zeros(nm, dtype=np.int32) 923 map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit') 924 925 # set start time to plans (important!) 926 plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act] 927 928 map_ids_fac_from = np.zeros(nm, dtype=np.int32) 929 map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from] 930 931 n_plans = len(ids_person_act) 932 print 'TrasitStrategy.plan n_plans=', n_plans 933 934 # make initial activity stage 935 ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]] 936 poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]] 937 # this is the time when first activity starts 938 # first activity is normally not simulated 939 940 names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 941 durations_act_from = activities.get_durations(ids_act_from) 942 times_from = map_times[ids_person_act]-durations_act_from 943 #times_from = activities.get_times_end(ids_act_from, pdf = 'unit') 944 945 for id_plan,\ 946 time,\ 947 id_act_from,\ 948 name_acttype_from,\ 949 duration_act_from,\ 950 id_edge_from,\ 951 pos_edge_from \ 952 in zip(map_ids_plan[ids_person_act], 953 times_from, 954 ids_act_from, 955 names_acttype_from, 956 durations_act_from, 957 ids_edge_from, 958 poss_edge_from): 959 960 id_stage_act, time = activitystages.append_stage( 961 id_plan, time, 962 ids_activity=id_act_from, 963 names_activitytype=name_acttype_from, 964 durations=duration_act_from, 965 ids_lane=edges.ids_lanes[id_edge_from][0], 966 positions=pos_edge_from, 967 ) 968 969 ## 970 971 ind_act = 0 972 973 # main loop while there are persons performing 974 # an activity at index ind_act 975 while len(ids_person_act) > 0: 976 ids_plan = map_ids_plan[ids_person_act] 977 978 times_from = map_times[ids_person_act] 979 980 names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]] 981 durations_act_to = activities.get_durations(ids_act_to) 982 983 ids_fac_from = map_ids_fac_from[ids_person_act] 984 ids_fac_to = activities.ids_facility[ids_act_to] 985 986 centroids_from = facilities.centroids[ids_fac_from] 987 centroids_to = facilities.centroids[ids_fac_to] 988 989 # origin edge and position 990 ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from] 991 poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from] 992 993 # destination edge and position 994 ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to] 995 poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to] 996 997 ids_stop_from = ptstops.get_closest(centroids_from) 998 ids_stop_to = ptstops.get_closest(centroids_to) 999 1000 ids_stopedge_from = ids_laneedge[ids_stoplane[ids_stop_from]] 1001 ids_stopedge_to = ids_laneedge[ids_stoplane[ids_stop_to]] 1002 1003 # do random pos here 1004 poss_stop_from = 0.5*(ptstops.positions_from[ids_stop_from] 1005 + ptstops.positions_to[ids_stop_from]) 1006 1007 poss_stop_to = 0.5*(ptstops.positions_from[ids_stop_to] 1008 + ptstops.positions_to[ids_stop_to]) 1009 1010 i = 0.0 1011 for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, id_stop_from, id_stopedge_from, pos_stop_from, id_stop_to, id_stopedge_to, pos_stop_to\ 1012 in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, ids_stop_from, ids_stopedge_from, poss_stop_from, ids_stop_to, ids_stopedge_to, poss_stop_to): 1013 n_pers = len(ids_person_act) 1014 if logger: 1015 logger.progress(i/n_pers*100) 1016 i += 1.0 1017 print 79*'_' 1018 print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person) 1019 1020 id_stage_walk1, time = walkstages.append_stage(id_plan, time_from, 1021 id_edge_from=id_edge_from, 1022 position_edge_from=pos_edge_from, 1023 id_edge_to=id_stopedge_from, 1024 position_edge_to=pos_stop_from, # -7.0, 1025 ) 1026 1027 # print ' id_stopedge_from',id_stopedge_from 1028 # print ' pos_stop_from',pos_stop_from 1029 1030 # print 1031 # print ' id_stopedge_to',id_stopedge_to 1032 # print ' pos_stop_to',pos_stop_to 1033 # print 1034 # print ' id_stop_from',id_stop_from 1035 # print ' id_stop_to',id_stop_to 1036 1037 durations, linktypes, ids_line, ids_fromstop, ids_tostop =\ 1038 ptlinks.route(id_stop_from, id_stop_to, 1039 fstar=ptfstar, times=pttimes, 1040 stops_to_enter=stops_to_enter, 1041 stops_to_exit=stops_to_exit) 1042 1043 # print ' routing done. make plan..' 1044 1045 if len(linktypes) > 0: 1046 if linktypes[-1] == type_walk: # is last stage a walk? 1047 # remove it, because will go directly to destination 1048 linktypes = linktypes[:-1] 1049 ids_line = ids_line[:-1] 1050 durations = durations[:-1] 1051 ids_fromstop = ids_fromstop[:-1] 1052 ids_tostop = ids_tostop[:-1] 1053 1054 # print ' ids_line ',ids_line 1055 # print ' ids_fromstop',ids_fromstop 1056 # print ' ids_tostop ',ids_tostop 1057 1058 if len(linktypes) > 0: # is there any public transport line to take? 1059 1060 # go though PT links and generate transits and walks to trasfer 1061 ids_stopedge_from = ids_laneedge[ids_stoplane[ids_fromstop]] 1062 ids_stopedge_to = ids_laneedge[ids_stoplane[ids_tostop]] 1063 poss_stop_from = 0.5*(ptstops.positions_from[ids_fromstop] 1064 + ptstops.positions_to[ids_fromstop]) 1065 poss_stop_to = 0.5*(ptstops.positions_from[ids_tostop] 1066 + ptstops.positions_to[ids_tostop]) 1067 1068 # this is wait time buffer to be added to the successive stage 1069 # as waiting is currently not modelled as an extra stage 1070 duration_wait = 0.0 1071 1072 # create stages for PT 1073 for linktype, id_line, duration,\ 1074 id_stopedge_from, pos_fromstop,\ 1075 id_stopedge_to, pos_tostop in\ 1076 zip(linktypes, 1077 ids_line, 1078 durations, 1079 ids_stopedge_from, poss_stop_from, 1080 ids_stopedge_to, poss_stop_to, 1081 ): 1082 print ' stage for linktype %2d fromedge %s toedge %s' % ( 1083 linktype, edges.ids_sumo[id_stopedge_from], edges.ids_sumo[id_stopedge_to]) 1084 1085 print ' id_stopedge_from,id_stopedge_to', id_stopedge_from, id_stopedge_to 1086 if linktype == type_transit: # transit! 1087 print ' add transit' 1088 id_stage_transit, time = transitstages.append_stage( 1089 id_plan, time, 1090 id_line=id_line, 1091 duration=duration+duration_wait, 1092 id_fromedge=id_stopedge_from, 1093 id_toedge=id_stopedge_to, 1094 ) 1095 duration_wait = 0.0 1096 1097 elif linktype == type_walk: # walk to transfer 1098 print ' add transfer' 1099 id_stage_transfer, time = walkstages.append_stage( 1100 id_plan, time, 1101 id_edge_from=id_stopedge_from, 1102 position_edge_from=pos_fromstop, 1103 id_edge_to=id_stopedge_to, 1104 position_edge_to=pos_tostop, 1105 duration=duration+duration_wait, 1106 ) 1107 duration_wait = 0.0 1108 1109 else: # all other link time are no modelld 1110 # do not do anything , just add wait time to next stage 1111 print ' add duration', duration 1112 duration_wait += duration 1113 1114 # walk from final stop to activity 1115 # print ' Stage for linktype %2d fromedge %s toedge %s'%(linktype, edges.ids_sumo[id_stopedge_to],edges.ids_sumo[id_edge_to] ) 1116 id_stage_walk2, time = walkstages.append_stage(id_plan, time, 1117 id_edge_from=id_stopedge_to, 1118 position_edge_from=pos_tostop, 1119 id_edge_to=id_edge_to, 1120 position_edge_to=pos_edge_to, 1121 ) 1122 1123 else: 1124 # there is no public transport line linking these nodes. 1125 # Modify walk directly from home to activity 1126 time = walkstages.modify_stage(id_stage_walk1, time_from, 1127 id_edge_from=id_edge_from, 1128 position_edge_from=pos_edge_from, 1129 id_edge_to=id_edge_to, 1130 position_edge_to=pos_edge_to, 1131 ) 1132 1133 # update time for trips estimation for this plan 1134 plans.times_est[id_plan] += time-time_from 1135 1136 # define current end time without last activity duration 1137 plans.times_end[id_plan] = time 1138 1139 id_stage_act, time = activitystages.append_stage( 1140 id_plan, time, 1141 ids_activity=id_act_to, 1142 names_activitytype=name_acttype_to, 1143 durations=duration_act_to, 1144 ids_lane=edges.ids_lanes[id_edge_to][0], 1145 positions=pos_edge_to, 1146 ) 1147 1148 # store time for next iteration in case other activities are 1149 # following 1150 map_times[id_person] = time 1151 1152 # select persons and activities for next setp 1153 ind_act += 1 1154 ids_person_act, ids_act_from, ids_act_to\ 1155 = virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act) 1156 1157 1158class WalkStrategy(StrategyMixin): 1159 def __init__(self, ident, parent=None, 1160 name='Walk Strategy', 1161 info='With this strategy, the person walks to all destinations.', 1162 **kwargs): 1163 1164 self._init_objman(ident, parent, name=name, info=info, **kwargs) 1165 attrsman = self.set_attrsman(cm.Attrsman(self)) 1166 # specific init 1167 self._init_attributes() 1168 self._init_constants() 1169 1170 def _init_attributes(self): 1171 # print 'StrategyMixin._init_attributes' 1172 pass 1173 1174 def _init_constants(self): 1175 #virtualpop = self.get_virtualpop() 1176 #stagetables = virtualpop.get_stagetables() 1177 1178 #self._walkstages = stagetables.get_stagetable('walks') 1179 #self._ridestages = stagetables.get_stagetable('rides') 1180 #self._activitystages = stagetables.get_stagetable('activities') 1181 1182 #self._plans = virtualpop.get_plans() 1183 # 1184 # print 'AutoStrategy._init_constants' 1185 # print dir(self) 1186 # self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans']) 1187 1188 modes = self.get_virtualpop().get_scenario().net.modes 1189 self._id_mode_bike = modes.get_id_mode('bicycle') 1190 self._id_mode_auto = modes.get_id_mode('passenger') 1191 self._id_mode_moto = modes.get_id_mode('motorcycle') 1192 self._id_mode_bus = modes.get_id_mode('bus') 1193 self._id_mode_ped = modes.get_id_mode('pedestrian') 1194 self.get_attrsman().do_not_save_attrs([ 1195 '_id_mode_bike', '_id_mode_auto', '_id_mode_moto', 1196 '_id_mode_bus', '_id_mode_ped', 1197 ]) 1198 1199 def preevaluate(self, ids_person): 1200 """ 1201 Preevaluation strategies for person IDs in vector ids_person. 1202 1203 Returns a preevaluation vector with a preevaluation value 1204 for each person ID. The values of the preevaluation vector are as follows: 1205 -1 : Strategy cannot be applied 1206 0 : Stategy can be applied, but the preferred mode is not used 1207 1 : Stategy can be applied, and preferred mode is part of the strategy 1208 2 : Strategy uses predomunantly preferred mode 1209 1210 """ 1211 n_pers = len(ids_person) 1212 persons = self.get_virtualpop() 1213 preeval = np.zeros(n_pers, dtype=np.int32) 1214 1215 # TODO: here we could exclude by age or distance facilities-stops 1216 1217 # put 0 for persons whose preference is not public transport 1218 preeval[persons.ids_mode_preferred[ids_person] != self._id_mode_ped] = 0 1219 1220 # put 2 for persons with car access and who prefer cars 1221 preeval[persons.ids_mode_preferred[ids_person] == self._id_mode_ped] = 2 1222 1223 print ' WalkStrategy.preevaluate', len(np.flatnonzero(preeval)) 1224 return preeval 1225 1226 def plan(self, ids_person, logger=None): 1227 """ 1228 Generates a plan for these person according to this strategie. 1229 Overriden by specific strategy. 1230 """ 1231 print 'WalkStrategy.pan', len(ids_person) 1232 #make_plans_private(self, ids_person = None, mode = 'passenger') 1233 # routing necessary? 1234 virtualpop = self.get_virtualpop() 1235 plans = virtualpop.get_plans() # self._plans 1236 demand = virtualpop.get_demand() 1237 #ptlines = demand.ptlines 1238 1239 walkstages = plans.get_stagetable('walks') 1240 #transitstages = plans.get_stagetable('transits') 1241 activitystages = plans.get_stagetable('activities') 1242 1243 activities = virtualpop.get_activities() 1244 activitytypes = demand.activitytypes 1245 landuse = virtualpop.get_landuse() 1246 facilities = landuse.facilities 1247 #parking = landuse.parking 1248 1249 scenario = virtualpop.get_scenario() 1250 net = scenario.net 1251 edges = net.edges 1252 lanes = net.lanes 1253 modes = net.modes 1254 1255 #ptstops = net.ptstops 1256 1257 ids_laneedge = net.lanes.ids_edge 1258 1259 times_est_plan = plans.times_est 1260 # here we can determine edge weights for different modes 1261 1262 # this could be centralized to avoid redundance 1263 plans.prepare_stagetables(['walks', 'activities']) 1264 1265 ids_person_act, ids_act_from, ids_act_to\ 1266 = virtualpop.get_activities_from_pattern(0, ids_person=ids_person) 1267 1268 if len(ids_person_act) == 0: 1269 print 'WARNING in WalkStrategy.plan: no eligible persons found.' 1270 return False 1271 1272 # temporary maps from ids_person to other parameters 1273 nm = np.max(ids_person_act)+1 1274 map_ids_plan = np.zeros(nm, dtype=np.int32) 1275 #ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy()) 1276 map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy()) 1277 1278 map_times = np.zeros(nm, dtype=np.int32) 1279 map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit') 1280 1281 # set start time to plans (important!) 1282 plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act] 1283 1284 map_ids_fac_from = np.zeros(nm, dtype=np.int32) 1285 map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from] 1286 1287 n_plans = len(ids_person_act) 1288 print 'TrasitStrategy.plan n_plans=', n_plans 1289 1290 # make initial activity stage 1291 ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]] 1292 poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]] 1293 # this is the time when first activity starts 1294 # first activity is normally not simulated 1295 1296 names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 1297 durations_act_from = activities.get_durations(ids_act_from) 1298 times_from = map_times[ids_person_act]-durations_act_from 1299 #times_from = activities.get_times_end(ids_act_from, pdf = 'unit') 1300 1301 for id_plan,\ 1302 time,\ 1303 id_act_from,\ 1304 name_acttype_from,\ 1305 duration_act_from,\ 1306 id_edge_from,\ 1307 pos_edge_from \ 1308 in zip(map_ids_plan[ids_person_act], 1309 times_from, 1310 ids_act_from, 1311 names_acttype_from, 1312 durations_act_from, 1313 ids_edge_from, 1314 poss_edge_from): 1315 1316 id_stage_act, time = activitystages.append_stage( 1317 id_plan, time, 1318 ids_activity=id_act_from, 1319 names_activitytype=name_acttype_from, 1320 durations=duration_act_from, 1321 ids_lane=edges.ids_lanes[id_edge_from][0], 1322 positions=pos_edge_from, 1323 ) 1324 1325 ## 1326 1327 ind_act = 0 1328 1329 # main loop while there are persons performing 1330 # an activity at index ind_act 1331 while len(ids_person_act) > 0: 1332 ids_plan = map_ids_plan[ids_person_act] 1333 1334 times_from = map_times[ids_person_act] 1335 1336 names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]] 1337 durations_act_to = activities.get_durations(ids_act_to) 1338 1339 ids_fac_from = map_ids_fac_from[ids_person_act] 1340 ids_fac_to = activities.ids_facility[ids_act_to] 1341 1342 centroids_from = facilities.centroids[ids_fac_from] 1343 centroids_to = facilities.centroids[ids_fac_to] 1344 1345 # origin edge and position 1346 ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from] 1347 poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from] 1348 1349 # destination edge and position 1350 ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to] 1351 poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to] 1352 1353 #ids_stop_from = ptstops.get_closest(centroids_from) 1354 #ids_stop_to = ptstops.get_closest(centroids_to) 1355 1356 #ids_stopedge_from = ids_laneedge[ids_stoplane[ids_stop_from]] 1357 #ids_stopedge_to = ids_laneedge[ids_stoplane[ids_stop_to]] 1358 1359 # do random pos here 1360 # poss_stop_from = 0.5*( ptstops.positions_from[ids_stop_from]\ 1361 # +ptstops.positions_to[ids_stop_from]) 1362 1363 # poss_stop_to = 0.5*( ptstops.positions_from[ids_stop_to]\ 1364 # +ptstops.positions_to[ids_stop_to]) 1365 1366 i = 0.0 1367 for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, \ 1368 in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to): 1369 n_pers = len(ids_person_act) 1370 if logger: 1371 logger.progress(i/n_pers*100) 1372 i += 1.0 1373 print 79*'_' 1374 print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person) 1375 1376 id_stage_walk1, time = walkstages.append_stage(id_plan, time_from, 1377 id_edge_from=id_edge_from, 1378 position_edge_from=pos_edge_from, 1379 id_edge_to=id_edge_to, 1380 position_edge_to=pos_edge_to, # -7.0, 1381 ) 1382 1383 # update time for trips estimation for this plan 1384 plans.times_est[id_plan] += time-time_from 1385 1386 # define current end time without last activity duration 1387 plans.times_end[id_plan] = time 1388 1389 id_stage_act, time = activitystages.append_stage( 1390 id_plan, time, 1391 ids_activity=id_act_to, 1392 names_activitytype=name_acttype_to, 1393 durations=duration_act_to, 1394 ids_lane=edges.ids_lanes[id_edge_to][0], 1395 positions=pos_edge_to, 1396 ) 1397 1398 # store time for next iteration in case other activities are 1399 # following 1400 map_times[id_person] = time 1401 1402 # select persons and activities for next setp 1403 ind_act += 1 1404 ids_person_act, ids_act_from, ids_act_to\ 1405 = virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act) 1406 1407 1408class AutoStrategy(StrategyMixin): 1409 def __init__(self, ident, parent=None, 1410 name='Auto strategy', 1411 info='With this strategy, the person uses his private auto as main transport mode.', 1412 **kwargs): 1413 1414 self._init_objman(ident, parent, name=name, info=info, **kwargs) 1415 attrsman = self.set_attrsman(cm.Attrsman(self)) 1416 # specific init 1417 self._init_attributes() 1418 self._init_constants() 1419 1420 def _init_attributes(self): 1421 # print 'StrategyMixin._init_attributes' 1422 pass 1423 1424 def _init_constants(self): 1425 #virtualpop = self.get_virtualpop() 1426 #stagetables = virtualpop.get_stagetables() 1427 1428 #self._walkstages = stagetables.get_stagetable('walks') 1429 #self._ridestages = stagetables.get_stagetable('rides') 1430 #self._activitystages = stagetables.get_stagetable('activities') 1431 1432 #self._plans = virtualpop.get_plans() 1433 # 1434 # print 'AutoStrategy._init_constants' 1435 # print dir(self) 1436 # self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans']) 1437 1438 modes = self.get_virtualpop().get_scenario().net.modes 1439 self._id_mode_bike = modes.get_id_mode('bicycle') 1440 self._id_mode_auto = modes.get_id_mode('passenger') 1441 self._id_mode_moto = modes.get_id_mode('motorcycle') 1442 self.get_attrsman().do_not_save_attrs([ 1443 '_id_mode_bike', '_id_mode_auto', '_id_mode_moto', 1444 ]) 1445 1446 def preevaluate(self, ids_person): 1447 """ 1448 Preevaluation strategies for person IDs in vector ids_person. 1449 1450 Returns a preevaluation vector with a preevaluation value 1451 for each person ID. The values of the preevaluation vector are as follows: 1452 -1 : Strategy cannot be applied 1453 0 : Stategy can be applied, but the preferred mode is not used 1454 1 : Stategy can be applied, and preferred mode is part of the strategy 1455 2 : Strategy uses predomunantly preferred mode 1456 1457 """ 1458 n_pers = len(ids_person) 1459 print 'Autostrategy.preevaluate', n_pers, 'persons' 1460 persons = self.get_virtualpop() 1461 preeval = np.zeros(n_pers, dtype=np.int32) 1462 1463 # put -1 for persons without car access 1464 preeval[persons.ids_iauto[ids_person] == -1] = -1 1465 print ' persons having no auto', len(np.flatnonzero(persons.ids_iauto[ids_person] == -1)) 1466 1467 # put 0 for persons with car but with a different preferred mode 1468 preeval[(persons.ids_iauto[ids_person] > -1) 1469 & (persons.ids_mode_preferred[ids_person] != self._id_mode_auto)] = 0 1470 1471 print ' persons with car but with a different preferred mode', len(np.flatnonzero( 1472 (persons.ids_iauto[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] != self._id_mode_auto))) 1473 1474 # put 2 for persons with car access and who prefer the car 1475 preeval[(persons.ids_iauto[ids_person] > -1) 1476 & (persons.ids_mode_preferred[ids_person] == self._id_mode_auto)] = 2 1477 print ' persons with car access and who prefer the car', len(np.flatnonzero( 1478 (persons.ids_iauto[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] == self._id_mode_auto))) 1479 1480 return preeval 1481 1482 # def are_feasible(self, ids_person): 1483 # """ 1484 # Returns a bool vector, with True values for 1485 # persons where this strategy can be applied. 1486 # """ 1487 # persons = self.get_virtualpop() 1488 # 1489 # # check if person has a car 1490 # # one may also check if there is parking available 1491 # # at all desinations 1492 # return persons.ids_iautos[ids_person] >= 0 1493 1494 def plan(self, ids_person, logger=None): 1495 """ 1496 Generates a plan for these person according to this strategie. 1497 Overriden by specific strategy. 1498 """ 1499 #make_plans_private(self, ids_person = None, mode = 'passenger') 1500 # routing necessary? 1501 virtualpop = self.get_virtualpop() 1502 plans = virtualpop.get_plans() # self._plans 1503 walkstages = plans.get_stagetable('walks') 1504 ridestages = plans.get_stagetable('autorides') 1505 activitystages = plans.get_stagetable('activities') 1506 1507 activities = virtualpop.get_activities() 1508 activitytypes = virtualpop.get_demand().activitytypes 1509 landuse = virtualpop.get_landuse() 1510 facilities = landuse.facilities 1511 parking = landuse.parking 1512 1513 scenario = virtualpop.get_scenario() 1514 edges = scenario.net.edges 1515 lanes = scenario.net.lanes 1516 modes = scenario.net.modes 1517 1518 #times_est_plan = plans.times_est 1519 1520 # here we can determine edge weights for different modes 1521 plans.prepare_stagetables(['walks', 'autorides', 'activities']) 1522 1523 # get initial travel times for persons. 1524 # initial travel times depend on the initial activity 1525 1526 landuse.parking.clear_booking() 1527 1528 ids_person_act, ids_act_from, ids_act_to\ 1529 = virtualpop.get_activities_from_pattern(0, ids_person=ids_person) 1530 1531 if len(ids_person_act) == 0: 1532 print 'WARNING in Autostrategy.plan: no eligible persons found.' 1533 return False 1534 1535 # ok 1536 1537 # temporary maps from ids_person to other parameters 1538 nm = np.max(ids_person_act)+1 1539 map_ids_plan = np.zeros(nm, dtype=np.int32) 1540 #ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy()) 1541 map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy()) 1542 1543 # err 1544 map_times = np.zeros(nm, dtype=np.int32) 1545 map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit') 1546 1547 # set start time to plans (important!) 1548 plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act] 1549 1550 map_ids_fac_from = np.zeros(nm, dtype=np.int32) 1551 map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from] 1552 1553 # err 1554 map_ids_parking_from = np.zeros(nm, dtype=np.int32) 1555 ids_parking_from, inds_vehparking = parking.get_closest_parkings(virtualpop.ids_iauto[ids_person_act], 1556 facilities.centroids[activities.ids_facility[ids_act_from]]) 1557 if len(ids_parking_from) == 0: 1558 return False 1559 1560 # err 1561 1562 map_ids_parking_from[ids_person_act] = ids_parking_from 1563 1564 n_plans = len(ids_person_act) 1565 print 'AutoStrategy.plan n_plans=', n_plans 1566 # print ' map_ids_parking_from[ids_person_act].shape',map_ids_parking_from[ids_person_act].shape 1567 # set initial activity 1568 # this is because the following steps start with travel 1569 # and set the next activity 1570 #names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 1571 # for id_plan 1572 1573 ind_act = 0 1574 1575 # make initial activity stage 1576 ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]] 1577 poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]] 1578 # this is the time when first activity starts 1579 # first activity is normally not simulated 1580 1581 names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 1582 durations_act_from = activities.get_durations(ids_act_from) 1583 times_from = map_times[ids_person_act]-durations_act_from 1584 #times_from = activities.get_times_end(ids_act_from, pdf = 'unit') 1585 1586 for id_plan,\ 1587 time,\ 1588 id_act_from,\ 1589 name_acttype_from,\ 1590 duration_act_from,\ 1591 id_edge_from,\ 1592 pos_edge_from \ 1593 in zip(map_ids_plan[ids_person_act], 1594 times_from, 1595 ids_act_from, 1596 names_acttype_from, 1597 durations_act_from, 1598 ids_edge_from, 1599 poss_edge_from): 1600 1601 id_stage_act, time = activitystages.append_stage( 1602 id_plan, time, 1603 ids_activity=id_act_from, 1604 names_activitytype=name_acttype_from, 1605 durations=duration_act_from, 1606 ids_lane=edges.ids_lanes[id_edge_from][0], 1607 positions=pos_edge_from, 1608 ) 1609 1610 # main loop while there are persons performing 1611 # an activity at index ind_act 1612 while len(ids_person_act) > 0: 1613 ids_plan = map_ids_plan[ids_person_act] 1614 ids_veh = virtualpop.ids_iauto[ids_person_act] 1615 #inds_pers = virtualpop.get_inds(ids_person) 1616 # self.persons.cols.mode_preferred[inds_pers]='private' 1617 1618 times_from = map_times[ids_person_act] 1619 1620 names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]] 1621 durations_act_to = activities.get_durations(ids_act_to) 1622 1623 ids_fac_from = map_ids_fac_from[ids_person_act] 1624 ids_fac_to = activities.ids_facility[ids_act_to] 1625 1626 centroids_to = facilities.centroids[ids_fac_to] 1627 1628 # origin edge and position 1629 ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from] 1630 poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from] 1631 1632 # this method will find and occupy parking space 1633 ids_parking_from = map_ids_parking_from[ids_person_act] 1634 1635 # print ' ids_veh.shape',ids_veh.shape 1636 # print ' centroids_to.shape',centroids_to.shape 1637 ids_parking_to, inds_vehparking = parking.get_closest_parkings(ids_veh, centroids_to) 1638 1639 ids_lane_parking_from = parking.ids_lane[ids_parking_from] 1640 ids_edge_parking_from = lanes.ids_edge[ids_lane_parking_from] 1641 poss_edge_parking_from = parking.positions[ids_parking_from] 1642 1643 # print ' ids_parking_to.shape',ids_parking_to.shape 1644 # print ' np.max(parking.get_ids()), np.max(ids_parking_to)',np.max(parking.get_ids()), np.max(ids_parking_to) 1645 ids_lane_parking_to = parking.ids_lane[ids_parking_to] 1646 ids_edge_parking_to = lanes.ids_edge[ids_lane_parking_to] 1647 poss_edge_parking_to = parking.positions[ids_parking_to] 1648 1649 # destination edge and position 1650 ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to] 1651 poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to] 1652 1653 i = 0.0 1654 n_pers = len(ids_person_act) 1655 for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_parking_from, pos_edge_parking_from, id_parking_from, id_parking_to, id_edge_parking_to, pos_edge_parking_to, id_edge_to, pos_edge_to\ 1656 in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_parking_from, poss_edge_parking_from, ids_parking_from, ids_parking_to, ids_edge_parking_to, poss_edge_parking_to, ids_edge_to, poss_edge_to): 1657 if logger: 1658 logger.progress(i/n_pers*100) 1659 i += 1.0 1660 #plans.set_row(id_plan, ids_person = id_person, ids_strategy = self.get_id_strategy()) 1661 1662 #times_est_plan[id_plan] = time-time_start 1663 # map_times[id_person] = self.plan_activity(\ 1664 # id_person, id_plan, time_from, 1665 # id_act_from, id_act_to, 1666 # name_acttype_to, duration_act_to, 1667 # id_veh, 1668 # id_edge_from, pos_edge_from, 1669 # id_parking_from, id_edge_parking_from, pos_edge_parking_from, 1670 # id_parking_to, id_edge_parking_to, pos_edge_parking_to, 1671 # id_edge_to, pos_edge_to, edges.ids_lanes[id_edge_to][0]) 1672 1673 # start creating stages for activity 1674 id_stage_walk1, time = walkstages.append_stage( 1675 id_plan, time_from, 1676 id_edge_from=id_edge_from, 1677 position_edge_from=pos_edge_from, 1678 id_edge_to=id_edge_parking_from, 1679 position_edge_to=pos_edge_parking_from-1.5, # wait 1.5 m before nose of parked car 1680 ) 1681 1682 # ride from car parking to road edge near activity 1683 id_stage_car, time = ridestages.append_stage( 1684 id_plan, time, 1685 id_veh=id_veh, 1686 # delay to be sure that person arrived!(workaround in combination with parking=False) 1687 time_init=time+30, # time_from, 1688 id_parking_from=id_parking_from, 1689 id_parking_to=id_parking_to, 1690 # TODO: here we could use id_edge_to as via edge to emulate search for parking 1691 ) 1692 if id_stage_car >= 0: 1693 # print ' car ride successful' 1694 id_stage_walk2, time = walkstages.append_stage( 1695 id_plan, time, 1696 id_edge_from=id_edge_parking_to, 1697 position_edge_from=pos_edge_parking_to-1.5, # ecessary? 1698 id_edge_to=id_edge_to, 1699 position_edge_to=pos_edge_to, 1700 ) 1701 else: 1702 # print ' parking not connected or distance too short, modify first walk and go directly to activity' 1703 # print ' id_stage_walk1',id_stage_walk1,type(id_stage_walk1) 1704 # print ' id_edge_from',id_edge_from 1705 # print ' position_edge_from',position_edge_from 1706 # print ' id_edge_to',id_edge_to 1707 # print ' position_edge_to',position_edge_to 1708 1709 time = walkstages.modify_stage( 1710 id_stage_walk1, time_from, 1711 id_edge_from=id_edge_from, 1712 position_edge_from=pos_edge_from, 1713 id_edge_to=id_edge_to, 1714 position_edge_to=pos_edge_to, 1715 ) 1716 1717 # store time estimation for this plan 1718 # note that these are the travel times, no activity time 1719 plans.times_est[id_plan] += time-time_from 1720 1721 # define current end time without last activity duration 1722 plans.times_end[id_plan] = time 1723 1724 # finally add activity and respective duration 1725 1726 id_stage_act, time = activitystages.append_stage( 1727 id_plan, time, 1728 ids_activity=id_act_to, 1729 names_activitytype=name_acttype_to, 1730 durations=duration_act_to, 1731 ids_lane=edges.ids_lanes[id_edge_to][0], 1732 positions=pos_edge_to, 1733 ) 1734 1735 map_times[id_person] = time 1736 # return time 1737 ## 1738 1739 # select persons and activities for next setp 1740 ind_act += 1 1741 ids_person_act, ids_act_from, ids_act_to\ 1742 = virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act) 1743 # update timing with (random) activity duration!! 1744 1745 return True 1746 1747 def plan_activity(self, id_person, id_plan, time_start, 1748 id_act_from, id_act_to, 1749 name_acttype_to, duration_act_to, 1750 id_veh, 1751 id_edge_from, pos_edge_from, 1752 id_parking_from, id_edge_parking_from, pos_edge_parking_from, 1753 id_parking_to, id_edge_parking_to, pos_edge_parking_to, 1754 id_edge_to, pos_edge_to, id_lane_to): 1755 print 79*'_' 1756 print ' id_plan=%d, id_person=%d, ids_veh=%d' % (id_plan, id_person, id_veh) 1757 1758 plans = self.get_virtualpop().get_plans() 1759 #stagetables = virtualpop.get_stagetables() 1760 walkstages = plans.get_stagetable('walks') 1761 ridestages = plans.get_stagetable('autorides') 1762 activitystages = plans.get_stagetable('activities') 1763 1764 id_stage_walk1, time = walkstages.append_stage( 1765 id_plan, time_start, 1766 id_edge_from=id_edge_from, 1767 position_edge_from=pos_edge_from, 1768 id_edge_to=id_edge_parking_from, 1769 position_edge_to=pos_edge_parking_from-1.5, # wait 1.5 m before nose of parked car 1770 ) 1771 1772 # ride from car parking to road edge near activity 1773 id_stage_car, time = ridestages.append_stage( 1774 id_plan, time, 1775 id_veh=id_veh, 1776 # delay to be sure that person arrived!(workaround in combination with parking=False) 1777 time_init=time+30, # time_start, 1778 id_parking_from=id_parking_from, 1779 id_parking_to=id_parking_to, 1780 # TODO: here we could use id_edge_to as via edge to emulate search for parking 1781 ) 1782 if id_stage_car >= 0: 1783 # print ' car ride successful' 1784 id_stage_walk2, time = walkstages.append_stage( 1785 id_plan, time, 1786 id_edge_from=id_edge_parking_to, 1787 position_edge_from=pos_edge_parking_to-1.5, # ecessary? 1788 id_edge_to=id_edge_to, 1789 position_edge_to=pos_edge_to, 1790 ) 1791 else: 1792 # print ' parking not connected or distance too short, modify first walk and go directly to activity' 1793 # print ' id_stage_walk1',id_stage_walk1,type(id_stage_walk1) 1794 # print ' id_edge_from',id_edge_from 1795 # print ' position_edge_from',position_edge_from 1796 # print ' id_edge_to',id_edge_to 1797 # print ' position_edge_to',position_edge_to 1798 1799 time = walkstages.modify_stage( 1800 id_stage_walk1, time_start, 1801 id_edge_from=id_edge_from, 1802 position_edge_from=pos_edge_from, 1803 id_edge_to=id_edge_to, 1804 position_edge_to=pos_edge_to, 1805 ) 1806 1807 # store time estimation for this plan 1808 # note that these are the travel times, no activity time 1809 plans.times_est[id_plan] += time-time_start 1810 1811 # define current end time without last activity duration 1812 plans.times_end[id_plan] = time 1813 1814 # finally add activity and respective duration 1815 id_stage_act, time = activitystages.append_stage( 1816 id_plan, time, 1817 ids_activity=id_act_to, 1818 names_activitytype=name_acttype_to, 1819 durations=duration_act_to, 1820 ids_lane=id_lane_to, 1821 positions=pos_edge_to, 1822 ) 1823 1824 return time 1825 1826 1827class BikeStrategy(StrategyMixin): 1828 def __init__(self, ident, parent=None, 1829 name='Bike strategy', 1830 info='With this strategy, the person uses his private bike as main transport mode.', 1831 **kwargs): 1832 1833 self._init_objman(ident, parent, name=name, info=info, **kwargs) 1834 attrsman = self.set_attrsman(cm.Attrsman(self)) 1835 # specific init 1836 self._init_attributes(**kwargs) 1837 self._init_constants() 1838 1839 def _init_attributes(self, **kwargs): 1840 # print 'StrategyMixin._init_attributes' 1841 attrsman = self.get_attrsman() 1842 1843 self._init_attributes_strategy(**kwargs) 1844 self.n_iter_bikeacces_max = attrsman.add(cm.AttrConf('n_iter_bikeacces_max', kwargs.get('n_iter_bikeacces_max', 5), 1845 groupnames=['options'], 1846 perm='rw', 1847 name='Max. bike access search iterations', 1848 info='Max. number of iterations while searching an edge with bike access.', 1849 )) 1850 1851 self.length_edge_min = attrsman.add(cm.AttrConf('length_edge_min', kwargs.get('length_edge_min', 20.0), 1852 groupnames=['options'], 1853 perm='rw', 1854 name='Min. edge length search', 1855 unit='m', 1856 info='Min. edge length when searching an edge with bike access.', 1857 )) 1858 1859 def _init_constants(self): 1860 #virtualpop = self.get_virtualpop() 1861 #stagetables = virtualpop.get_stagetables() 1862 1863 #self._walkstages = stagetables.get_stagetable('walks') 1864 #self._ridestages = stagetables.get_stagetable('rides') 1865 #self._activitystages = stagetables.get_stagetable('activities') 1866 1867 #self._plans = virtualpop.get_plans() 1868 # 1869 # print 'AutoStrategy._init_constants' 1870 # print dir(self) 1871 # self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans']) 1872 1873 modes = self.get_virtualpop().get_scenario().net.modes 1874 self._id_mode_ped = modes.get_id_mode('pedestrian') 1875 self._id_mode_bike = modes.get_id_mode('bicycle') 1876 self._id_mode_auto = modes.get_id_mode('passenger') 1877 self._id_mode_moto = modes.get_id_mode('motorcycle') 1878 self._edges = self.get_virtualpop().get_scenario().net.edges 1879 self.get_attrsman().do_not_save_attrs([ 1880 '_id_mode_bike', '_id_mode_auto', '_id_mode_moto', 1881 '_id_mode_ped', 1882 '_edges']) 1883 1884 def preevaluate(self, ids_person): 1885 """ 1886 Preevaluation strategies for person IDs in vector ids_person. 1887 1888 Returns a preevaluation vector with a preevaluation value 1889 for each person ID. The values of the preevaluation vector are as follows: 1890 -1 : Strategy cannot be applied 1891 0 : Stategy can be applied, but the preferred mode is not used 1892 1 : Stategy can be applied, and preferred mode is part of the strategy 1893 2 : Strategy uses predomunantly preferred mode 1894 1895 """ 1896 n_pers = len(ids_person) 1897 print 'BikeStrategy.preevaluate', n_pers, 'persons' 1898 persons = self.get_virtualpop() 1899 preeval = np.zeros(n_pers, dtype=np.int32) 1900 1901 # put -1 for persons without car access 1902 preeval[persons.ids_ibike[ids_person] == -1] = -1 1903 print ' persons having no bike', len(np.flatnonzero(persons.ids_ibike[ids_person] == -1)) 1904 1905 # put 0 for persons with bike but with a different preferred mode 1906 preeval[(persons.ids_ibike[ids_person] > -1) 1907 & (persons.ids_mode_preferred[ids_person] != self._id_mode_bike)] = 0 1908 1909 print ' persons with bike but with a different preferred mode', len(np.flatnonzero( 1910 (persons.ids_ibike[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] != self._id_mode_bike))) 1911 1912 # put 2 for persons with bike access and who prefer the bikr 1913 preeval[(persons.ids_ibike[ids_person] > -1) 1914 & (persons.ids_mode_preferred[ids_person] == self._id_mode_auto)] = 2 1915 print ' persons with car access and who prefer the car', len(np.flatnonzero( 1916 (persons.ids_ibike[ids_person] > -1) & (persons.ids_mode_preferred[ids_person] == self._id_mode_bike))) 1917 1918 return preeval 1919 1920 def get_edge_bikeaccess(self, id_edge, is_search_backward=False): 1921 1922 # print 'get_edge_bikeaccess',id_edge, is_search_backward,'id_sumo',self._edges.ids_sumo[id_edge] 1923 id_mode = self._id_mode_bike 1924 id_mode_ped = self._id_mode_ped 1925 get_accesslevel = self._edges.get_accesslevel 1926 1927 if is_search_backward: 1928 get_next = self._edges.get_incoming 1929 else: 1930 get_next = self._edges.get_outgoing 1931 1932 edgelengths = self._edges.lengths 1933 #ids_tried = set() 1934 ids_current = [id_edge] 1935 id_bikeedge = -1 1936 pos = 0.0 1937 n = 0 1938 while (id_bikeedge < 0) & (n < self.n_iter_bikeacces_max): 1939 n += 1 1940 ids_new = [] 1941 for id_edge_test, is_long_enough in zip(ids_current, edgelengths[ids_current] > self.length_edge_min): 1942 # print ' check id',id_edge_test, is_long_enough,get_accesslevel(id_edge_test, id_mode) 1943 if is_long_enough & (get_accesslevel(id_edge_test, id_mode) >= 0) & (get_accesslevel(id_edge_test, id_mode_ped) >= 0): 1944 id_bikeedge = id_edge_test 1945 # print ' found',id_bikeedge,self._edges.ids_sumo[id_bikeedge] 1946 break 1947 else: 1948 ids_new += get_next(id_edge_test) 1949 1950 ids_current = ids_new 1951 1952 if id_bikeedge > -1: 1953 if is_search_backward: 1954 pos = edgelengths[id_bikeedge]-0.5*self.length_edge_min 1955 else: 1956 pos = 0.5*self.length_edge_min 1957 1958 if id_bikeedge == -1: 1959 print 'WARNING in get_edge_bikeaccess no access for', id_edge, self._edges.ids_sumo[id_edge] 1960 return id_bikeedge, pos 1961 1962 def plan_bikeride(self, id_plan, time_from, id_veh, 1963 id_edge_from, pos_edge_from, 1964 id_edge_to, pos_edge_to, 1965 dist_from_to, dist_walk_max, 1966 walkstages, ridestages): 1967 1968 # start creating stages 1969 id_stage_walk1 = -1 1970 id_stage_bike = -1 1971 1972 id_edge_from_bike, pos_from_bike = self.get_edge_bikeaccess(id_edge_from) 1973 id_edge_to_bike, pos_to_bike = self.get_edge_bikeaccess(id_edge_to, is_search_backward=True) 1974 1975 if (dist_from_to < dist_walk_max) | (id_edge_from_bike == -1) | (id_edge_to_bike == -1): 1976 # print ' go by foot because distance is too short or no bike access',dist_from_to,id_edge_from_bike,id_edge_to_bike 1977 id_stage_walk1, time = walkstages.append_stage( 1978 id_plan, time_from, 1979 id_edge_from=id_edge_from, 1980 position_edge_from=pos_edge_from, 1981 id_edge_to=id_edge_to, 1982 position_edge_to=pos_edge_to, 1983 ) 1984 1985 else: 1986 # print ' try to take the bike',id_veh 1987 # print ' id_edge_from_bike',edges.ids_sumo[id_edge_from_bike],pos_from_bike 1988 # print ' id_edge_to_bike',edges.ids_sumo[id_edge_to_bike],pos_to_bike 1989 1990 if id_edge_from_bike != id_edge_from: 1991 # print ' must walk from origin to bikerack',time_from 1992 1993 id_stage_walk1, time = walkstages.append_stage( 1994 id_plan, time_from, 1995 id_edge_from=id_edge_from, 1996 position_edge_from=pos_edge_from, 1997 id_edge_to=id_edge_from_bike, 1998 position_edge_to=pos_from_bike, 1999 ) 2000 2001 if id_edge_to_bike != id_edge_to: 2002 # print ' must cycle from bikerack to dest bike rack',time 2003 id_stage_bike, time = ridestages.append_stage( 2004 id_plan, time, 2005 id_veh=id_veh, 2006 # delay to be sure that person arrived!(workaround in combination with parking=False) 2007 time_init=time-10, # time_from, 2008 id_edge_from=id_edge_from_bike, 2009 position_edge_from=pos_from_bike, 2010 id_edge_to=id_edge_to_bike, 2011 position_edge_to=pos_to_bike, 2012 ) 2013 if id_stage_bike > -1: 2014 # print ' must walk from dest bikerack to dest',time 2015 id_stage_walk2, time = walkstages.append_stage( 2016 id_plan, time, 2017 id_edge_from=id_edge_to_bike, 2018 position_edge_from=pos_to_bike, 2019 id_edge_to=id_edge_to, 2020 position_edge_to=pos_edge_to, 2021 ) 2022 2023 else: 2024 # print ' cycle from bikerack to destination',time 2025 id_stage_bike, time = ridestages.append_stage( 2026 id_plan, time, 2027 id_veh=id_veh, 2028 # delay to be sure that person arrived!(workaround in combination with parking=False) 2029 time_init=time-10, # time_from, 2030 id_edge_from=id_edge_from_bike, 2031 position_edge_from=pos_from_bike, 2032 id_edge_to=id_edge_to, 2033 position_edge_to=pos_edge_to, 2034 ) 2035 else: 2036 # print ' cycle directly from orign edge',time_from 2037 if id_edge_to_bike != id_edge_to: 2038 # print ' must cycle from origin to bikerack',time_from 2039 2040 #pos_to_bike = 0.1*edges.lengths[id_edge_to_bike] 2041 id_stage_bike, time = ridestages.append_stage( 2042 id_plan, time_from, 2043 id_veh=id_veh, 2044 # delay to be sure that person arrived!(workaround in combination with parking=False) 2045 time_init=time_from-10, # time_from, 2046 id_edge_from=id_edge_from, 2047 position_edge_from=pos_edge_from, 2048 id_edge_to=id_edge_to_bike, 2049 position_edge_to=pos_to_bike, 2050 ) 2051 if id_stage_bike > -1: 2052 id_stage_walk2, time = walkstages.append_stage( 2053 id_plan, time, 2054 id_edge_from=id_edge_to_bike, 2055 position_edge_from=pos_to_bike, 2056 id_edge_to=id_edge_to, 2057 position_edge_to=pos_edge_to, 2058 ) 2059 else: 2060 # print ' must cycle from origin to destination',time_from 2061 id_stage_bike, time = ridestages.append_stage( 2062 id_plan, time_from, 2063 id_veh=id_veh, 2064 # delay to be sure that person arrived!(workaround in combination with parking=False) 2065 time_init=time_from-10, # time_from, 2066 id_edge_from=id_edge_from, 2067 position_edge_from=pos_edge_from, 2068 id_edge_to=id_edge_to, 2069 position_edge_to=pos_edge_to, 2070 ) 2071 2072 # here we should have created a bike ride 2073 # if not, for ehatever reason, 2074 # we walk from origin to destination 2075 if id_stage_bike == -1: 2076 # print ' walk because no ride stage has been planned',time_from 2077 if id_stage_walk1 == -1: 2078 # no walk stage has been planned 2079 id_stage_walk1, time = walkstages.append_stage( 2080 id_plan, time_from, 2081 id_edge_from=id_edge_from, 2082 position_edge_from=pos_edge_from, 2083 id_edge_to=id_edge_to, 2084 position_edge_to=pos_edge_to, 2085 ) 2086 2087 elif time_from == time: 2088 # walking to bike has already been schedules, 2089 # but cycling failed. So walk the whole way 2090 time = walkstages.modify_stage( 2091 id_stage_walk1, time_from, 2092 id_edge_from=id_edge_from, 2093 position_edge_from=pos_edge_from, 2094 id_edge_to=id_edge_to, 2095 position_edge_to=pos_edge_to, 2096 ) 2097 return time 2098 2099 def plan(self, ids_person, logger=None): 2100 """ 2101 Generates a plan for these person according to this strategie. 2102 Overriden by specific strategy. 2103 """ 2104 #make_plans_private(self, ids_person = None, mode = 'passenger') 2105 # routing necessary? 2106 virtualpop = self.get_virtualpop() 2107 plans = virtualpop.get_plans() # self._plans 2108 walkstages = plans.get_stagetable('walks') 2109 ridestages = plans.get_stagetable('bikerides') 2110 activitystages = plans.get_stagetable('activities') 2111 2112 activities = virtualpop.get_activities() 2113 activitytypes = virtualpop.get_demand().activitytypes 2114 landuse = virtualpop.get_landuse() 2115 facilities = landuse.facilities 2116 #parking = landuse.parking 2117 2118 scenario = virtualpop.get_scenario() 2119 edges = scenario.net.edges 2120 lanes = scenario.net.lanes 2121 modes = scenario.net.modes 2122 2123 #times_est_plan = plans.times_est 2124 2125 # here we can determine edge weights for different modes 2126 plans.prepare_stagetables(['walks', 'bikerides', 'activities']) 2127 2128 # get initial travel times for persons. 2129 # initial travel times depend on the initial activity 2130 2131 # landuse.parking.clear_booking() 2132 2133 ids_person_act, ids_act_from, ids_act_to\ 2134 = virtualpop.get_activities_from_pattern(0, ids_person=ids_person) 2135 2136 if len(ids_person_act) == 0: 2137 print 'WARNING in BikeStrategy.plan: no eligible persons found.' 2138 return False 2139 2140 # ok 2141 2142 # temporary maps from ids_person to other parameters 2143 nm = np.max(ids_person_act)+1 2144 map_ids_plan = np.zeros(nm, dtype=np.int32) 2145 map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy()) 2146 2147 map_times = np.zeros(nm, dtype=np.int32) 2148 map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit') 2149 2150 # set start time to plans (important!) 2151 plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act] 2152 2153 map_ids_fac_from = np.zeros(nm, dtype=np.int32) 2154 map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from] 2155 2156 #map_ids_parking_from = np.zeros(nm, dtype = np.int32) 2157 # ids_parking_from, inds_vehparking = parking.get_closest_parkings( virtualpop.ids_iauto[ids_person_act], 2158 # facilities.centroids[activities.ids_facility[ids_act_from]]) 2159 # if len(ids_parking_from)==0: 2160 # return False 2161 2162 # err 2163 2164 #map_ids_parking_from[ids_person_act] = ids_parking_from 2165 2166 n_plans = len(ids_person_act) 2167 print 'BikeStrategy.plan n_plans=', n_plans 2168 # print ' map_ids_parking_from[ids_person_act].shape',map_ids_parking_from[ids_person_act].shape 2169 # set initial activity 2170 # this is because the following steps start with travel 2171 # and set the next activity 2172 #names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 2173 # for id_plan 2174 2175 ind_act = 0 2176 2177 # make initial activity stage 2178 ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]] 2179 2180 poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]] 2181 poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from) 2182 2183 # this is the time when first activity starts 2184 # first activity is normally not simulated 2185 2186 names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 2187 durations_act_from = activities.get_durations(ids_act_from) 2188 times_from = map_times[ids_person_act]-durations_act_from 2189 #times_from = activities.get_times_end(ids_act_from, pdf = 'unit') 2190 2191 # do initial stage 2192 # could be common to all strategies 2193 for id_plan,\ 2194 time,\ 2195 id_act_from,\ 2196 name_acttype_from,\ 2197 duration_act_from,\ 2198 id_edge_from,\ 2199 pos_edge_from \ 2200 in zip(map_ids_plan[ids_person_act], 2201 times_from, 2202 ids_act_from, 2203 names_acttype_from, 2204 durations_act_from, 2205 ids_edge_from, 2206 poss_edge_from): 2207 2208 id_stage_act, time = activitystages.append_stage( 2209 id_plan, time, 2210 ids_activity=id_act_from, 2211 names_activitytype=name_acttype_from, 2212 durations=duration_act_from, 2213 ids_lane=edges.ids_lanes[id_edge_from][0], 2214 positions=pos_edge_from, 2215 ) 2216 2217 # main loop while there are persons performing 2218 # an activity at index ind_act 2219 while len(ids_person_act) > 0: 2220 ids_plan = map_ids_plan[ids_person_act] 2221 ids_veh = virtualpop.ids_ibike[ids_person_act] 2222 dists_walk_max = virtualpop.dists_walk_max[ids_person_act] 2223 times_from = map_times[ids_person_act] 2224 2225 names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]] 2226 durations_act_to = activities.get_durations(ids_act_to) 2227 2228 ids_fac_from = map_ids_fac_from[ids_person_act] 2229 ids_fac_to = activities.ids_facility[ids_act_to] 2230 2231 # origin edge and position 2232 ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from] 2233 poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from] 2234 poss_edge_from = self.clip_positions(poss_edge_from, ids_edge_from) 2235 2236 centroids_from = facilities.centroids[ids_fac_from] 2237 2238 # this method will find and occupy parking space 2239 #ids_parking_from = map_ids_parking_from[ids_person_act] 2240 2241 # print ' ids_veh.shape',ids_veh.shape 2242 # print ' centroids_to.shape',centroids_to.shape 2243 #ids_parking_to, inds_vehparking = parking.get_closest_parkings(ids_veh, centroids_to) 2244 2245 #ids_lane_parking_from = parking.ids_lane[ids_parking_from] 2246 #ids_edge_parking_from = lanes.ids_edge[ids_lane_parking_from] 2247 #poss_edge_parking_from = parking.positions[ids_parking_from] 2248 2249 # print ' ids_parking_to.shape',ids_parking_to.shape 2250 # print ' np.max(parking.get_ids()), np.max(ids_parking_to)',np.max(parking.get_ids()), np.max(ids_parking_to) 2251 #ids_lane_parking_to = parking.ids_lane[ids_parking_to] 2252 #ids_edge_parking_to = lanes.ids_edge[ids_lane_parking_to] 2253 #poss_edge_parking_to = parking.positions[ids_parking_to] 2254 2255 # destination edge and position 2256 ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to] 2257 2258 poss_edge_to1 = facilities.positions_roadedge_closest[ids_fac_to] 2259 poss_edge_to = self.clip_positions(poss_edge_to1, ids_edge_to) 2260 centroids_to = facilities.centroids[ids_fac_to] 2261 2262 # debug poscorrection..OK 2263 # for id_edge, id_edge_sumo, length, pos_to1, pos in zip(ids_edge_to, edges.ids_sumo[ids_edge_to],edges.lengths[ids_edge_to],poss_edge_to1, poss_edge_to): 2264 # print ' ',id_edge, 'IDe%s'%id_edge_sumo, 'L=%.2fm'%length, '%.2fm'%pos_to1, '%.2fm'%pos 2265 2266 dists_from_to = np.sqrt(np.sum((centroids_to - centroids_from)**2, 1)) 2267 2268 i = 0.0 2269 n_pers = len(ids_person_act) 2270 for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, dist_from_to, dist_walk_max\ 2271 in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, dists_from_to, dists_walk_max): 2272 if logger: 2273 logger.progress(i/n_pers*100) 2274 i += 1.0 2275 print 79*'*' 2276 print ' plan id_plan', id_plan, 'time_from', time_from, 'from', id_edge_from, pos_edge_from, 'to', id_edge_to, pos_edge_to 2277 print ' id_edge_from', edges.ids_sumo[id_edge_from], 'id_edge_to', edges.ids_sumo[id_edge_to] 2278 2279 time = self.plan_bikeride(id_plan, time_from, id_veh, 2280 id_edge_from, pos_edge_from, 2281 id_edge_to, pos_edge_to, 2282 dist_from_to, dist_walk_max, 2283 walkstages, ridestages) 2284 2285 ################ 2286 2287 # store time estimation for this plan 2288 # note that these are the travel times, no activity time 2289 plans.times_est[id_plan] += time-time_from 2290 2291 # define current end time without last activity duration 2292 plans.times_end[id_plan] = time 2293 2294 # finally add activity and respective duration 2295 2296 id_stage_act, time = activitystages.append_stage( 2297 id_plan, time, 2298 ids_activity=id_act_to, 2299 names_activitytype=name_acttype_to, 2300 durations=duration_act_to, 2301 ids_lane=edges.ids_lanes[id_edge_to][0], 2302 positions=pos_edge_to, 2303 ) 2304 2305 map_times[id_person] = time 2306 # return time 2307 ## 2308 2309 # select persons and activities for next setp 2310 ind_act += 1 2311 ids_person_act, ids_act_from, ids_act_to\ 2312 = virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act) 2313 # update timing with (random) activity duration!! 2314 2315 return True 2316 2317 2318class TransitStrategy(StrategyMixin): 2319 def __init__(self, ident, parent=None, 2320 name='Public Transport Strategy', 2321 info='With this strategy, the person uses public transport.', 2322 **kwargs): 2323 2324 self._init_objman(ident, parent, name=name, info=info, **kwargs) 2325 attrsman = self.set_attrsman(cm.Attrsman(self)) 2326 # specific init 2327 self._init_attributes() 2328 self._init_constants() 2329 2330 def _init_attributes(self): 2331 # print 'StrategyMixin._init_attributes' 2332 pass 2333 2334 def _init_constants(self): 2335 #virtualpop = self.get_virtualpop() 2336 #stagetables = virtualpop.get_stagetables() 2337 2338 #self._walkstages = stagetables.get_stagetable('walks') 2339 #self._ridestages = stagetables.get_stagetable('rides') 2340 #self._activitystages = stagetables.get_stagetable('activities') 2341 2342 #self._plans = virtualpop.get_plans() 2343 # 2344 # print 'AutoStrategy._init_constants' 2345 # print dir(self) 2346 # self.get_attrsman().do_not_save_attrs(['_activitystages','_ridestages','_walkstages','_plans']) 2347 2348 modes = self.get_virtualpop().get_scenario().net.modes 2349 self._id_mode_bike = modes.get_id_mode('bicycle') 2350 self._id_mode_auto = modes.get_id_mode('passenger') 2351 self._id_mode_moto = modes.get_id_mode('motorcycle') 2352 self._id_mode_bus = modes.get_id_mode('bus') 2353 self.get_attrsman().do_not_save_attrs([ 2354 '_id_mode_bike', '_id_mode_auto', '_id_mode_moto', '_id_mode_bus' 2355 ]) 2356 2357 def preevaluate(self, ids_person): 2358 """ 2359 Preevaluation strategies for person IDs in vector ids_person. 2360 2361 Returns a preevaluation vector with a preevaluation value 2362 for each person ID. The values of the preevaluation vector are as follows: 2363 -1 : Strategy cannot be applied 2364 0 : Stategy can be applied, but the preferred mode is not used 2365 1 : Stategy can be applied, and preferred mode is part of the strategy 2366 2 : Strategy uses predomunantly preferred mode 2367 2368 """ 2369 n_pers = len(ids_person) 2370 persons = self.get_virtualpop() 2371 preeval = np.zeros(n_pers, dtype=np.int32) 2372 2373 # TODO: here we could exclude by age or distance facilities-stops 2374 2375 # put 0 for persons whose preference is not public transport 2376 preeval[persons.ids_mode_preferred[ids_person] != self._id_mode_bus] = 0 2377 2378 # put 2 for persons with car access and who prefer cars 2379 preeval[persons.ids_mode_preferred[ids_person] == self._id_mode_bus] = 2 2380 2381 print ' TransitStrategy.preevaluate', len(np.flatnonzero(preeval)) 2382 return preeval 2383 2384 def plan_transit(self, id_plan, time_from, 2385 id_edge_from, pos_edge_from, 2386 id_edge_to, pos_edge_to, 2387 id_stop_from, id_stopedge_from, pos_stop_from, 2388 id_stop_to, id_stopedge_to, pos_stop_to, 2389 #dist_from_to, dist_walk_max, 2390 walkstages, transitstages, 2391 ptlines, ptfstar, pttimes, 2392 stops_to_enter, stops_to_exit, 2393 ids_laneedge, ids_stoplane, ptstops): 2394 2395 ptlinks = ptlines.get_ptlinks() 2396 ptlinktypes = ptlinks.types.choices 2397 type_enter = ptlinktypes['enter'] 2398 type_transit = ptlinktypes['transit'] 2399 type_board = ptlinktypes['board'] 2400 type_alight = ptlinktypes['alight'] 2401 type_transfer = ptlinktypes['transfer'] 2402 type_walk = ptlinktypes['walk'] 2403 type_exit = ptlinktypes['exit'] 2404 2405 if (id_edge_from == id_stopedge_from) & (abs(pos_edge_from-pos_stop_from) < 1.0): 2406 time = time_from 2407 id_stage_walk1 = None 2408 else: 2409 id_stage_walk1, time = walkstages.append_stage(id_plan, time_from, 2410 id_edge_from=id_edge_from, 2411 position_edge_from=pos_edge_from, 2412 id_edge_to=id_stopedge_from, 2413 position_edge_to=pos_stop_from, # -7.0, 2414 ) 2415 2416 # print ' id_stopedge_from',id_stopedge_from 2417 # print ' pos_stop_from',pos_stop_from 2418 2419 # print 2420 # print ' id_stopedge_to',id_stopedge_to 2421 # print ' pos_stop_to',pos_stop_to 2422 # print 2423 # print ' id_stop_from',id_stop_from 2424 # print ' id_stop_to',id_stop_to 2425 2426 durations, linktypes, ids_line, ids_fromstop, ids_tostop =\ 2427 ptlinks.route(id_stop_from, id_stop_to, 2428 fstar=ptfstar, times=pttimes, 2429 stops_to_enter=stops_to_enter, 2430 stops_to_exit=stops_to_exit) 2431 2432 # print ' routing done. make plan..' 2433 2434 if len(linktypes) > 0: 2435 if linktypes[-1] == type_walk: # is last stage a walk? 2436 # remove it, because will go directly to destination 2437 linktypes = linktypes[:-1] 2438 ids_line = ids_line[:-1] 2439 durations = durations[:-1] 2440 ids_fromstop = ids_fromstop[:-1] 2441 ids_tostop = ids_tostop[:-1] 2442 2443 # print ' ids_line ',ids_line 2444 # print ' ids_fromstop',ids_fromstop 2445 # print ' ids_tostop ',ids_tostop 2446 2447 if len(linktypes) > 0: # is there any public transport line to take? 2448 2449 # go though PT links and generate transits and walks to trasfer 2450 ids_stopedge_from = ids_laneedge[ids_stoplane[ids_fromstop]] 2451 ids_stopedge_to = ids_laneedge[ids_stoplane[ids_tostop]] 2452 poss_stop_from = 0.5*(ptstops.positions_from[ids_fromstop] 2453 + ptstops.positions_to[ids_fromstop]) 2454 poss_stop_to = 0.5*(ptstops.positions_from[ids_tostop] 2455 + ptstops.positions_to[ids_tostop]) 2456 2457 # this is wait time buffer to be added to the successive stage 2458 # as waiting is currently not modelled as an extra stage 2459 duration_wait = 0.0 2460 2461 # create stages for PT 2462 for linktype, id_line, duration,\ 2463 id_stopedge_from, pos_fromstop,\ 2464 id_stopedge_to, pos_tostop in\ 2465 zip(linktypes, 2466 ids_line, 2467 durations, 2468 ids_stopedge_from, poss_stop_from, 2469 ids_stopedge_to, poss_stop_to, 2470 ): 2471 # print ' stage for linktype %2d fromedge %s toedge %s'%(linktype, edges.ids_sumo[id_stopedge_from],edges.ids_sumo[id_stopedge_to] ) 2472 2473 print ' id_stopedge_from,id_stopedge_to', id_stopedge_from, id_stopedge_to 2474 if linktype == type_transit: # transit! 2475 print ' add transit' 2476 id_stage_transit, time = transitstages.append_stage( 2477 id_plan, time, 2478 id_line=id_line, 2479 duration=duration+duration_wait, 2480 id_fromedge=id_stopedge_from, 2481 id_toedge=id_stopedge_to, 2482 ) 2483 duration_wait = 0.0 2484 2485 elif linktype == type_walk: # walk to transfer 2486 print ' add transfer' 2487 id_stage_transfer, time = walkstages.append_stage( 2488 id_plan, time, 2489 id_edge_from=id_stopedge_from, 2490 position_edge_from=pos_fromstop, 2491 id_edge_to=id_stopedge_to, 2492 position_edge_to=pos_tostop, 2493 duration=duration+duration_wait, 2494 ) 2495 duration_wait = 0.0 2496 2497 else: # all other link time are no modelld 2498 # do not do anything , just add wait time to next stage 2499 print ' add duration', duration 2500 duration_wait += duration 2501 2502 # walk from final stop to activity 2503 # print ' Stage for linktype %2d fromedge %s toedge %s'%(linktype, edges.ids_sumo[id_stopedge_to],edges.ids_sumo[id_edge_to] ) 2504 # if (id_edge_to == id_stopedge_to)&(abs(pos_edge_to-pos_tostop)<1.0): 2505 # print ' already at right edge and position' 2506 # pass 2507 # else: 2508 id_stage_walk2, time = walkstages.append_stage(id_plan, time, 2509 id_edge_from=id_stopedge_to, 2510 position_edge_from=pos_tostop, 2511 id_edge_to=id_edge_to, 2512 position_edge_to=pos_edge_to, 2513 ) 2514 2515 else: 2516 # there is no public transport line linking these nodes. 2517 2518 if id_stage_walk1 is None: 2519 # Create first walk directly from home to activity 2520 id_stage_walk1, time = walkstages.append_stage(id_plan, 2521 time_from, 2522 id_edge_from=id_edge_from, 2523 position_edge_from=pos_edge_from, 2524 id_edge_to=id_edge_to, 2525 position_edge_to=pos_edge_to, 2526 ) 2527 else: 2528 # Modify first walk directly from home to activity 2529 time = walkstages.modify_stage(id_stage_walk1, time_from, 2530 id_edge_from=id_edge_from, 2531 position_edge_from=pos_edge_from, 2532 id_edge_to=id_edge_to, 2533 position_edge_to=pos_edge_to, 2534 ) 2535 2536 return time 2537 2538 def plan(self, ids_person, logger=None): 2539 """ 2540 Generates a plan for these person according to this strategie. 2541 Overriden by specific strategy. 2542 """ 2543 print 'TransitStrategy.plan', len(ids_person) 2544 #make_plans_private(self, ids_person = None, mode = 'passenger') 2545 # routing necessary? 2546 virtualpop = self.get_virtualpop() 2547 plans = virtualpop.get_plans() # self._plans 2548 demand = virtualpop.get_demand() 2549 ptlines = demand.ptlines 2550 2551 walkstages = plans.get_stagetable('walks') 2552 transitstages = plans.get_stagetable('transits') 2553 activitystages = plans.get_stagetable('activities') 2554 2555 activities = virtualpop.get_activities() 2556 activitytypes = demand.activitytypes 2557 landuse = virtualpop.get_landuse() 2558 facilities = landuse.facilities 2559 parking = landuse.parking 2560 2561 scenario = virtualpop.get_scenario() 2562 net = scenario.net 2563 edges = net.edges 2564 lanes = net.lanes 2565 modes = net.modes 2566 2567 ptstops = net.ptstops 2568 2569 # print ' demand',demand 2570 # print ' demand.ptlines',demand.ptlines,dir(demand.ptlines) 2571 # print ' demand.ptlines.get_ptlinks()',demand.ptlines.get_ptlinks() 2572 # print ' demand.virtualpop',demand.virtualpop,dir(demand.virtualpop) 2573 # print ' demand.trips',demand.trips,dir(demand.trips) 2574 if len(ptlines) == 0: 2575 print 'WARNING in TrasitStrategy.plan: no transit services available. Create public trasit services by connecting stops.' 2576 return False 2577 2578 ptlinks = ptlines.get_ptlinks() 2579 if len(ptlinks) == 0: 2580 print 'WARNING in TrasitStrategy.plan: no public transport links. Run methods: "create routes" and "build links" from public trasport services.' 2581 return False 2582 2583 ptlinktypes = ptlinks.types.choices 2584 2585 ptfstar = ptlinks.get_fstar() 2586 pttimes = ptlinks.get_times() 2587 stops_to_enter, stops_to_exit = ptlinks.get_stops_to_enter_exit() 2588 2589 ids_stoplane = ptstops.ids_lane 2590 ids_laneedge = net.lanes.ids_edge 2591 2592 times_est_plan = plans.times_est 2593 # here we can determine edge weights for different modes 2594 2595 # this could be centralized to avoid redundance 2596 plans.prepare_stagetables(['walks', 'transits', 'activities']) 2597 2598 ids_person_act, ids_act_from, ids_act_to\ 2599 = virtualpop.get_activities_from_pattern(0, ids_person=ids_person) 2600 2601 if len(ids_person_act) == 0: 2602 print 'WARNING in TrasitStrategy.plan: no eligible persons found.' 2603 return False 2604 2605 # temporary maps from ids_person to other parameters 2606 nm = np.max(ids_person_act)+1 2607 map_ids_plan = np.zeros(nm, dtype=np.int32) 2608 #ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy()) 2609 map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy()) 2610 2611 map_times = np.zeros(nm, dtype=np.int32) 2612 map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit') 2613 2614 # set start time to plans (important!) 2615 plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act] 2616 2617 map_ids_fac_from = np.zeros(nm, dtype=np.int32) 2618 map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from] 2619 2620 n_plans = len(ids_person_act) 2621 print 'TrasitStrategy.plan n_plans=', n_plans 2622 2623 # make initial activity stage 2624 ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]] 2625 poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]] 2626 # this is the time when first activity starts 2627 # first activity is normally not simulated 2628 2629 names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 2630 durations_act_from = activities.get_durations(ids_act_from) 2631 times_from = map_times[ids_person_act]-durations_act_from 2632 #times_from = activities.get_times_end(ids_act_from, pdf = 'unit') 2633 2634 for id_plan,\ 2635 time,\ 2636 id_act_from,\ 2637 name_acttype_from,\ 2638 duration_act_from,\ 2639 id_edge_from,\ 2640 pos_edge_from \ 2641 in zip(map_ids_plan[ids_person_act], 2642 times_from, 2643 ids_act_from, 2644 names_acttype_from, 2645 durations_act_from, 2646 ids_edge_from, 2647 poss_edge_from): 2648 2649 id_stage_act, time = activitystages.append_stage( 2650 id_plan, time, 2651 ids_activity=id_act_from, 2652 names_activitytype=name_acttype_from, 2653 durations=duration_act_from, 2654 ids_lane=edges.ids_lanes[id_edge_from][0], 2655 positions=pos_edge_from, 2656 ) 2657 2658 ## 2659 2660 ind_act = 0 2661 2662 # main loop while there are persons performing 2663 # an activity at index ind_act 2664 while len(ids_person_act) > 0: 2665 ids_plan = map_ids_plan[ids_person_act] 2666 2667 times_from = map_times[ids_person_act] 2668 2669 names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]] 2670 durations_act_to = activities.get_durations(ids_act_to) 2671 2672 ids_fac_from = map_ids_fac_from[ids_person_act] 2673 ids_fac_to = activities.ids_facility[ids_act_to] 2674 2675 centroids_from = facilities.centroids[ids_fac_from] 2676 centroids_to = facilities.centroids[ids_fac_to] 2677 2678 # origin edge and position 2679 ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from] 2680 poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from] 2681 2682 # destination edge and position 2683 ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to] 2684 poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to] 2685 2686 ids_stop_from = ptstops.get_closest(centroids_from) 2687 ids_stop_to = ptstops.get_closest(centroids_to) 2688 2689 ids_stopedge_from = ids_laneedge[ids_stoplane[ids_stop_from]] 2690 ids_stopedge_to = ids_laneedge[ids_stoplane[ids_stop_to]] 2691 2692 # do random pos here 2693 poss_stop_from = 0.5*(ptstops.positions_from[ids_stop_from] 2694 + ptstops.positions_to[ids_stop_from]) 2695 2696 poss_stop_to = 0.5*(ptstops.positions_from[ids_stop_to] 2697 + ptstops.positions_to[ids_stop_to]) 2698 2699 i = 0.0 2700 for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, id_stop_from, id_stopedge_from, pos_stop_from, id_stop_to, id_stopedge_to, pos_stop_to\ 2701 in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, ids_stop_from, ids_stopedge_from, poss_stop_from, ids_stop_to, ids_stopedge_to, poss_stop_to): 2702 n_pers = len(ids_person_act) 2703 if logger: 2704 logger.progress(i/n_pers*100) 2705 i += 1.0 2706 print 79*'_' 2707 print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person) 2708 2709 time = self.plan_transit(id_plan, time_from, 2710 id_edge_from, pos_edge_from, 2711 id_edge_to, pos_edge_to, 2712 id_stop_from, id_stopedge_from, pos_stop_from, 2713 id_stop_to, id_stopedge_to, pos_stop_to, 2714 #dist_from_to, dist_walk_max, 2715 walkstages, transitstages, 2716 ptlines, ptfstar, pttimes, 2717 stops_to_enter, stops_to_exit, 2718 ids_laneedge, ids_stoplane, ptstops) 2719 2720 # update time for trips estimation for this plan 2721 plans.times_est[id_plan] += time-time_from 2722 2723 # define current end time without last activity duration 2724 plans.times_end[id_plan] = time 2725 2726 id_stage_act, time = activitystages.append_stage( 2727 id_plan, time, 2728 ids_activity=id_act_to, 2729 names_activitytype=name_acttype_to, 2730 durations=duration_act_to, 2731 ids_lane=edges.ids_lanes[id_edge_to][0], 2732 positions=pos_edge_to, 2733 ) 2734 2735 # store time for next iteration in case other activities are 2736 # following 2737 map_times[id_person] = time 2738 2739 # select persons and activities for next setp 2740 ind_act += 1 2741 ids_person_act, ids_act_from, ids_act_to\ 2742 = virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act) 2743 2744 2745class BikeTransitStrategy(BikeStrategy, TransitStrategy): 2746 def __init__(self, ident, parent=None, 2747 name='Bike+Public Transport Strategy', 2748 info='With this strategy, the person combines bike and public transport.', 2749 **kwargs): 2750 2751 self._init_objman(ident, parent, name=name, info=info, **kwargs) 2752 attrsman = self.set_attrsman(cm.Attrsman(self)) 2753 # specific init 2754 self._init_attributes() 2755 self._init_constants() 2756 2757 def _init_attributes(self): 2758 # print 'StrategyMixin._init_attributes' 2759 BikeStrategy._init_attributes(self) 2760 TransitStrategy._init_attributes(self) 2761 2762 def _init_constants(self): 2763 2764 BikeStrategy._init_constants(self) 2765 TransitStrategy._init_constants(self) 2766 2767 def preevaluate(self, ids_person): 2768 """ 2769 Preevaluation strategies for person IDs in vector ids_person. 2770 2771 Returns a preevaluation vector with a preevaluation value 2772 for each person ID. The values of the preevaluation vector are as follows: 2773 -1 : Strategy cannot be applied 2774 0 : Stategy can be applied, but the preferred mode is not used 2775 1 : Stategy can be applied, and preferred mode is part of the strategy 2776 2 : Strategy uses predomunantly preferred mode 2777 2778 """ 2779 n_pers = len(ids_person) 2780 persons = self.get_virtualpop() 2781 preeval = np.zeros(n_pers, dtype=np.int32) 2782 2783 inds_prefer = (persons.ids_mode_preferred[ids_person] == self._id_mode_bus)\ 2784 | (persons.ids_mode_preferred[ids_person] == self._id_mode_bike)\ 2785 2786 inds_avail = persons.ids_ibike[ids_person] > -1 2787 preeval[np.logical_not(inds_avail)] = -1 2788 # TODO: here we could exclude by age or distance facilities-stops 2789 2790 # put 0 for persons whose preference is not public transport 2791 preeval[inds_avail & np.logical_not(inds_prefer)] = 0 2792 2793 # put 2 for persons with bike access and who prefer bike or bus 2794 preeval[inds_avail & inds_prefer] = 1 2795 2796 print ' BikeTransitStrategy.preevaluate', len(np.flatnonzero(preeval)) 2797 return preeval 2798 2799 def plan(self, ids_person, logger=None): 2800 """ 2801 Generates a plan for these person according to this strategie. 2802 Overriden by specific strategy. 2803 """ 2804 print 'TransitStrategy.plan', len(ids_person) 2805 #make_plans_private(self, ids_person = None, mode = 'passenger') 2806 # routing necessary? 2807 virtualpop = self.get_virtualpop() 2808 plans = virtualpop.get_plans() # self._plans 2809 demand = virtualpop.get_demand() 2810 ptlines = demand.ptlines 2811 2812 walkstages = plans.get_stagetable('walks') 2813 transitstages = plans.get_stagetable('transits') 2814 ridestages = plans.get_stagetable('bikerides') 2815 activitystages = plans.get_stagetable('activities') 2816 2817 activities = virtualpop.get_activities() 2818 activitytypes = demand.activitytypes 2819 landuse = virtualpop.get_landuse() 2820 facilities = landuse.facilities 2821 #parking = landuse.parking 2822 2823 scenario = virtualpop.get_scenario() 2824 net = scenario.net 2825 edges = net.edges 2826 lanes = net.lanes 2827 modes = net.modes 2828 2829 ptstops = net.ptstops 2830 2831 # print ' demand',demand 2832 # print ' demand.ptlines',demand.ptlines,dir(demand.ptlines) 2833 # print ' demand.ptlines.get_ptlinks()',demand.ptlines.get_ptlinks() 2834 # print ' demand.virtualpop',demand.virtualpop,dir(demand.virtualpop) 2835 # print ' demand.trips',demand.trips,dir(demand.trips) 2836 if len(ptlines) == 0: 2837 print 'WARNING in TrasitStrategy.plan: no transit services available.' 2838 return False 2839 2840 ptlinks = ptlines.get_ptlinks() 2841 ptlinktypes = ptlinks.types.choices 2842 2843 ptfstar = ptlinks.get_fstar() 2844 pttimes = ptlinks.get_times() 2845 stops_to_enter, stops_to_exit = ptlinks.get_stops_to_enter_exit() 2846 2847 ids_stoplane = ptstops.ids_lane 2848 ids_laneedge = net.lanes.ids_edge 2849 2850 times_est_plan = plans.times_est 2851 # here we can determine edge weights for different modes 2852 2853 # this could be centralized to avoid redundance 2854 plans.prepare_stagetables(['walks', 'bikerides', 'transits', 'activities']) 2855 2856 ids_person_act, ids_act_from, ids_act_to\ 2857 = virtualpop.get_activities_from_pattern(0, ids_person=ids_person) 2858 2859 if len(ids_person_act) == 0: 2860 print 'WARNING in TrasitStrategy.plan: no eligible persons found.' 2861 return False 2862 2863 # temporary maps from ids_person to other parameters 2864 nm = np.max(ids_person_act)+1 2865 map_ids_plan = np.zeros(nm, dtype=np.int32) 2866 #ids_plan_act = virtualpop.add_plans(ids_person_act, id_strategy = self.get_id_strategy()) 2867 map_ids_plan[ids_person_act] = virtualpop.add_plans(ids_person_act, id_strategy=self.get_id_strategy()) 2868 2869 map_times = np.zeros(nm, dtype=np.int32) 2870 map_times[ids_person_act] = activities.get_times_end(ids_act_from, pdf='unit') 2871 2872 # set start time to plans (important!) 2873 plans.times_begin[map_ids_plan[ids_person_act]] = map_times[ids_person_act] 2874 2875 map_ids_fac_from = np.zeros(nm, dtype=np.int32) 2876 map_ids_fac_from[ids_person_act] = activities.ids_facility[ids_act_from] 2877 2878 n_plans = len(ids_person_act) 2879 print 'TrasitStrategy.plan n_plans=', n_plans 2880 2881 # make initial activity stage 2882 ids_edge_from = facilities.ids_roadedge_closest[map_ids_fac_from[ids_person_act]] 2883 poss_edge_from = facilities.positions_roadedge_closest[map_ids_fac_from[ids_person_act]] 2884 # this is the time when first activity starts 2885 # first activity is normally not simulated 2886 2887 names_acttype_from = activitytypes.names[activities.ids_activitytype[ids_act_from]] 2888 durations_act_from = activities.get_durations(ids_act_from) 2889 times_from = map_times[ids_person_act]-durations_act_from 2890 #times_from = activities.get_times_end(ids_act_from, pdf = 'unit') 2891 2892 for id_plan,\ 2893 time,\ 2894 id_act_from,\ 2895 name_acttype_from,\ 2896 duration_act_from,\ 2897 id_edge_from,\ 2898 pos_edge_from \ 2899 in zip(map_ids_plan[ids_person_act], 2900 times_from, 2901 ids_act_from, 2902 names_acttype_from, 2903 durations_act_from, 2904 ids_edge_from, 2905 poss_edge_from): 2906 2907 id_stage_act, time = activitystages.append_stage( 2908 id_plan, time, 2909 ids_activity=id_act_from, 2910 names_activitytype=name_acttype_from, 2911 durations=duration_act_from, 2912 ids_lane=edges.ids_lanes[id_edge_from][0], 2913 positions=pos_edge_from, 2914 ) 2915 2916 ## 2917 2918 ind_act = 0 2919 2920 # main loop while there are persons performing 2921 # an activity at index ind_act 2922 while len(ids_person_act) > 0: 2923 ids_plan = map_ids_plan[ids_person_act] 2924 2925 times_from = map_times[ids_person_act] 2926 2927 ids_veh = virtualpop.ids_ibike[ids_person_act] 2928 dists_walk_max = virtualpop.dists_walk_max[ids_person_act] 2929 names_acttype_to = activitytypes.names[activities.ids_activitytype[ids_act_to]] 2930 durations_act_to = activities.get_durations(ids_act_to) 2931 2932 ids_fac_from = map_ids_fac_from[ids_person_act] 2933 ids_fac_to = activities.ids_facility[ids_act_to] 2934 2935 centroids_from = facilities.centroids[ids_fac_from] 2936 centroids_to = facilities.centroids[ids_fac_to] 2937 2938 # origin edge and position 2939 ids_edge_from = facilities.ids_roadedge_closest[ids_fac_from] 2940 poss_edge_from = facilities.positions_roadedge_closest[ids_fac_from] 2941 2942 # destination edge and position 2943 ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to] 2944 poss_edge_to = facilities.positions_roadedge_closest[ids_fac_to] 2945 2946 ids_stop_from = ptstops.get_closest(centroids_from) 2947 ids_stop_to = ptstops.get_closest(centroids_to) 2948 2949 ids_stopedge_from = ids_laneedge[ids_stoplane[ids_stop_from]] 2950 ids_stopedge_to = ids_laneedge[ids_stoplane[ids_stop_to]] 2951 2952 centroids_stop_from = ptstops.centroids[ids_stop_from] 2953 centroids_stop_to = ptstops.centroids[ids_stop_to] 2954 # do random pos here 2955 poss_stop_from = 0.5*(ptstops.positions_from[ids_stop_from] 2956 + ptstops.positions_to[ids_stop_from]) 2957 2958 poss_stop_to = 0.5*(ptstops.positions_from[ids_stop_to] 2959 + ptstops.positions_to[ids_stop_to]) 2960 2961 dists_from_to = np.sqrt(np.sum((centroids_to - centroids_from)**2, 1)) 2962 dists_from_stop_from = np.sqrt(np.sum((centroids_stop_from - centroids_from)**2, 1)) 2963 dists_stop_to_to = np.sqrt(np.sum((centroids_to - centroids_stop_to)**2, 1)) 2964 2965 i = 0.0 2966 for id_person, id_plan, time_from, id_act_from, id_act_to, name_acttype_to, duration_act_to, id_veh, id_edge_from, pos_edge_from, id_edge_to, pos_edge_to, id_stop_from, id_stopedge_from, pos_stop_from, id_stop_to, id_stopedge_to, pos_stop_to, dists_from_to, dist_from_stop_from, dist_stop_to_to, dist_walk_max\ 2967 in zip(ids_person_act, ids_plan, times_from, ids_act_from, ids_act_to, names_acttype_to, durations_act_to, ids_veh, ids_edge_from, poss_edge_from, ids_edge_to, poss_edge_to, ids_stop_from, ids_stopedge_from, poss_stop_from, ids_stop_to, ids_stopedge_to, poss_stop_to, dists_from_to, dists_from_stop_from, dists_stop_to_to, dists_walk_max): 2968 n_pers = len(ids_person_act) 2969 if logger: 2970 logger.progress(i/n_pers*100) 2971 i += 1.0 2972 print 79*'_' 2973 print ' id_plan=%d, id_person=%d, ' % (id_plan, id_person) 2974 #dist_from_stop_from, dist_stop_to_to 2975 2976 time = self.plan_bikeride(id_plan, time_from, id_veh, 2977 id_edge_from, pos_edge_from, 2978 id_stopedge_from, pos_stop_from, 2979 dist_from_stop_from, dist_walk_max, 2980 walkstages, ridestages) 2981 2982 time = self.plan_transit(id_plan, time, 2983 id_stopedge_from, pos_stop_from, 2984 id_stopedge_to, pos_stop_to, 2985 id_stop_from, id_stopedge_from, pos_stop_from, 2986 id_stop_to, id_stopedge_to, pos_stop_to, 2987 #dist_from_to, dist_walk_max, 2988 walkstages, transitstages, 2989 ptlines, ptfstar, pttimes, 2990 stops_to_enter, stops_to_exit, 2991 ids_laneedge, ids_stoplane, ptstops) 2992 2993 time = self.plan_bikeride(id_plan, time, id_veh, 2994 id_stopedge_to, pos_stop_to, 2995 id_edge_to, pos_edge_to, 2996 dist_stop_to_to, dist_walk_max, 2997 walkstages, ridestages) 2998 2999 # update time for trips estimation for this plan 3000 plans.times_est[id_plan] += time-time_from 3001 3002 # define current end time without last activity duration 3003 plans.times_end[id_plan] = time 3004 3005 id_stage_act, time = activitystages.append_stage( 3006 id_plan, time, 3007 ids_activity=id_act_to, 3008 names_activitytype=name_acttype_to, 3009 durations=duration_act_to, 3010 ids_lane=edges.ids_lanes[id_edge_to][0], 3011 positions=pos_edge_to, 3012 ) 3013 3014 # store time for next iteration in case other activities are 3015 # following 3016 map_times[id_person] = time 3017 3018 # select persons and activities for next setp 3019 ind_act += 1 3020 ids_person_act, ids_act_from, ids_act_to\ 3021 = virtualpop.get_activities_from_pattern(ind_act, ids_person=ids_person_act) 3022 3023 3024class Strategies(am.ArrayObjman): 3025 def __init__(self, ident, virtualpop, **kwargs): 3026 self._init_objman(ident, 3027 parent=virtualpop, 3028 name='Mobility Strategies', 3029 info="""Contains different mobility strategies. 3030 A strategy has methods to identify whether a strategy is applicaple to a person 3031 and to make a plan fo a person. 3032 """, 3033 version=0.2, 3034 **kwargs) 3035 3036 self.add_col(am.ArrayConf('names', 3037 default='', 3038 dtype='object', 3039 perm='r', 3040 is_index=True, 3041 name='Short name', 3042 info='Strategy name. Must be unique, used as index.', 3043 )) 3044 self._init_attributes() 3045 self._init_constants() 3046 3047 def _init_attributes(self): 3048 3049 self.add_col(cm.ObjsConf('strategies', 3050 #groupnames = ['state'], 3051 name='Strategy', 3052 info='Strategy object.', 3053 )) 3054 3055 self.add_col(am.ArrayConf('colors', np.ones(4, np.float32), 3056 dtype=np.float32, 3057 metatype='color', 3058 perm='rw', 3059 name='Color', 3060 info="Route color. Color as RGBA tuple with values from 0.0 to 1.0", 3061 xmltag='color', 3062 )) 3063 if self.get_version() < 0.2: 3064 self._set_colors_default() 3065 self.set_version(0.2) 3066 3067 def format_ids(self, ids): 3068 return ', '.join(self.names[ids]) 3069 3070 def get_id_from_formatted(self, idstr): 3071 return self.names.get_id_from_index(idstr) 3072 3073 def get_ids_from_formatted(self, idstrs): 3074 return self.names.get_ids_from_indices_save(idstrs.split(',')) 3075 3076 def add_default(self): 3077 3078 self.add_strategy('walk', WalkStrategy) 3079 self.add_strategy('auto', AutoStrategy) 3080 self.add_strategy('bike', BikeStrategy) 3081 self.add_strategy('transit', TransitStrategy) 3082 self.add_strategy('biketransit', BikeTransitStrategy) 3083 self._set_colors_default() 3084 3085 def _set_colors_default(self): 3086 colors_default = {'walk': np.array([160, 72, 0, 220], np.float32)/255, 3087 'auto': np.array([250, 213, 0, 220], np.float32)/255, 3088 'bike': np.array([8, 191, 73, 210], np.float32)/255, 3089 'transit': np.array([8, 77, 191, 220], np.float32)/255, 3090 'biketransit': np.array([8, 201, 223, 220], np.float32)/255, 3091 } 3092 ids = self.names.get_ids_from_indices_save(colors_default.keys()) 3093 self.colors[ids] = colors_default.values() # np.array(colors_default.values(), np.float32).reshape(-1,4) 3094 3095 #self.colors.indexset(colors_default.keys(), colors_default.values()) 3096 3097 def add_strategy(self, ident, Strategyclass, color=(0.0, 0.0, 0.0, 1.0)): 3098 # print 'add_strategy', ident 3099 if not self.names.has_index(ident): 3100 strategy = Strategyclass(ident, self) 3101 self.add_row(names=ident, 3102 strategies=strategy, 3103 colours=color, 3104 ) 3105 return strategy 3106 else: 3107 # print 'WARNING in add_strategy: strategy %s already initialized'%ident 3108 return self.strategies[self.names.get_id_from_index(ident)] 3109 3110 def preevaluate(self, ids_person): 3111 """ 3112 Preevaluation of strategies for person IDs in vector ids_person. 3113 3114 Returns a vector with strategy IDs and a preevaluation matrix. 3115 The rows of the matrix corrispond to each person ID. 3116 The columns corrsopond to reck strategy ID. 3117 The values of the preevaluation matrix are as follows: 3118 -1 : Strategy cannot be applied 3119 0 : Stategy can be applied, but the preferred mode is not used 3120 1 : Stategy can be applied, and preferred mode is part of the strategy 3121 2 : Strategy uses predomunantly preferred mode 3122 3123 """ 3124 print 'preevaluate strategies' 3125 ids_strat = self.get_ids() 3126 n_pers = len(ids_person) 3127 n_strat = len(ids_strat) 3128 3129 preeval = np.zeros((n_pers, n_strat), dtype=np.int32) 3130 for i, strategy in zip(range(n_strat), self.strategies[ids_strat]): 3131 print ' preevaluate strategiy', strategy.ident 3132 preeval[i, :] = strategy.preevaluate(ids_person) 3133 3134 return ids_strat, preeval 3135 3136 3137class StageTypeMixin(am.ArrayObjman): 3138 def init_stagetable(self, ident, stages, name='', info="Stage of Plan"): 3139 3140 self._init_objman(ident=ident, parent=stages, name=name, 3141 info=info, 3142 version=0.2, 3143 ) 3144 3145 self.add_col(am.IdsArrayConf('ids_plan', self.get_plans(), 3146 #groupnames = ['state'], 3147 name='ID plan', 3148 info='ID of plan.', 3149 xmltag='type', 3150 )) 3151 3152 self.add_col(am.ArrayConf('times_start', -1.0, 3153 groupnames=['parameters'], # new 3154 name='Start time', 3155 unit='s', 3156 info='Planned or estimated time when this stage starts. Value -1 means unknown.', 3157 )) 3158 3159 self.add_col(am.ArrayConf('durations', -1.0, 3160 name='Duration', 3161 groupnames=['parameters'], # new 3162 unit='s', 3163 info='Planned or estimated duration for this stage starts. Value -1 means unknown.', 3164 xmltag='type', 3165 )) 3166 3167 def get_plans(self): 3168 return self.parent 3169 3170 def get_ids_from_ids_plan(self, ids_plan): 3171 """ 3172 Returns only stage IDs which are part of the given plans IDs. 3173 """ 3174 # print 'get_ids_from_ids_plan for',type(ids_plan),ids_plan 3175 3176 ids = self.get_ids() 3177 #ids_plan_part = self.ids_plan[ids] 3178 are_selected = np.zeros(len(ids), dtype=np.bool) 3179 for ind, id_plan_part in zip(xrange(len(ids)), self.ids_plan[ids]): 3180 are_selected[ind] = id_plan_part in ids_plan 3181 return ids[are_selected] 3182 # print ' ids_plan_part',type(ids_plan_part),ids_plan_part 3183 # print ' ids_selected',type(ids_plan_part.intersection(ids_plan)),ids_plan_part.intersection(ids_plan) 3184 # return np.array(list(ids_plan_part.intersection(ids_plan)), dtype = np.int32) 3185 3186 def get_virtualpop(self): 3187 # print 'get_virtualpop ' 3188 return self.parent.parent 3189 3190 def prepare_planning(self): 3191 pass 3192 3193 def append_stage(self, id_plan, time_start, **kwargs): 3194 3195 # try to fix timing 3196 # if time_start<0: 3197 # time_start_prev, duration_prev = self.parent.plans.get_timing_laststage(id_plan) 3198 # if (duration_prev>=0)&(time_start_prev>=0): 3199 # time_start = time_start_prev+duration_prev 3200 3201 id_stage = self.add_row(ids_plan=id_plan, times_start=time_start, **kwargs) 3202 # print 'STAGE.appended stage %s id_plan=%d, id_stage=%d, t=%d'%(self.get_name(),id_plan,id_stage,time_start) 3203 # for key in kwargs.keys(): 3204 # print ' %s=%s'%(key,kwargs[key]) 3205 # print ' --id_plan, self, id_stage',id_plan, self, id_stage#,self.ids_plan.get_linktab() 3206 3207 self.parent.append_stage(id_plan, self, id_stage) 3208 # print ' plan appended',id_plan, self, id_stage 3209 3210 return id_stage, time_start+self.durations[id_stage] 3211 3212 def modify_stage(self, id_stage, time_start, **kwargs): 3213 self.set_row(id_stage, **kwargs) 3214 return time_start+self.durations[id_stage] 3215 3216 def get_timing(self, id_stage): 3217 #ind = self.get_ind(id_stage) 3218 return self.times_start[id_stage], self.durations[id_stage] 3219 3220 def to_xml(self, id_stage, fd, indent=0): 3221 """ 3222 To be overridden by specific stage class. 3223 """ 3224 pass 3225 3226 3227class TransitStages(StageTypeMixin): 3228 def __init__(self, ident, stages, name='Transit rides', info='Ride on a single public transport line (no transfers).'): 3229 self.init_stagetable(ident, 3230 stages, name=name, 3231 info=info, 3232 ) 3233 self._init_attributes() 3234 3235 def _init_attributes(self): 3236 #ptstops = self.parent.get_ptstops() 3237 edges = self.get_virtualpop().get_net().edges 3238 if hasattr(self, 'ids_fromstop'): 3239 self.delete('ids_fromstop') 3240 self.delete('ids_tostop') 3241 3242 self.add_col(am.IdsArrayConf('ids_line', self.get_virtualpop().get_ptlines(), 3243 groupnames=['parameters'], 3244 name='ID line', 3245 info='ID of public transport line.', 3246 )) 3247 3248 self.add_col(am.IdsArrayConf('ids_fromedge', edges, 3249 groupnames=['parameters'], 3250 name='Edge ID from', 3251 info='Edge ID of departure bus stop or station.', 3252 )) 3253 3254 self.add_col(am.IdsArrayConf('ids_toedge', edges, 3255 groupnames=['parameters'], 3256 name='Edge ID to', 3257 info='Edge ID of destination bus stop or station.', 3258 )) 3259 3260 def _init_constants(self): 3261 self.get_attrsman().do_not_save_attrs(['_costs', '_fstar', ]) 3262 3263 def prepare_planning(self): 3264 ptlinks = self.ids_line.get_linktab().ptlinks.get_value() 3265 if len(ptlinks) == 0: 3266 # no links built...built them 3267 ptlinks.build() 3268 3269 self._costs = ptlinks.get_times() 3270 self._fstar = ptlinks.get_fstar() 3271 3272 def append_stage(self, id_plan, time_start=-1.0, 3273 id_line=-1, duration=0.0, 3274 id_fromedge=-1, id_toedge=-1, **kwargs): 3275 """ 3276 Appends a transit stage to plan id_plan. 3277 3278 """ 3279 # print 'TransitStages.append_stage',id_stage 3280 3281 id_stage, time_end = StageTypeMixin.append_stage(self, 3282 id_plan, 3283 time_start, 3284 durations=duration, 3285 ids_line=id_line, 3286 ids_fromedge=id_fromedge, 3287 ids_toedge=id_toedge, 3288 ) 3289 3290 # add this stage to the vehicle database 3291 # ind_ride gives the index of this ride (within the same plan??) 3292 #ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage) 3293 return id_stage, time_end 3294 3295 def to_xml(self, id_stage, fd, indent=0): 3296 # <ride from="1/3to0/3" to="0/4to1/4" lines="train0"/> 3297 net = self.get_virtualpop().get_net() 3298 #ids_stoplane = net.ptstops.ids_lane 3299 #ids_laneedge = net.lanes.ids_edge 3300 ids_sumoedge = net.edges.ids_sumo 3301 3302 #ind = self.get_ind(id_stage) 3303 fd.write(xm.start('ride', indent=indent)) 3304 fd.write(xm.num('from', ids_sumoedge[self.ids_fromedge[id_stage]])) 3305 fd.write(xm.num('to', ids_sumoedge[self.ids_toedge[id_stage]])) 3306 fd.write(xm.num('lines', self.ids_line.get_linktab().linenames[self.ids_line[id_stage]])) 3307 # if self.cols.pos_edge_from[ind]>0: 3308 # fd.write(xm.num('departPos', self.cols.pos_edge_from[ind])) 3309 # if self.cols.pos_edge_to[ind]>0: 3310 # fd.write(xm.num('arrivalPos', self.cols.pos_edge_to[ind])) 3311 3312 fd.write(xm.stopit()) # ends stage 3313 3314 3315class AutorideStages(StageTypeMixin): 3316 3317 def __init__(self, ident, population, 3318 name='Auto rides', 3319 info='Rides with privately owned auto.', 3320 version=1.0, 3321 ): 3322 3323 self.init_stagetable(ident, population, name=name, info=info) 3324 # print 'Rides.__init__',self.get_name() 3325 self._init_attributes() 3326 3327 def _init_attributes(self): 3328 # TODO: this structure needs review: the private vehicle is part of a person, not a stage 3329 # street parking at home and work could be in stage. Private garage is part of person... 3330 # print '_init_attributes',self.parent.get_iautos(), self.ident,self.parent.get_landuse().parking 3331 3332 self.add_col(am.IdsArrayConf('ids_iauto', self.get_virtualpop().get_iautos(), 3333 groupnames=['state'], 3334 name='ID vehicle', 3335 info='ID of private vehicle.', 3336 )) 3337 3338 self.add_col(am.ArrayConf('times_init', -1.0, 3339 name='Init. time', 3340 unit='s', 3341 info='Initialization time, which is the time when the vehicle appears in the scenario. Value -1 means unknown.', 3342 )) 3343 3344 self.add_col(am.IdsArrayConf('ids_parking_from', self.get_virtualpop().get_landuse().parking, 3345 groupnames=['state'], 3346 name='ID dep. parking', 3347 info='Parking ID at the departure of the ride starts.', 3348 )) 3349 3350 self.add_col(am.IdsArrayConf('ids_parking_to', self.get_virtualpop().get_landuse().parking, 3351 groupnames=['state'], 3352 name='ID arr. parking', 3353 info='Parking ID at the arrival of the ride.', 3354 )) 3355 3356 self.add_col(am.IdlistsArrayConf('ids_edges', self.get_virtualpop().get_net().edges, 3357 groupnames=['_private'], 3358 name='Route', 3359 info="The vehicle's route as a sequence of edge IDs.", 3360 )) 3361 3362 self.add(cm.AttrConf('dist_ride_min', 400.0, 3363 dtype='object', 3364 groupnames=['options'], 3365 perm='rw', 3366 name='Min ride dist.', 3367 info='Minimum ride distance. If the distanve between parkings is less, then the person will walk.', 3368 )) 3369 3370 # if hasattr(self,'parking'): 3371 # self.delete('parking') 3372 3373 def _init_constants(self): 3374 self.get_attrsman().do_not_save_attrs(['_costs', '_fstar', ]) 3375 3376 def prepare_planning(self): 3377 net = self.get_virtualpop().get_net() 3378 # ??? do this for all vehicles?? 3379 self._costs = net.edges.get_times(id_mode=net.modes.get_id_mode('passenger'), 3380 is_check_lanes=True) 3381 self._fstar = net.edges.get_fstar(is_ignor_connections=False) 3382 3383 def append_stage(self, id_plan, time_start=-1.0, id_veh=-1, 3384 time_init=-1, 3385 id_parking_from=.1, id_parking_to=-1, **kwargs): 3386 """ 3387 Appends a ride stage to plan id_plan in case the ride is feasible. 3388 The ride is feasible if from parking and to parking are connected. 3389 3390 If feasible, the stage ID and estimated time when stage is finished 3391 will be returned. 3392 3393 If not feasible -1 and start time will be returned. 3394 """ 3395 # print 'Rides.append_stage',id_stage 3396 3397 # check feasibility 3398 route, dist, duration = self.get_route_between_parking(id_parking_from, id_parking_to) 3399 3400 if (len(route) > 0): # |(dist > self.dist_ride_min.get_value()): # is there a connection 3401 # create stage 3402 id_stage, time_end = StageTypeMixin.append_stage(self, 3403 id_plan, 3404 time_start, 3405 durations=duration, 3406 times_init=time_init, 3407 ids_iauto=id_veh, 3408 ids_parking_from=id_parking_from, 3409 ids_parking_to=id_parking_to, 3410 ids_edges=route, 3411 ) 3412 3413 # add this stage to the vehicle database 3414 # ind_ride gives the index of this ride (within the same plan??) 3415 #ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage) 3416 return id_stage, time_end 3417 3418 else: 3419 # not connected or too short of a distance 3420 return -1, time_start # no stage creation took place 3421 3422 def get_route_between_parking(self, id_parking_from, id_parking_to): 3423 """ 3424 Return route and distance of ride with vehicle type vtype 3425 between id_parking_from and id_parking_to 3426 3427 """ 3428 # print 'get_route_between_parking',id_parking_from, id_parking_to 3429 scenario = self.get_virtualpop().get_scenario() 3430 edges = scenario.net.edges 3431 lanes = scenario.net.lanes 3432 3433 # print self.get_demand().getVehicles().cols.maxSpeed 3434 #v_max = self.get_demand().getVehicles().maxSpeed.get(vtype) 3435 parking = scenario.landuse.parking 3436 3437 ids_lanes = parking.ids_lane[[id_parking_from, id_parking_to]] 3438 id_edge_from, id_edge_to = lanes.ids_edge[ids_lanes] 3439 pos_from, pos_to = parking.positions[[id_parking_from, id_parking_to]] 3440 3441 # print ' id_edge_from, id_edge_to=',id_edge_from, id_edge_to 3442 duration_approx, route = routing.get_mincostroute_edge2edge( 3443 id_edge_from, 3444 id_edge_to, 3445 weights=self._costs, # mode-specific!! 3446 fstar=self._fstar # mode-specific!! 3447 ) 3448 3449 # here is a big problem: starting with the successive node of edge_from 3450 # may result that the first edge of the route is not connected with edge_from 3451 # And arriving at the preceding node of edge_to may result that from 3452 # the last edge in route the edge_to is not connected. 3453 3454 #route = [edge_from]+route+[edge_to] 3455 dist = np.sum(edges.lengths[route]) 3456 dist = dist - pos_from - (edges.lengths[id_edge_to] - pos_to) 3457 # if 0: 3458 # if len(route)>0: 3459 # print ' dist,duration',dist,duration_approx 3460 # else: 3461 # print ' no route found' 3462 3463 return route, dist, duration_approx 3464 3465 # def make_id_veh_ride(self, id_stage, i_ride): 3466 # # make a unique vehicle ID for this stage 3467 # self.inds_ride[id_stage] = i_ride 3468 # return str(self.ids_veh[id_stage])+'.'+str(i_ride) 3469 3470 def get_writexmlinfo(self, ids_plan, is_route=True): 3471 print 'AutorideStages.get_writexmlinfo', len(ids_plan) 3472 iautos = self.get_virtualpop().get_iautos() 3473 writefunc = iautos.prepare_write_xml() 3474 ids = self.get_ids_from_ids_plan(ids_plan) 3475 writefuncs = np.zeros(len(ids), dtype=np.object) 3476 writefuncs[:] = writefunc 3477 return self.times_init[ids], writefuncs, ids 3478 3479 def to_xml(self, id_stage, fd, indent=0): 3480 #lanes = self.parent.get_scenario().net.lanes 3481 scenario = self.get_virtualpop().get_scenario() 3482 3483 edges = scenario.net.edges 3484 edgeindex = edges.ids_sumo 3485 parking = scenario.landuse.parking 3486 3487 ind = self.get_ind(id_stage) 3488 fd.write(xm.start('ride', indent=indent)) 3489 3490 id_edge_from, pos_from = parking.get_edge_pos_parking(self.ids_parking_from.value[ind]) 3491 id_edge_to, pos_to = parking.get_edge_pos_parking(self.ids_parking_to.value[ind]) 3492 3493 # edgeindex.get_index_from_id(self.ids_edge_to.value[ind]) 3494 fd.write(xm.num('from', edgeindex[id_edge_from])) 3495 fd.write(xm.num('to', edgeindex[id_edge_to])) 3496 fd.write(xm.num('lines', self.ids_iauto.get_linktab().get_id_line_xml( 3497 self.ids_iauto[id_stage]))) # mode specific 3498 3499 # if 0: 3500 # #pos = pos_from 3501 # length = max(edges.lengths[id_edge_from]-4.0,0.0) 3502 # 3503 # if (pos_from>0) & (pos_from < length ): 3504 # fd.write(xm.num('departPos', pos)) 3505 # 3506 # elif pos_from < 0: 3507 # fd.write(xm.num('departPos', 0.0)) 3508 # 3509 # else: 3510 # fd.write(xm.num('departPos', length)) 3511 # 3512 # #pos = self.positions_to.value[ind] 3513 # length = max(edges.lengths[id_edge_to]-4.0, 0.0) 3514 # if (pos_to>0) & (pos_to < length ): 3515 # fd.write(xm.num('arrivalPos', pos_to)) 3516 # 3517 # elif pos_to < 0: 3518 # fd.write(xm.num('arrivalPos', 0.0)) 3519 # 3520 # else: 3521 # fd.write(xm.num('arrivalPos', length)) 3522 3523 fd.write(xm.stopit()) # ends stage 3524 3525 3526class BikerideStages(StageTypeMixin): 3527 3528 def __init__(self, ident, population, 3529 name='Bike rides', 3530 info='Rides with privately owned bike.', 3531 version=1.0, 3532 ): 3533 3534 self.init_stagetable(ident, population, name=name, info=info) 3535 # print 'Rides.__init__',self.get_name() 3536 self._init_attributes() 3537 3538 def _init_attributes(self): 3539 # TODO: this structure needs review: the private vehicle is part of a person, not a stage 3540 # street parking at home and work could be in stage. Private garage is part of person... 3541 # print '_init_attributes',self.parent.get_iautos(), self.ident,self.parent.get_landuse().parking 3542 3543 self.add_col(am.IdsArrayConf('ids_ibike', self.get_virtualpop().get_ibikes(), 3544 groupnames=['state'], 3545 name='ID bike', 3546 info='ID of private, individual bike.', 3547 )) 3548 3549 self.add_col(am.ArrayConf('times_init', -1.0, 3550 name='Init. time', 3551 unit='s', 3552 info='Initialization time, which is the time when the vehicle appears in the scenario. Value -1 means unknown.', 3553 )) 3554 3555 edges = self.get_virtualpop().get_net().edges 3556 3557 self.add_col(am.IdsArrayConf('ids_edge_from', edges, 3558 groupnames=['state'], 3559 name='ID Dep. edge', 3560 info='Edge ID at departure of walk.', 3561 )) 3562 3563 self.add_col(am.IdsArrayConf('ids_edge_to', edges, 3564 groupnames=['state'], 3565 name='ID Arr. edge', 3566 info='Edge ID where walk finishes.', 3567 )) 3568 3569 self.add_col(am.ArrayConf('positions_from', 0.0, 3570 dtype=np.float32, 3571 #choices = OPTIONMAP_POS_DEPARTURE, 3572 perm='r', 3573 name='Depart pos', 3574 unit='m', 3575 info="Position on edge at the moment of departure.", 3576 #xmltag = 'departPos', 3577 #xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL), 3578 )) 3579 3580 self.add_col(am.ArrayConf('positions_to', 0.0, 3581 dtype=np.float32, 3582 #choices = OPTIONMAP_POS_ARRIVAL, 3583 perm='r', 3584 name='Arrival pos', 3585 unit='m', 3586 info="Position on edge at the moment of arrival.", 3587 #xmltag = 'arrivalPos', 3588 #xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL), 3589 )) 3590 3591 self.add_col(am.IdlistsArrayConf('ids_edges', self.get_virtualpop().get_net().edges, 3592 groupnames=['_private'], 3593 name='Route', 3594 info="The vehicle's route as a sequence of edge IDs.", 3595 )) 3596 3597 def _init_constants(self): 3598 self.get_attrsman().do_not_save_attrs(['_costs', '_fstar', ]) 3599 3600 def prepare_planning(self): 3601 net = self.get_virtualpop().get_net() 3602 3603 print 'prepare_planning' 3604 self._costs = net.edges.get_times(id_mode=net.modes.get_id_mode('bicycle'), 3605 is_check_lanes=True) 3606 3607 ids_edge = net.edges.get_ids() 3608 for id_edge, cost in zip(ids_edge, self._costs[ids_edge]): 3609 print ' id_edge', id_edge, 'sumo', net.edges.ids_sumo[id_edge], cost 3610 3611 self._fstar = net.edges.get_fstar(is_ignor_connections=False) 3612 3613 def append_stage(self, id_plan, time_start=-1.0, id_veh=-1, 3614 time_init=-1, 3615 id_edge_from=-1, id_edge_to=-1, 3616 position_edge_from=0.0, position_edge_to=0.0, 3617 **kwargs): 3618 """ 3619 Appends a ride stage to plan id_plan in case the ride is feasible. 3620 The ride is feasible if from parking and to parking are connected. 3621 3622 If feasible, the stage ID and estimated time when stage is finished 3623 will be returned. 3624 3625 If not feasible -1 and start time will be returned. 3626 """ 3627 # print 'BikeRides.append_stage',id_plan,time_start,time_init 3628 #edges = self.get_virtualpop().get_net().edges 3629 # check feasibility 3630 #route, dist, duration = self.get_route_between_parking(id_parking_from, id_parking_to) 3631 3632 # print ' id_edge_from, id_edge_to=',id_edge_from, id_edge_to 3633 duration_approx, route = routing.get_mincostroute_edge2edge( 3634 id_edge_from, 3635 id_edge_to, 3636 weights=self._costs, # mode-specific!! 3637 fstar=self._fstar # mode-specific!! 3638 ) 3639 3640 #route = [edge_from]+route+[edge_to] 3641 3642 #dist = np.sum(edges.lengths[route]) 3643 #dist = dist - pos_from - ( edges.lengths[id_edge_to] - pos_to) 3644 3645 if (len(route) > 0): # |(dist > self.dist_ride_min.get_value()): # is there a connection 3646 # create stage 3647 id_stage, time_end = StageTypeMixin.append_stage(self, 3648 id_plan, 3649 time_start, 3650 durations=duration_approx, 3651 times_init=time_init, 3652 ids_ibike=id_veh, 3653 ids_edge_from=id_edge_from, 3654 positions_from=position_edge_from, 3655 ids_edge_to=id_edge_to, 3656 positions_to=position_edge_to, 3657 ids_edges=route, 3658 ) 3659 3660 # print ' route = ',route 3661 # print ' ids_edges = ',self.ids_edges[id_stage] 3662 # add this stage to the vehicle database 3663 # ind_ride gives the index of this ride (within the same plan??) 3664 #ind_ride = self.parent.get_iautos().append_ride(id_veh, id_stage) 3665 return id_stage, time_end 3666 3667 else: 3668 # not connected or too short of a distance 3669 return -1, time_start # no stage creation took place 3670 3671 def get_writexmlinfo(self, ids_plan, is_route=True): 3672 print 'BikerideStages.get_writexmlinfo', len(ids_plan) 3673 ibikes = self.get_virtualpop().get_ibikes() 3674 bikewritefunc = ibikes.prepare_write_xml() 3675 ids = self.get_ids_from_ids_plan(ids_plan) 3676 3677 bikewritefuncs = np.zeros(len(ids), dtype=np.object) 3678 bikewritefuncs[:] = bikewritefunc 3679 return self.times_init[ids], bikewritefuncs, ids 3680 3681 def to_xml(self, id_stage, fd, indent=0): 3682 #lanes = self.parent.get_scenario().net.lanes 3683 scenario = self.get_virtualpop().get_scenario() 3684 3685 edges = scenario.net.edges 3686 edgeindex = edges.ids_sumo 3687 3688 #parking = scenario.landuse.parking 3689 3690 #ind = self.get_ind(id_stage) 3691 fd.write(xm.start('ride', indent=indent)) 3692 3693 #id_edge_from, pos_from = parking.get_edge_pos_parking(self.ids_parking_from.value[ind]) 3694 #id_edge_to, pos_to = parking.get_edge_pos_parking(self.ids_parking_to.value[ind]) 3695 3696 # edgeindex.get_index_from_id(self.ids_edge_to.value[ind]) 3697 id_edge_from = self.ids_edge_from[id_stage] 3698 fd.write(xm.num('from', edgeindex[self.ids_edge_from[id_stage]])) 3699 fd.write(xm.num('to', edgeindex[self.ids_edge_to[id_stage]])) 3700 fd.write(xm.num('lines', self.ids_ibike.get_linktab().get_id_line_xml( 3701 self.ids_ibike[id_stage]))) # mode specific 3702 3703 # if 0: 3704 # #pos = pos_from 3705 # length = max(edges.lengths[id_edge_from]-4.0,0.0) 3706 # 3707 # if (pos_from>0) & (pos_from < length ): 3708 # fd.write(xm.num('departPos', pos)) 3709 # 3710 # elif pos_from < 0: 3711 # fd.write(xm.num('departPos', 0.0)) 3712 # 3713 # else: 3714 # fd.write(xm.num('departPos', length)) 3715 # 3716 # #pos = self.positions_to.value[ind] 3717 # length = max(edges.lengths[id_edge_to]-4.0, 0.0) 3718 # if (pos_to>0) & (pos_to < length ): 3719 # fd.write(xm.num('arrivalPos', pos_to)) 3720 # 3721 # elif pos_to < 0: 3722 # fd.write(xm.num('arrivalPos', 0.0)) 3723 # 3724 # else: 3725 # fd.write(xm.num('arrivalPos', length)) 3726 3727 fd.write(xm.stopit()) # ends stage 3728 3729 3730class WalkStages(StageTypeMixin): 3731 def __init__(self, ident, stages, name='WalkStages', 3732 info='walk from a position on a lane to another position of another lane.'): 3733 3734 self.init_stagetable(ident, stages, name=name, info=info) 3735 3736 edges = self.get_virtualpop().get_scenario().net.edges 3737 self.add_col(am.IdsArrayConf('ids_edge_from', edges, 3738 groupnames=['state'], 3739 name='ID Dep. edge', 3740 info='Edge ID at departure of walk.', 3741 )) 3742 3743 self.add_col(am.IdsArrayConf('ids_edge_to', edges, 3744 groupnames=['state'], 3745 name='ID Arr. edge', 3746 info='Edge ID where walk finishes.', 3747 )) 3748 3749 self.add_col(am.ArrayConf('positions_from', 0.0, 3750 dtype=np.float32, 3751 #choices = OPTIONMAP_POS_DEPARTURE, 3752 perm='r', 3753 name='Depart pos', 3754 unit='m', 3755 info="Position on edge at the moment of departure.", 3756 #xmltag = 'departPos', 3757 #xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL), 3758 )) 3759 self.positions_from.set_xmltag(None) 3760 3761 self.add_col(am.ArrayConf('positions_to', 0.0, 3762 dtype=np.float32, 3763 #choices = OPTIONMAP_POS_ARRIVAL, 3764 perm='r', 3765 name='Arrival pos', 3766 unit='m', 3767 info="Position on edge at the moment of arrival.", 3768 #xmltag = 'arrivalPos', 3769 #xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL), 3770 )) 3771 3772 self.positions_to.set_xmltag(None) 3773 3774 def append_stage(self, id_plan, time_start=-1.0, 3775 id_edge_from=-1, id_edge_to=-1, 3776 position_edge_from=0.1, position_edge_to=0.0, 3777 **kwargs): 3778 # print 'WalkStages.append_stage',id_stage 3779 if kwargs.has_key('duration'): 3780 duration = kwargs['duration'] 3781 else: 3782 dist, duration = self.plan_walk(id_edge_from, id_edge_to, 3783 position_edge_from, position_edge_to) 3784 3785 id_stage, time_end = StageTypeMixin.append_stage(self, 3786 id_plan, 3787 time_start, 3788 durations=duration, 3789 ids_edge_from=id_edge_from, 3790 ids_edge_to=id_edge_to, 3791 positions_from=position_edge_from, 3792 positions_to=position_edge_to, 3793 ) 3794 3795 return id_stage, time_end 3796 3797 def modify_stage(self, id_stage, time_start, 3798 id_edge_from=-1, id_edge_to=-1, 3799 position_edge_from=0.1, position_edge_to=0.0): 3800 3801 dist, duration = self.plan_walk(id_edge_from, id_edge_to, 3802 position_edge_from, position_edge_to) 3803 3804 time_end = StageTypeMixin.modify_stage(self, id_stage, time_start, 3805 durations=duration, 3806 ids_edge_from=id_edge_from, 3807 ids_edge_to=id_edge_to, 3808 positions_from=position_edge_from, 3809 positions_to=position_edge_to, 3810 ) 3811 3812 return time_end 3813 3814 def plan_walk(self, id_edge_from, id_edge_to, pos_from, pos_to, id_mode=1): 3815 """ 3816 Routing for pedestrians. 3817 Currently limited to estimation of line of sight distance 3818 and walk time. 3819 """ 3820 # print 'plan_walk',id_edge_from, id_edge_to,id_mode, pos_from, pos_to 3821 scenario = self.get_virtualpop().get_scenario() 3822 edges = scenario.net.edges 3823 3824 coord_from = edges.get_coord_from_pos(id_edge_from, pos_from) 3825 coord_to = edges.get_coord_from_pos(id_edge_to, pos_to) 3826 3827 # from lanes, more precis, but less efficient and less robust 3828 # lanes = scenario.net.lanes 3829 #coord_from = lanes.get_coord_from_pos(edges.ids_lane[id_edge_from][0], pos_from) 3830 #coord_to = lanes.get_coord_from_pos(edges.ids_lane[id_edge_to][0], pos_to) 3831 3832 # print ' coord_from',coord_from,type(coord_from) 3833 # print ' coord_to',coord_from,type(coord_to) 3834 # print ' delta',coord_to-coord_from 3835 # line of sight distance 3836 dist = np.sqrt(np.sum((coord_to-coord_from)**2)) 3837 3838 duration_approx = dist/scenario.net.modes.speeds_max[id_mode] 3839 # print ' dist,duration',dist,duration_approx,scenario.net.modes.speeds_max[id_mode] 3840 3841 return dist, duration_approx 3842 3843 def to_xml(self, id_stage, fd, indent=0): 3844 #scenario = self.parent.get_scenario() 3845 #edges = scenario.net.edges 3846 edges = self.ids_edge_from.get_linktab() 3847 edgeindex = edges.ids_sumo 3848 3849 ind = self.get_ind(id_stage) 3850 3851 id_edge_from = self.ids_edge_from.value[ind] 3852 id_edge_to = self.ids_edge_to.value[ind] 3853 fd.write(xm.start('walk', indent=indent)) 3854 fd.write(xm.num('from', edgeindex[id_edge_from])) 3855 fd.write(xm.num('to', edgeindex[id_edge_to])) 3856 3857 pos = self.positions_from.value[ind] 3858 length = max(edges.lengths[id_edge_from]-4.0, 0.0) 3859 3860 # depricated 3861 # if (pos>0) & (pos < length ): 3862 # fd.write(xm.num('departPos', pos)) 3863 # 3864 # elif pos < 0: 3865 # fd.write(xm.num('departPos', 0.0)) 3866 # 3867 # else: 3868 # fd.write(xm.num('departPos', length)) 3869 3870 pos = self.positions_to.value[ind] 3871 length = max(edges.lengths[id_edge_to]-4.0, 0.0) 3872 if (pos > 0) & (pos < length): 3873 fd.write(xm.num('arrivalPos', pos)) 3874 3875 elif pos < 0: 3876 fd.write(xm.num('arrivalPos', 0.0)) 3877 3878 else: 3879 fd.write(xm.num('arrivalPos', length)) 3880 3881 fd.write(xm.stopit()) # ends walk 3882 3883 3884class ActivityStages(StageTypeMixin): 3885 def __init__(self, ident, stages, name='Activities'): 3886 self.init_stagetable(ident, stages, name=name, info='Do some activity at a position of a lane.') 3887 3888 self._init_attributes() 3889 3890 def _init_attributes(self): 3891 3892 # TODO: this structure needs review: the private vehicle is part of a person, not a stage 3893 # street parking at home and work could be in stage. Private garage is part of person... 3894 3895 activities = self.get_virtualpop().get_activities() 3896 self.add_col(am.IdsArrayConf('ids_activity', activities, 3897 groupnames=['parameters'], 3898 name='Activity ID', 3899 info='Scheduled activity ID. This is the activity which schould be carried out in this stage.', 3900 )) 3901 3902 # this is redundant information but here for speed when writing xml 3903 self.add_col(am.ArrayConf('names_activitytype', '', 3904 groupnames=['parameters'], 3905 dtype=np.object, 3906 perm='r', 3907 name='Type name', 3908 info="Name of activity type.", 3909 xmltag='actType', 3910 #xmlmap = get_inversemap( activitytypes.names.get_indexmap()), 3911 )) 3912 3913 # self.add_col(am.IdsArrayConf( 'ids_facility', self.get_virtualpop().get_landuse().facilities, 3914 # groupnames = ['parameters'], 3915 # name = 'ID facility', 3916 # info = 'Facility where activity takes place.', 3917 # )) 3918 3919 # lane and position can be computed from facility 3920 self.add_col(am.IdsArrayConf('ids_lane', self.get_virtualpop().get_net().lanes, 3921 groupnames=['parameters'], 3922 name='Lane ID', 3923 info='Lane ID where activity takes place.', 3924 #xmltag = 'lane', 3925 )) 3926 # for update..can be removed 3927 self.ids_lane.set_xmltag(None) 3928 3929 self.add_col(am.ArrayConf('positions', 0.0, 3930 groupnames=['parameters'], 3931 dtype=np.float32, 3932 perm='r', 3933 name='Lane pos', 3934 unit='m', 3935 info="Position on lane nearby where activity takes place.", 3936 #xmltag = 'startPos', 3937 #xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL), 3938 )) 3939 3940 self.positions.set_xmltag(None) 3941 3942 self.add_col(am.ArrayConf('durations', 0.0, 3943 groupnames=['parameters'], 3944 dtype=np.int32, 3945 perm='r', 3946 name='Duration', 3947 unit='s', 3948 info="Duration of activity.", 3949 xmltag='duration', 3950 #xmlmap = get_inversemap(OPTIONMAP_POS_ARRIVAL), 3951 )) 3952 3953 self.durations.set_xmltag('duration') 3954 3955 def get_edges_positions(self, ids_stage): 3956 """ 3957 Returns road edge and positions of activity. 3958 """ 3959 return self.ids_lane.get_linktab().ids_edge[self.ids_lane[ids_stage]],\ 3960 self.positions[ids_stage] 3961 3962 def _init_constants(self): 3963 #self._activities = self.get_virtualpop().get_activities() 3964 #self._activitytypes = self.get_virtualpop().get_demand().activitytypes 3965 # self.do_not_save_attrs(['_activities','_activitytypes']) 3966 pass 3967 3968 def to_xml(self, id_stage, fd, indent=0): 3969 3970 # <stop lane="1/4to2/4_0" duration="20" startPos="40" actType="singing"/> 3971 3972 #ind = self.get_ind(id_stage) 3973 fd.write(xm.start('stop', indent=indent)) 3974 3975 lanes = self.get_virtualpop().get_net().lanes 3976 id_lane = self.ids_lane[id_stage] 3977 # get all xml configs and damp to fd 3978 for attrconf in self.get_group('parameters'): 3979 # this will write only if a xmltag is defined 3980 attrconf.write_xml(fd, id_stage) 3981 fd.write(xm.num('lane', lanes.get_id_sumo(id_lane))) 3982 #fd.write(xm.num('duration', self.durations[id_stage])) 3983 3984 pos = self.positions[id_stage] 3985 length = max(lanes.get_lengths(id_lane)-4.0, 0.0) 3986 3987 if (pos > 0) & (pos < length): 3988 fd.write(xm.num('startPos', pos)) 3989 3990 elif pos < 0: 3991 fd.write(xm.num('startPos', 0.0)) 3992 3993 else: 3994 fd.write(xm.num('startPos', length)) 3995 3996 #fd.write(xm.num('lane', self.cols.id_lane[ind])) 3997 #fd.write(xm.num('startPos', self.cols.pos_lane[ind])) 3998 #fd.write(xm.num('duration', self.cols.duration[ind])) 3999 # fd.write(xm.num('actType', self._activitytypes.names[self._activities.) 4000 4001 fd.write(xm.stopit()) # ends activity 4002 4003 4004class Plans(am.ArrayObjman): 4005 def __init__(self, population, **kwargs): 4006 """Plans database.""" 4007 self._init_objman(ident='plans', 4008 parent=population, 4009 name='Plans', 4010 info='Mobility plan for virtual population.', 4011 #xmltag = ('plans','plan',None), 4012 version=0.1, 4013 **kwargs) 4014 4015 self._init_attributes() 4016 self._init_constants() 4017 4018 def _init_attributes(self): 4019 4020 # upgrade 4021 if self.get_version() < 0.1: 4022 pass 4023 4024 self.set_version(0.1) 4025 persons = self.parent 4026 4027 #self.add(cm.ObjConf(StageTables('stagetables',self)) ) 4028 4029 self.add_stagetable('walks', WalkStages) 4030 self.add_stagetable('autorides', AutorideStages) 4031 self.add_stagetable('bikerides', BikerideStages) 4032 self.add_stagetable('transits', TransitStages) 4033 self.add_stagetable('activities', ActivityStages) 4034 4035 self.add_col(am.IdsArrayConf('ids_person', persons, 4036 groupnames=['links'], 4037 name='Person ID', 4038 info='Person ID to who this plan belongs to.', 4039 )) 4040 4041 self.add_col(am.IdsArrayConf('ids_strategy', persons.get_strategies(), 4042 groupnames=['links'], 4043 name='Stategy ID', 4044 info='Stategy ID with which this plan has been generated.', 4045 )) 4046 4047 self.add_col(am.ArrayConf('times_begin', -np.inf, 4048 dtype=np.float32, 4049 name='Begin time', 4050 info='Time when active travelling begins. This is the time in the simulation when the person appears. The first activity is not simulated.', 4051 unit='s', 4052 )) 4053 4054 self.add_col(am.ArrayConf('times_end', -np.inf, 4055 dtype=np.float32, 4056 name='End time', 4057 info='Time when active travelling ends. This is the time in the simulation when the person disappears. The last activity is not simulated.', 4058 unit='s', 4059 )) 4060 4061 self.add_col(am.ArrayConf('times_est', 0.0, 4062 dtype=np.float32, 4063 name='Estim. time', 4064 info='Estimated time duration to execute travel plan. Activity times are excluded.', 4065 unit='s', 4066 )) 4067 4068 self.add_col(am.ArrayConf('times_exec', 0.0, 4069 dtype=np.float32, 4070 name='Exec. time', 4071 info='Last plan execution time from simulation run.', 4072 unit='s', 4073 )) 4074 4075 self.add_col(am.ArrayConf('utilities', 0.0, 4076 dtype=np.float32, 4077 name='utility', 4078 info='Utility of plan.', 4079 )) 4080 4081 self.add_col(am.ArrayConf('probabilities', 1.0, 4082 dtype=np.float32, 4083 name='Probability', 4084 info='Probability that the plan is selected out of all plans available for one person.', 4085 )) 4086 4087 self.add_col(am.TabIdListArrayConf('stagelists', 4088 name='Stages', 4089 info='Sequence of stages of this plan.', 4090 )) 4091 4092 def _init_constants(self): 4093 #self._id_mode_bike = self.parent.get_scenario().net.modes.get_id_mode('bicycle') 4094 # self.do_not_save_attrs([]) 4095 pass 4096 4097 def clear_plans(self): 4098 print 'Plans.clear_plans' 4099 for stagetable in self.get_stagetables(): 4100 # print ' stagetable',stagetable 4101 stagetable.clear() 4102 4103 self.clear_rows() 4104 # for attrconfig in self.get_attrsman().get_colconfigs(): 4105 # print ' clear attrconfig',attrconfig.attrname 4106 # attrconfig.clear() 4107 # no: self.clear() 4108 4109 def add_stagetable(self, ident, StagesClass, **kwargs): 4110 if not hasattr(self, ident): 4111 self.add(cm.ObjConf(StagesClass(ident, self, **kwargs), 4112 groupnames=['stagetables'])) 4113 return getattr(self, ident).get_value() 4114 4115 def get_stagetable(self, ident): 4116 return getattr(self, ident).get_value() 4117 4118 def get_stagetables(self): 4119 """Return a list of with all stage objects""" 4120 stageobjs = [] 4121 # print 'get_stagetables',self.get_group('stagetables') 4122 for stageobj in self.get_group('stagetables'): 4123 stageobjs.append(stageobj) 4124 return stageobjs 4125 4126 def prepare_stagetables(self, idents_stagetable): 4127 # print 'prepare_stages',stagenames 4128 #ids = self.names.get_ids_from_indices_save(stagenames) 4129 # print ' ids',ids 4130 # print ' self.stagetables[ids]',self.stagetables[ids] 4131 for indent in idents_stagetable: 4132 self.get_stagetable(indent).prepare_planning() 4133 4134 def get_stages(self, id_plan): 4135 stages = self.stagelists[id_plan] 4136 if stages is None: 4137 return [] 4138 else: 4139 return stages 4140 4141 def append_stage(self, id_plan, stage, id_stage): 4142 # test: stage = cm.TableEntry(stagetable, id_plan) 4143 # print 'Plans.append_stage',self,id_plan, stage, id_stage 4144 4145 if self.stagelists[id_plan] is None: 4146 self.stagelists[id_plan] = [(stage, id_stage)] 4147 else: 4148 self.stagelists[id_plan].append((stage, id_stage)) 4149 # print ' after append stagelists[id_plan]',type(self.stagelists[id_plan]),self.stagelists[id_plan] 4150 4151 # def prepare_stages(self,stagenames): 4152 # self.get_stagetables().prepare_stages(stagenames) 4153 4154 def get_timing_laststage(self, id_plan): 4155 """ 4156 Return time_start and duration of last stage of plan id_plan 4157 """ 4158 stages_current = self.stagelists[id_plan] 4159 4160 if stages_current is not None: 4161 stage_last, id_stage_last = stages_current[-1] 4162 return stage_last.get_timing(id_stage_last) 4163 else: 4164 return -1, -1 4165 4166 4167class Virtualpopulation(DemandobjMixin, am.ArrayObjman): 4168 def __init__(self, ident, demand, **kwargs): 4169 self._init_objman(ident=ident, 4170 parent=demand, 4171 name='Virtual population', 4172 info='Contains information of each individual of the virtual population.', 4173 version=0.2, # only for new scenarios 4174 **kwargs) 4175 self._init_attributes() 4176 self._init_constants() 4177 4178 def _init_attributes(self): 4179 4180 # update here 4181 4182 # 4183 self.set_version(0.2) 4184 4185 demand = self.parent 4186 scenario = demand.get_scenario() 4187 4188 # -------------------------------------------------------------------- 4189 # individual vehicles tables 4190 4191 self.add(cm.ObjConf(IndividualAutos('iautos', self))) 4192 self.add(cm.ObjConf(IndividualBikes('ibikes', self))) 4193 self.add(cm.ObjConf(IndividualMotorcycles('imotos', self))) 4194 4195 # -------------------------------------------------------------------- 4196 # activity table 4197 #self.add(cm.ObjConf(ActivityTypes('activitytypes', self)) ) 4198 self.add(cm.ObjConf(Activities('activities', self))) 4199 4200 # -------------------------------------------------------------------- 4201 # strategies table (must be before plans) 4202 4203 self.add(cm.ObjConf(Strategies('strategies', self))) 4204 4205 # -------------------------------------------------------------------- 4206 # plans table 4207 self.add(cm.ObjConf(Plans(self))) 4208 4209 self.get_strategies().add_default() 4210 4211 # =================================================================== 4212 # Add person attributes 4213 4214 # -------------------------------------------------------------------- 4215 # socio economic parameters 4216 self.add_col(am.ArrayConf('identifications', '', 4217 dtype=np.object, 4218 groupnames=['socioeconomic'], 4219 name='Name', 4220 info='Identification or name of person.', 4221 )) 4222 4223 self.add_col(am.ArrayConf('ids_gender', default=-1, 4224 dtype=np.int32, 4225 groupnames=['socioeconomic'], 4226 choices=GENDERS, 4227 name='Gender', 4228 info='Gender of person.', 4229 )) 4230 4231 self.add_col(am.ArrayConf('years_birth', default=-1, 4232 dtype=np.int32, 4233 groupnames=['socioeconomic'], 4234 name='Birth year', 4235 info='Year when person has been born.', 4236 )) 4237 4238 self.add_col(am.ArrayConf('ids_occupation', default=OCCUPATIONS['unknown'], 4239 dtype=np.int32, 4240 choices=OCCUPATIONS, 4241 groupnames=['socioeconomic'], 4242 name='Occupation', 4243 info='Type of occupation.', 4244 )) 4245 4246 # -------------------------------------------------------------------- 4247 # household parameters 4248 self.add_col(am.ArrayConf('numbers_houehold', default=1, 4249 dtype=np.int32, 4250 groupnames=['household'], 4251 name='Number in household', 4252 info='Number of persons in household.', 4253 )) 4254 4255 self.add_col(am.ArrayConf('numbers_minor', default=0, 4256 dtype=np.int32, 4257 groupnames=['household'], 4258 name='Number minors', 4259 info='Number of minor in household. In the context of traffic simulations minors are persons who need to be accompaigned by adulds when travelling.', 4260 )) 4261 4262 # -------------------------------------------------------------------- 4263 # activity parameters 4264 # lists with activity patterns 4265 4266 self.add_col(am.IdlistsArrayConf('activitypatterns', self.activities.get_value(), 4267 groupnames=['activity'], 4268 name='Activity IDs', 4269 info="Sequence of activity IDs to be accomplished by the person.", 4270 )) 4271 4272 # -------------------------------------------------------------------- 4273 # mobility parameters 4274 # -------------------------------------------------------------------- 4275 4276 # give a pedestrian vtype to each person 4277 vtypes = self.get_demand().vtypes 4278 self.add_col(am.IdsArrayConf('ids_vtype', vtypes, 4279 id_default=vtypes.select_by_mode(mode='pedestrian')[0], 4280 groupnames=['mobility'], 4281 name='Ped. type', 4282 info='The pedestrian type ID specifies the walking characteristics and visual representation of the person. In SUMO terminology, this is the vehicle type.', 4283 #xmltag = 'type', 4284 )) 4285 4286 self.add_col(am.ArrayConf('traveltimebudgets', default=55*60, 4287 dtype=np.int32, 4288 groupnames=['mobility'], 4289 name='time budget', 4290 unit='s', 4291 info='Daily time budget used for traveling.', 4292 )) 4293 4294 self.add_col(am.IdsArrayConf('ids_mode_preferred', scenario.net.modes, 4295 groupnames=['mobility'], 4296 name='ID preferred mode', 4297 info='ID of preferred transport mode of person.', 4298 )) 4299 4300 self.add_col(am.IdsArrayConf('ids_iauto', self.get_iautos(), 4301 groupnames=['mobility'], 4302 name='ID auto', 4303 info='ID of individual auto. Negative value means no bile available.', 4304 )) 4305 4306 self.add_col(am.IdsArrayConf('ids_ibike', self.get_ibikes(), 4307 groupnames=['mobility'], 4308 name='ID bike', 4309 info='ID of individual bicycle. Negative value means no bike available.', 4310 )) 4311 4312 self.add_col(am.IdsArrayConf('ids_imoto', self.get_imotos(), 4313 groupnames=['mobility'], 4314 name='ID motorcycle', 4315 info='ID of individual motorcycle. Negative value means no motorcycle available.', 4316 )) 4317 4318 self.add_col(am.ArrayConf('dists_walk_max', default=300.0, 4319 dtype=np.float32, 4320 groupnames=['mobility'], 4321 name='Max. walk dist', 4322 info='Maximum acceptable walking distance between origin and destination or for transfers between modes.', 4323 )) 4324 4325 # -------------------------------------------------------------------- 4326 # plans 4327 self.add_col(am.IdsArrayConf('ids_plan', self.get_plans(), 4328 groupnames=['plans'], 4329 name='ID Plan', 4330 info='Currently selected mobility plan ID of person. This is the plan which will be simulated.', 4331 )) 4332 4333 self.add_col(am.IdlistsArrayConf('lists_ids_plan', self.get_plans(), 4334 groupnames=['plans'], 4335 name='Plan IDs', 4336 info='List with alternative, feasible mobility plan IDs for each person.', 4337 )) 4338 4339 def _init_constants(self): 4340 modes = self.get_scenario().net.modes 4341 self.id_mode_bike = modes.get_id_mode('bicycle') 4342 self.id_mode_auto = modes.get_id_mode('passenger') 4343 self.id_mode_moto = modes.get_id_mode('motorcycle') 4344 self._edges = self.get_net().edges 4345 self.do_not_save_attrs(['id_mode_bike', 'id_mode_auto', 'id_mode_moto', 4346 '_edges']) 4347 4348 def get_demand(self): 4349 return self.parent 4350 4351 def clear_population(self): 4352 # self.clear() 4353 self.clear_plans() 4354 self.clear_ivehicles() 4355 4356 # TODO: this should disappear 4357 self.get_landuse().parking.clear_booking() 4358 4359 # for attrconfig in self.get_attrsman().get_colconfigs(): 4360 # attrconfig.clear() 4361 self.clear_rows() 4362 4363 def clear_plans(self): 4364 # print 'clear_plans',self.get_stagetables() 4365 self.ids_plan.reset() 4366 self.lists_ids_plan.reset() 4367 self.get_plans().clear_plans() 4368 4369 # TODO: this should disappear 4370 self.get_landuse().parking.clear_booking() 4371 4372 def clear_ivehicles(self): 4373 """ 4374 Clear all individually owned vehicles. 4375 """ 4376 print 'clear_ivehicles' 4377 self.get_iautos().clear_vehicles() 4378 self.get_ibikes().clear_vehicles() 4379 self.get_imotos().clear_vehicles() 4380 4381 def get_activities(self): 4382 return self.activities.get_value() 4383 4384 def get_strategies(self): 4385 return self.strategies.get_value() 4386 4387 def get_plans(self): 4388 return self.plans.get_value() 4389 4390 def get_iautos(self): 4391 return self.iautos.get_value() 4392 4393 def get_ibikes(self): 4394 return self.ibikes.get_value() 4395 4396 def get_imotos(self): 4397 return self.imotos.get_value() 4398 4399 def get_stagetables(self): 4400 return self.get_plans().get_stagetables() 4401 4402 def get_landuse(self): 4403 return self.parent.get_scenario().landuse 4404 4405 def get_scenario(self): 4406 return self.parent.get_scenario() 4407 4408 def get_net(self): 4409 return self.parent.get_scenario().net 4410 4411 def get_ptlines(self): 4412 return self.get_demand().ptlines 4413 4414 def get_ptstops(self): 4415 return self.get_net().ptstops 4416 4417 def get_id_sumo_from_id(self, id_sumo): 4418 return u'vp.%s' % id_sumo 4419 4420 def get_id_from_id_sumo(self, id_veh_sumo): 4421 if len(id_veh_sumo.split('.')) == 2: 4422 prefix, id_pers = id_veh_sumo.split('.') 4423 if prefix == 'vp': 4424 return int(id_pers) 4425 else: 4426 return -1 4427 return -1 4428 4429 def get_ids_from_ids_sumo(self, ids_sumo): 4430 ids = np.zeros(len(ids_sumo), dtype=int32) 4431 for id_sumo in ids_sumo: 4432 ids[i] = self.get_id_from_id_sumo(id_sumo) 4433 return ids 4434 4435 def get_time_depart_first(self): 4436 # print 'Virtualpop.get_time_depart_first' 4437 if len(self.get_plans()) > 0: 4438 plans = self.get_plans() 4439 ids = self.select_ids(self.ids_plan.get_value() >= 0) 4440 # print ' ids',ids 4441 return float(np.min(plans.times_begin[self.ids_plan[ids]])) 4442 else: 4443 return 0.0 4444 4445 def get_time_depart_last(self): 4446 if len(self.get_plans()) > 0: 4447 # todo: this can be improved by adding plan execution time 4448 plans = self.get_plans() 4449 ids = self.select_ids(self.ids_plan.get_value() >= 0) 4450 4451 return float(np.max(plans.times_end[self.ids_plan[ids]])) 4452 else: 4453 return 0.0 4454 4455 # def add_stagetable(self,ident,StageClass, **kwargs): 4456 # print 'add_stagetable',ident,StageClass#,kwargs 4457 # if not hasattr(self,ident): 4458 # #print ' StageClass',StageClass(ident, self, **kwargs) 4459 # #print ' ObjConf',cm.ObjConf(StageClass(ident, self, **kwargs), goupnames = ['stages']) 4460 # self.add(cm.ObjConf(StageClass(ident, self, **kwargs), goupnames = ['stages']) ) 4461 # return getattr(self, ident).get_value() 4462 4463 # def get_stagetable(self, ident): 4464 # return getattr(self, ident).get_value() 4465 4466 # def get_stagetables(self): 4467 # """Return a list of with all stage objects""" 4468 # stageobjs = [] 4469 # #print 'get_stagetables',self.get_group('stages') 4470 # for stageobj in self.get_group('stages'): 4471 # stageobjs.append(stageobj) 4472 # return stageobjs 4473 4474 def make_multiple(self, n, **kwargs): 4475 return self.add_rows(n=n, **kwargs) 4476 4477 def disaggregate_odflow(self, time_start, time_end, id_mode, 4478 ids_fac, probs_fac_orig, probs_fac_dest, 4479 tripnumber_tot, 4480 id_activitytype_orig, 4481 id_activitytype_dest, 4482 hour_begin_earliest_orig, 4483 hour_begin_earliest_dest, 4484 hour_begin_latest_orig, 4485 hour_begin_latest_dest, 4486 duration_min_orig, 4487 duration_min_dest, 4488 duration_max_orig, 4489 duration_max_dest, 4490 scale=1.0, 4491 hour_offset=8.0, # 08:00 4492 hour_tripbudget=25.0/60, # 25min 4493 **kwargs 4494 ): 4495 """ 4496 Disaggregation of demand dem from taz id_zone_orig to id_zone_dest with id_mode 4497 during time interval time_start,time_end, and creation of persons 4498 which are parameterized accordingly. 4499 The facility type at origin will be landusetype_orig 4500 and at destination landusetype_dest. 4501 4502 4503 """ 4504 tripnumber = int(scale*tripnumber_tot) 4505 print 'disaggregate_odflow', time_start, time_end, id_mode, tripnumber 4506 4507 print ' id_activitytype_orig,id_activitytype_dest', id_activitytype_orig, id_activitytype_dest 4508 4509 # print ' probs_orig',sum(probs_fac_orig),'\n',probs_fac_orig 4510 # print ' probs_dest',sum(probs_fac_dest),'\n',probs_fac_dest 4511 4512 # is there a chance to find facilities to locate persons in 4513 # origin and destination zone 4514 4515 #activitytypes= self.get_scenario().demand.activitytypes 4516 #ctivitynames = self.activitytypes.names 4517 #get_id_act = activitynames.get_id_from_index 4518 4519 if (np.sum(probs_fac_orig) > 0) & (np.sum(probs_fac_dest) > 0): 4520 # if id_mode == self._id_mode_bike: 4521 # are_bikeowner = np.ones(tripnumber, dtype=np.bool) 4522 # else: 4523 # # TODO: assign a default percentage of bike owners 4524 # are_bikeowner = np.zeros(tripnumber, dtype=np.bool) 4525 #times_start = np.random.randint(time_start,time_end,tripnumber) 4526 ids_person = self.make_multiple(tripnumber, 4527 ids_mode_preferred=id_mode * np.ones(tripnumber, dtype=np.int32), 4528 #times_start = times_start, 4529 ) 4530 4531 unitvec_int = np.ones(tripnumber, dtype=np.int32) 4532 unitvec_float = np.ones(tripnumber, dtype=np.int32) 4533 4534 # activity timing 4535 #hours_start = hour_offset + np.array(times_start,dtype = np.float32)/3600 4536 #tol_orig = hour_begin_latest_orig+duration_max_orig-(hour_begin_earliest_orig+duration_min_orig) 4537 4538 # print ' hours_start[:3]',hours_start[:3] 4539 # print ' tol_orig',tol_orig 4540 4541 #hours_end_est = hours_start + hour_tripbudget 4542 #tol_dest = hour_begin_latest_dest-hour_begin_earliest_dest 4543 4544 # print ' hours_end_est[:3]',hours_end_est[:3] 4545 # print ' tol_dest',tol_dest 4546 4547 #self.map_id_act_to_ids_facattrconf[id_activitytype_orig][ids_person] = ids_fac[random_choice(tripnumber, probs_fac_orig)] 4548 #self.map_id_act_to_ids_facattrconf[id_activitytype_dest][ids_person] = ids_fac[random_choice(tripnumber, probs_fac_dest)] 4549 activities = self.get_activities() 4550 4551 # fix first departure hours for first activity imposed by 4552 # OD flow data 4553 hours_end_earliest_orig = (hour_offset+float(time_start)/3600)*unitvec_float 4554 hours_end_latest_orig = (hour_offset+float(time_end)/3600)*unitvec_float 4555 4556 duration_mean_orig = 0.5 * duration_min_orig+duration_max_orig 4557 hours_begin_earliest_orig = hours_end_earliest_orig-duration_mean_orig 4558 hours_begin_latest_orig = hours_end_latest_orig-duration_mean_orig 4559 4560 # this estimate could be *optionally* replaced by preliminary routing 4561 hours_begin_earliest_dest = hours_end_earliest_orig+hour_tripbudget 4562 hours_begin_latest_dest = hours_end_latest_orig+hour_tripbudget 4563 4564 #hours_end_earliest_dest = hours_begin_earliest_dest+duration_min_dest 4565 #hours_end_latest_dest = hours_begin_latest_dest+duration_max_dest 4566 4567 ids_activity_orig = activities.add_rows( 4568 n=tripnumber, 4569 ids_activitytype=id_activitytype_orig * unitvec_int, 4570 ids_facility=ids_fac[random_choice(tripnumber, probs_fac_orig)], 4571 hours_begin_earliest=hours_begin_earliest_orig, 4572 hours_begin_latest=hours_begin_latest_orig, 4573 durations_min=duration_mean_orig-1.0/60.0 * unitvec_float, # min mast be less than max to prevent crash 4574 durations_max=duration_mean_orig * unitvec_float, 4575 ) 4576 4577 ids_activity_dest = activities.add_rows( 4578 n=tripnumber, 4579 ids_activitytype=id_activitytype_dest * unitvec_int, 4580 ids_facility=ids_fac[random_choice(tripnumber, probs_fac_dest)], 4581 hours_begin_earliest=hours_begin_earliest_dest, 4582 hours_begin_latest=hours_begin_latest_dest, 4583 durations_min=duration_min_dest*unitvec_float, 4584 durations_max=duration_max_dest*unitvec_float, 4585 ) 4586 4587 for id_person, id_activity_orig, id_activity_dest in zip(ids_person, ids_activity_orig, ids_activity_dest): 4588 self.activitypatterns[id_person] = [id_activity_orig, id_activity_dest] 4589 4590 #activitypatterns = np.zeros((tripnumber,2), dtype = np.int32) 4591 #activitypatterns[:,0]= ids_activity_orig 4592 #activitypatterns[:,1]= ids_activity_dest 4593 # try convert in this way to lists 4594 # print ' activitypatterns',activitypatterns.tolist() 4595 #self.activitypatterns[ids_person] = activitypatterns.tolist() 4596 # for id_person, act_pattern in zip(ids_person,activitypatterns.tolist()): 4597 # self.activitypatterns[id_person] = act_pattern 4598 4599 return ids_person 4600 else: 4601 print 'WARNING in disaggregate_odflow: no probabilities', np.sum(probs_fac_orig), np.sum(probs_fac_dest) 4602 4603 return [] 4604 4605 def create_pop_from_odflows(self, is_use_landusetypes=False, **kwargs): 4606 """ 4607 Creates a population and defines home and activity facility 4608 according to OD matrix defined in odflows. 4609 The population is distributed within the zones according to 4610 the area of the facility. 4611 if landusetype_orig and landusetype_dest also landuse types 4612 of facilities of origin and destination are taken into account. 4613 """ 4614 print 'create_pop_from_odflows' 4615 4616 demand = self.parent 4617 odflowtab = demand.odintervals.generate_odflows() 4618 landuse = self.get_landuse() 4619 activitytypes = demand.activitytypes 4620 log = kwargs.get('logger', self.get_logger()) 4621 4622 if is_use_landusetypes: 4623 4624 # TODO: not tested and works only for one landusetype per activity 4625 #activitytypes = self.activitytypes.get_value() 4626 #id_landusetype_orig = activitytypes.ids_landusetypes[kwargs['id_activitytype_orig']][0] 4627 #id_landusetype_dest = activitytypes.ids_landusetypes[kwargs['id_activitytype_dest']][0] 4628 pass 4629 # TODO: get activitypes from activity 4630 #probs_fac, ids_fac = self.get_landuse().facilities.get_departure_probabilities_landuse() 4631 4632 else: 4633 probs_fac_area, ids_fac = landuse.facilities.get_departure_probabilities() 4634 4635 # self._make_map_id_act_to_ids_facattrconf() 4636 ids_flow = odflowtab.get_ids() 4637 n_flows = len(ids_flow) 4638 4639 ids_activitytype_orig = odflowtab.ids_activitytype_orig[ids_flow] 4640 ids_activitytype_dest = odflowtab.ids_activitytype_dest[ids_flow] 4641 4642 i = 0.0 4643 for id_flow,\ 4644 id_orig,\ 4645 id_dest,\ 4646 id_mode,\ 4647 time_start,\ 4648 time_end,\ 4649 tripnumber,\ 4650 id_activitytype_orig,\ 4651 id_activitytype_dest,\ 4652 hour_begin_earliest_orig,\ 4653 hour_begin_earliest_dest,\ 4654 hour_begin_latest_orig,\ 4655 hour_begin_latest_dest,\ 4656 duration_min_orig,\ 4657 duration_min_dest,\ 4658 duration_max_orig,\ 4659 duration_max_dest\ 4660 in zip(ids_flow, 4661 odflowtab.ids_orig[ids_flow], 4662 odflowtab.ids_dest[ids_flow], 4663 odflowtab.ids_mode[ids_flow], 4664 odflowtab.times_start[ids_flow], 4665 odflowtab.times_end[ids_flow], 4666 odflowtab.tripnumbers[ids_flow], 4667 ids_activitytype_orig, 4668 ids_activitytype_dest, 4669 activitytypes.hours_begin_earliest[ids_activitytype_orig], 4670 activitytypes.hours_begin_earliest[ids_activitytype_dest], 4671 activitytypes.hours_begin_latest[ids_activitytype_orig], 4672 activitytypes.hours_begin_latest[ids_activitytype_dest], 4673 activitytypes.durations_min[ids_activitytype_orig], 4674 activitytypes.durations_min[ids_activitytype_dest], 4675 activitytypes.durations_max[ids_activitytype_orig], 4676 activitytypes.durations_max[ids_activitytype_dest], 4677 ): 4678 4679 log.progress(i/n_flows*100) 4680 i += 1 4681 if is_use_landusetypes: 4682 # TODO: not tested and works only for one landusetype per activity 4683 # but in activity typrs several landuse types are defined 4684 4685 # idea: add the probabilities for landuse types of origin and dest 4686 #probs_fac_orig = probs_fac[id_orig][id_landusetype_orig] 4687 #probs_fac_dest = probs_fac[id_dest][id_landusetype_dest] 4688 pass 4689 else: 4690 probs_fac_orig = probs_fac_area[id_orig] 4691 probs_fac_dest = probs_fac_area[id_dest] 4692 4693 self.disaggregate_odflow(time_start, 4694 time_end, 4695 id_mode, 4696 ids_fac, 4697 probs_fac_orig, 4698 probs_fac_dest, 4699 tripnumber, 4700 id_activitytype_orig, 4701 id_activitytype_dest, 4702 hour_begin_earliest_orig, 4703 hour_begin_earliest_dest, 4704 hour_begin_latest_orig, 4705 hour_begin_latest_dest, 4706 duration_min_orig, 4707 duration_min_dest, 4708 duration_max_orig, 4709 duration_max_dest, 4710 **kwargs 4711 ) 4712 4713 # return odflowtab 4714 4715 def add_plans(self, ids_person, id_strategy=-1): 4716 print 'add_plans n, id_strategy', len(ids_person), id_strategy 4717 n_plans = len(ids_person) 4718 # print ' get_plans',self.get_plans() 4719 # print ' stagetables',self.get_plans().get_stagetables().get_ident_abs() 4720 # print ' stagetables',self.get_plans().get_stagetables().stagetables.get_value() 4721 ids_plan = self.get_plans().add_rows(n=n_plans, 4722 ids_person=ids_person, 4723 ids_strategy=id_strategy*np.ones(n_plans, dtype=np.int32), 4724 ) 4725 4726 # print ' post stagetables',self.get_plans().get_stagetables().get_ident_abs() 4727 # print ' post stagetables',self.get_plans().get_stagetables().stagetables.get_value() 4728 4729 # return ids_plan 4730 self.ids_plan[ids_person] = 1*ids_plan 4731 4732 for id_person, id_plan in zip(ids_person, ids_plan): 4733 if self.lists_ids_plan[id_person] is None: 4734 self.lists_ids_plan[id_person] = [id_plan] 4735 else: 4736 self.lists_ids_plan[id_person].append(id_plan) 4737 return ids_plan 4738 4739 def plan_with_strategy(self, id_strategy, evalcrit=0, logger=None): 4740 strategy = self.get_strategies().strategies[id_strategy] 4741 ids_person = self.get_ids() 4742 evals = strategy.preevaluate(ids_person) 4743 # TODO: check whether at least two activities are in 4744 # activitypattern...could be done centrally 4745 4746 ids_person_preeval = ids_person[evals >= evalcrit] 4747 print 'plan_with_strategy', strategy.ident, 'n_pers', len(ids_person_preeval) 4748 strategy.plan(ids_person_preeval, logger=logger) 4749 4750 # def get_times(self, ind, ids_person = None, pdf = 'unit'): 4751 # """ 4752 # Returns person IDs, activity IDs and initial times 4753 # for persons with at least one acivity. 4754 # 4755 # ids_person: array of preselected person IDs 4756 # 4757 # pdf: gives the probability density function to be chosen to determin 4758 # the departure times within the initial time intervals given by 4759 # initial activity attributes. 4760 # """ 4761 # ids_person, ids_activity = self.get_activity_from_pattern(0,ids_person) 4762 # times_init = self.get_activities().get_times_init(ids_activity, pdf) 4763 # 4764 # return ids_person, ids_activity, times_init 4765 4766 def get_activities_from_pattern(self, ind, ids_person=None): 4767 """ 4768 Returns person IDs and from/to activity IDs for persons who perform an activity 4769 at the given activity index ind. 4770 Returns arrays: ids_person, ids_activity_from, ids_activity_to 4771 4772 ind: index of activity in activity pattern, starting with 0 4773 ids_person: array of preselected person IDs 4774 4775 4776 """ 4777 4778 ids_person_activity = [] 4779 ids_activity_from = [] 4780 ids_activity_to = [] 4781 if ids_person is None: 4782 ids_person = self.get_ids() 4783 4784 for id_person, activitypattern in zip(ids_person, self.activitypatterns[ids_person]): 4785 # has person activity at index ind? 4786 if len(activitypattern) > ind+1: 4787 ids_person_activity.append(id_person) 4788 ids_activity_from.append(activitypattern[ind]) 4789 ids_activity_to.append(activitypattern[ind+1]) 4790 4791 return ids_person_activity, ids_activity_from, ids_activity_to 4792 4793 # activities.hours_begin_earliest[ids_person_activity], 4794 # activities.hours_begin_latest[ids_person_activity], 4795 # activities.durations_min[ids_person_activity], 4796 # activities.durations_max[ids_person_activity], 4797 4798 def get_vtypes(self): 4799 4800 ids_vtypes = set() 4801 # get individual vehicle types 4802 ids_vtypes.update(self.get_iautos().ids_vtype.get_value()) 4803 ids_vtypes.update(self.get_imotos().ids_vtype.get_value()) 4804 ids_vtypes.update(self.get_ibikes().ids_vtype.get_value()) 4805 4806 # add public transport 4807 ids_vtypes.update(self.get_ptlines().ids_vtype.get_value()) 4808 4809 # add pedestrian types 4810 ids_vtypes.update(self.ids_vtype.get_value()) 4811 4812 return ids_vtypes 4813 4814 def select_plans_preferred_mode(self, fraction=0.1, **kwargs): 4815 """ 4816 Selects current plant to satisfy best the preferred mode. 4817 """ 4818 4819 strategies = self.get_strategies() 4820 ids_strat = strategies.get_ids() 4821 n_strat = len(ids_strat) 4822 ids_pers_all = self.get_ids() 4823 ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)] 4824 n_pers = len(ids_pers) 4825 preevals = -1*np.ones((np.max(ids_pers)+1, np.max(ids_strat)+1), dtype=np.int32) 4826 for ind, id_strategy, strategy in zip(range(n_strat), ids_strat, strategies.strategies[ids_strat]): 4827 preevals[ids_pers, id_strategy] = strategy.preevaluate(ids_pers) 4828 4829 preferred = 2 4830 plans = self.get_plans() 4831 self.ids_plan.reset() 4832 for id_pers, ids_plan in zip(ids_pers, self.lists_ids_plan[ids_pers]): 4833 if len(ids_plan) > 0: 4834 # print ' id_pers,ids_plan',id_pers,ids_plan 4835 # print ' ids_strat, preeval',plans.ids_strategy[ids_plan],preevals[id_pers,plans.ids_strategy[ids_plan]] 4836 inds_sel = preevals[id_pers, plans.ids_strategy[ids_plan]] == preferred 4837 # print ' inds_sel',inds_sel,np.flatnonzero(inds_sel),inds_sel.dtype 4838 if len(inds_sel) > 0: 4839 #ids_plan_sel = np.array(ids_plan)[inds_sel] 4840 # print ' ids_plan_sel',ids_plan_sel 4841 # at least one plan contains preferred mode 4842 self.ids_plan[id_pers] = np.array(ids_plan)[inds_sel][0] # whu [1]? 4843 # else: 4844 # assumption: a plan for the preferred mode always exists 4845 # # no preferred mode found try to satisfy best possible 4846 # #ids_plan[preevals[id_pers,plans.ids_strategy[ids_plan]] == preferred] 4847 # self.ids_plan[id_pers] = -1 4848 return True 4849 4850 def select_plans_min_time_est(self, fraction=1.0, timedev=-1.0, c_probit=-1.0, **kwargs): 4851 """ 4852 Select plan with minimum estimated travel time as current plant. 4853 """ 4854 ids_pers_all = self.get_ids() 4855 ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)] 4856 times_est = self.get_plans().times_est 4857 # self.ids_plan.reset() 4858 for id_pers, ids_plan_all in zip(ids_pers, self.lists_ids_plan[ids_pers]): 4859 ids_plan = np.array(ids_plan_all, dtype=np.int32)[times_est[ids_plan_all] > 0.1] 4860 if len(ids_plan) > 0: 4861 # print ' id_pers,ids_plan',id_pers,ids_plan 4862 if timedev > 0.1: 4863 times_rand = np.random.normal(0.0, timedev, len(ids_plan)) 4864 elif c_probit > 0: 4865 times_rand = np.zeros(len(ids_plan), dtype=np.float32) 4866 for i, t in zip(xrange(len(ids_plan)), times_est[ids_plan]): 4867 times_rand[i] = np.random.normal(0.0, c_probit * t, 1) 4868 4869 else: 4870 times_rand = np.zeros(len(ids_plan), dtype=np.float32) 4871 self.ids_plan[id_pers] = np.array(ids_plan)[np.argmin(times_est[ids_plan]+times_rand)] 4872 return True 4873 4874 def select_plans_random(self, fraction=0.1, **kwargs): 4875 """ 4876 A fraction of the population changes a plan. 4877 The new plans are chosen randomly. 4878 """ 4879 4880 ids_pers_all = self.get_ids() 4881 print 'select_plans_random', len(ids_pers_all), fraction 4882 times_est = self.get_plans().times_est 4883 # self.ids_plan.reset() 4884 # ids_mode[random_choice(n,shares/np.sum(shares))] 4885 4886 ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)] 4887 print ' ids_pers', ids_pers 4888 for id_pers, ids_plan in zip(ids_pers, self.lists_ids_plan[ids_pers]): 4889 if len(ids_plan) > 0: 4890 # print ' id_pers,ids_plan',id_pers,ids_plan 4891 self.ids_plan[id_pers] = ids_plan[np.random.randint(len(ids_plan))] 4892 return True 4893 4894 def select_plans_min_time_exec(self, fraction=0.1, timedev=-1, c_probit=-1, **kwargs): 4895 """ 4896 Select plan with minimum executed travel time as current plant. 4897 """ 4898 ids_pers_all = self.get_ids() 4899 # print 'select_plans_random',len(ids_pers_all),fraction 4900 ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)] 4901 times_exec = self.get_plans().times_exec 4902 # self.ids_plan.reset() 4903 for id_pers, ids_plan_all in zip(ids_pers, self.lists_ids_plan[ids_pers]): 4904 # print ' ids_plan_all',ids_plan_all,type(ids_plan_all) 4905 ids_plan = np.array(ids_plan_all, dtype=np.int32)[times_exec[ids_plan_all] > 0.1] 4906 if len(ids_plan) > 0: 4907 # print ' id_pers,ids_plan',id_pers,ids_plan 4908 if timedev > 0.1: 4909 times_rand = np.random.normal(0.0, timedev, len(ids_plan)) 4910 elif c_probit > 0: 4911 times_rand = np.zeros(len(ids_plan), dtype=np.float32) 4912 for i, t in zip(xrange(len(ids_plan)), times_exec[ids_plan]): 4913 times_rand[i] = np.random.normal(0.0, c_probit * t, 1) 4914 4915 else: 4916 times_rand = np.zeros(len(ids_plan), dtype=np.float32) 4917 4918 self.ids_plan[id_pers] = np.array(ids_plan)[np.argmin(times_exec[ids_plan]+times_rand)] 4919 return True 4920 4921 def select_plans_min_time_exec_est(self, fraction=0.1, timedev=-1, c_probit=-1, **kwargs): 4922 """ 4923 Select plan with minimum executed or estimated (if executed doesn't exist) travel time as current plant. 4924 """ 4925 n_analyzed_persons = 0 4926 ids_pers_all = self.get_ids() 4927 ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)] 4928 times_exec = self.get_plans().times_exec 4929 times_est = self.get_plans().times_est 4930 ids_plans = self.get_plans().get_ids() 4931 for id_pers, ids_plan_all in zip(ids_pers, self.lists_ids_plan[ids_pers]): 4932 ids_plan_est = np.array(ids_plan_all, dtype=np.int32)[times_est[ids_plan_all] > 0.1] 4933 ids_plan_exec = np.array(ids_plan_all, dtype=np.int32)[times_exec[ids_plan_all] > 0.1] 4934 if len(ids_plan_est) > 0: 4935 if len(ids_plan_est) == len(ids_plan_exec): 4936 ids_plan_est = [] 4937 else: 4938 c = np.zeros(len(ids_plan_est)) 4939 for x in range(len(ids_plan_est)): 4940 for y in range(len(ids_plan_exec)): 4941 if ids_plan_est[x] == ids_plan_exec[y]: 4942 c[x] = 1 4943 d = np.delete(ids_plan_est, np.flatnonzero(c)) 4944 ids_plan_est = d 4945 4946 n_analyzed_persons += 1 4947 4948 if timedev > 0.1: 4949 if len(ids_plan_est) > 0: 4950 times_rand_est = np.random.normal(0.0, timedev, len(ids_plan_est)) 4951 if len(ids_plan_exec) > 0: 4952 times_rand_exec = np.random.normal(0.0, timedev, len(ids_plan_exec)) 4953 4954 elif c_probit > 0: 4955 if len(ids_plan_est) > 0: 4956 times_rand_est = np.zeros(len(ids_plan_est), dtype=np.float32) 4957 for i, t in zip(xrange(len(ids_plan_est)), times_est[ids_plan_est]): 4958 times_rand_est[i] = np.random.normal(0.0, c_probit * t, 1) 4959 if len(ids_plan_exec) > 0: 4960 times_rand_exec = np.zeros(len(ids_plan_exec), dtype=np.float32) 4961 for i, t in zip(xrange(len(ids_plan_exec)), times_exec[ids_plan_exec]): 4962 times_rand_exec[i] = np.random.normal(0.0, c_probit * t, 1) 4963 4964 else: 4965 if len(ids_plan_exec) > 0: 4966 times_rand_exec = np.zeros(len(ids_plan_exec), dtype=np.float32) 4967 if len(ids_plan_est) > 0: 4968 times_rand_est = np.zeros(len(ids_plan_est), dtype=np.float32) 4969 4970 if len(ids_plan_exec) > 0 and len(ids_plan_est) > 0: 4971 if min(times_exec[ids_plan_exec]+times_rand_exec) < min(times_est[ids_plan_est]+times_rand_est): 4972 self.ids_plan[id_pers] = np.array(ids_plan_exec)[np.argmin( 4973 times_exec[ids_plan_exec]+times_rand_exec)] 4974 else: 4975 self.ids_plan[id_pers] = np.array( 4976 ids_plan_est)[np.argmin(times_est[ids_plan_est]+times_rand_est)] 4977 elif len(ids_plan_exec) == 0: 4978 self.ids_plan[id_pers] = np.array(ids_plan_est)[np.argmin(times_est[ids_plan_est]+times_rand_est)] 4979 4980 else: 4981 4982 self.ids_plan[id_pers] = np.array(ids_plan_exec)[np.argmin( 4983 times_exec[ids_plan_exec]+times_rand_exec)] 4984 4985 print 'were analyzed %d persons' % (n_analyzed_persons) 4986 return True 4987 4988 def select_plans_next(self, fraction=0.1, **kwargs): 4989 """ 4990 Select next plan in the plan list as current plant. 4991 """ 4992 # print 'select_plans_next' 4993 ids_pers_all = self.get_ids() 4994 ids_pers = ids_pers_all[np.random.random(len(ids_pers_all)) > (1.0-fraction)] 4995 for id_pers, id_plan_current, ids_plan in zip(ids_pers, self.ids_plan[ids_pers], self.lists_ids_plan[ids_pers]): 4996 n_plan = len(ids_plan) 4997 if n_plan > 0: 4998 # print ' id_pers,id_plan_current',id_pers,id_plan_current,ids_plan,id_plan_current != -1 4999 if id_plan_current != -1: 5000 ind = ids_plan.index(id_plan_current) 5001 # print ' ind',ind,ind +1 < n_plan 5002 if ind + 1 < n_plan: 5003 ind += 1 5004 else: 5005 ind = 0 5006 else: 5007 ind = 0 5008 5009 # print ' ind,n_plan',ind,n_plan,'ids_plan[ind]', ids_plan[ind] 5010 self.ids_plan[id_pers] = ids_plan[ind] 5011 # print ' finally: ids_plan=',self.ids_plan.get_value() 5012 return True 5013 5014 def prepare_sim(self, process): 5015 return [] # [(steptime1,func1),(steptime2,func2),...] 5016 5017 def get_trips(self): 5018 # returns trip object, method common to all demand objects 5019 return self.get_iautos() 5020 5021 def get_writexmlinfo(self, is_route=False): 5022 """ 5023 Returns three array where the first array is the 5024 begin time of the first vehicle and the second array is the 5025 write function to be called for the respectice vehicle and 5026 the third array contains the vehicle ids 5027 5028 Method used to sort trips when exporting to route or trip xml file 5029 """ 5030 print 'Virtualpop.get_writexmlinfo' 5031 plans = self.get_plans() 5032 5033 ids_pers = self.select_ids(self.ids_plan.get_value() >= 0) 5034 n_pers = len(ids_pers) 5035 ids_plans = self.ids_plan[ids_pers] 5036 5037 # get vehicle trip info 5038 times_depart_bike, writefuncs_bike, ids_rides_bike = plans.get_stagetable( 5039 'bikerides').get_writexmlinfo(ids_plans, is_route) 5040 times_depart_auto, writefuncs_auto, ids_rides_auto = plans.get_stagetable( 5041 'autorides').get_writexmlinfo(ids_plans, is_route) 5042 5043 #self.add_stagetable('walks', WalkStages) 5044 #self.add_stagetable('autorides', AutorideStages) 5045 #self.add_stagetable('bikerides', BikerideStages) 5046 #self.add_stagetable('transits', TransitStages) 5047 #self.add_stagetable('activities', ActivityStages) 5048 5049 #rides = plans.get_stagetable('autorides') 5050 5051 # do persons 5052 5053 times_depart_pers = plans.times_begin[ids_plans] 5054 writefuncs_pers = np.zeros(n_pers, dtype=np.object) 5055 writefuncs_pers[:] = self.write_person_xml 5056 5057 # assemble vectors 5058 print ' times_depart_pers.shape', times_depart_pers.shape 5059 print ' times_depart_bike.shape', times_depart_bike.shape 5060 print ' times_depart_auto.shape', times_depart_auto.shape 5061 times_depart = np.concatenate((times_depart_pers, 5062 times_depart_auto, 5063 times_depart_bike, 5064 )) 5065 5066 writefuncs = np.concatenate((writefuncs_pers, 5067 writefuncs_auto, 5068 writefuncs_bike, 5069 )) 5070 5071 ids = np.concatenate((ids_pers, 5072 ids_rides_auto, 5073 ids_rides_bike, 5074 )) 5075 5076 return times_depart, writefuncs, ids 5077 5078 def write_person_xml(self, fd, id_pers, time_begin, indent=2): 5079 5080 stages = self.get_plans().get_stages(self.ids_plan[id_pers]) 5081 5082 fd.write(xm.start('person', indent=indent+2)) 5083 fd.write(xm.num('id', self.get_id_sumo_from_id(id_pers))) 5084 # fd.write(xm.num('depart',self.times_start[id_pers])) 5085 fd.write(xm.num('depart', time_begin)) 5086 fd.write(xm.num('type', self.parent.vtypes.ids_sumo[self.ids_vtype[id_pers]])) 5087 5088 activity_init, id_stage_init = stages[0] 5089 id_edge_init, pos_init = activity_init.get_edges_positions(id_stage_init) 5090 5091 # self.ids_edge_depart.write_xml(fd,id_trip) 5092 # self.positions_depart.write_xml(fd,id_trip) 5093 fd.write(xm.num('from', self._edges.ids_sumo[id_edge_init])) 5094 fd.write(xm.num('departPos', pos_init)) 5095 5096 fd.write(xm.stop()) 5097 5098 # write stages of this person. 5099 # Attention!! first and last stage, which are activities, 5100 # will NOT be exportes , therefore [1:-1] 5101 for stage, id_stage in stages[1:-1]: 5102 stage.to_xml(id_stage, fd, indent+4) 5103 5104 fd.write(xm.end('person', indent=indent+2)) 5105 5106 def config_results(self, results): 5107 5108 results.add_resultobj(res.Personresults('virtualpersonresults', results, 5109 self, 5110 self.get_net().edges, 5111 name='Virtual person results', 5112 info='Table with simulation results for person of the virtual population. The results refer to all trips made by the person during the entire simulation period.', 5113 ), groupnames=['Trip results']) 5114 5115 results.add_resultobj(res.Vehicleresults('iautotripresults', results, 5116 self.get_iautos(), 5117 self.get_net().edges, 5118 name='Auto trip results', 5119 info='Table with trip results mad with individual autos. The results refer to all trips made by a specific vehicle during the entire simulation period.', 5120 ), groupnames=['Trip results']) 5121 5122 results.add_resultobj(res.Vehicleresults('ibiketripresults', results, 5123 self.get_ibikes(), 5124 self.get_net().edges, 5125 name='Bike trip results', 5126 info='Table with trip results mad with individual bikes. The results refer to all trips made by a specific vehicle during the entire simulation period.', 5127 ), groupnames=['Trip results']) 5128 5129 # def process_results(self, results, process = None): 5130 # print 'process_results' 5131 # ## copy total travel into plan execution time 5132 # personresults = results.virtualpersonresults 5133 # self.update_plans(personresults) 5134 5135 def update_results(self, personresults): 5136 """ 5137 Updates plans with results from previous 5138 simulation run, and updates plan choice 5139 """ 5140 5141 ids_res = personresults.get_ids() 5142 print 'update_results', len(ids_res) 5143 ids_person = personresults.ids_person[ids_res] 5144 ids_plan = self.ids_plan[ids_person] 5145 self.get_plans().times_exec[ids_plan] = personresults.times_travel_total[ids_res] 5146 # change mobility plan based on updated travel times 5147 pass 5148 5149 5150class PopGenerator(Process): 5151 def __init__(self, ident='virtualpopgenerator', virtualpop=None, logger=None, **kwargs): 5152 print 'PopFromOdfGenerator.__init__ ', ident, virtualpop 5153 5154 # TODO: let this be independent, link to it or child?? 5155 # 5156 scenario = virtualpop.get_scenario() 5157 self._init_common(ident, 5158 parent=virtualpop, 5159 name='Population generator', 5160 logger=logger, 5161 info='Create virtual population from basic statistical data.', 5162 ) 5163 5164 attrsman = self.set_attrsman(cm.Attrsman(self)) 5165 5166 # make for each possible pattern a field for prob 5167 activitytypes = self.parent.get_scenario().demand.activitytypes 5168 5169 self.n_person = attrsman.add(cm.AttrConf('n_person', kwargs.get('n_person', 1000), 5170 groupnames=['options'], 5171 perm='rw', 5172 name='Number of person', 5173 info='Number of adult persons.', 5174 )) 5175 5176 self.ids_acttype_default = activitytypes.get_ids_from_formatted('home,work') 5177 # self.ids_acttype = attrsman.add(cm.AttrConf( 'ids_acttype',kwargs.get('id_acttype',activitytypes.get_id_from_formatted('home')), 5178 # groupnames = ['options'], 5179 # choices = activitytypes.names.get_indexmap(), 5180 # perm='rw', 5181 # name = 'Activity type', 5182 # info = 'Initial activity type.', 5183 # )) 5184 5185 self.ttb_mean = attrsman.add(cm.AttrConf('ttb_mean', kwargs.get('ttb_mean', 55*60), 5186 groupnames=['options'], 5187 perm='rw', 5188 name='Avg. of 24h travel time budget', 5189 unit='s', 5190 info="""Average travel time budget for one day. 5191 This time excludes time for activities. 5192 """, 5193 )) 5194 self.ttb_dev = attrsman.add(cm.AttrConf('ttb_dev', kwargs.get('ttb_dev', 10*60), 5195 groupnames=['options'], 5196 perm='rw', 5197 name='Std. of 24h travel time budget', 5198 unit='s', 5199 info="""Standard deviation of travel time budget for one day. 5200 """, 5201 )) 5202 5203 mode_to_id = self.parent.get_scenario().net.modes.get_id_mode 5204 self.share_pedestrian = attrsman.add(cm.AttrConf('share_pedestrian', kwargs.get('share_pedestrian', 0.1), 5205 groupnames=['options', 'modal split'], 5206 perm='rw', 5207 id_mode=mode_to_id('pedestrian'), 5208 name='Pedestrian share', 5209 info="""Share of pedestrians.""", 5210 )) 5211 5212 self.share_autouser = attrsman.add(cm.AttrConf('share_autouser', kwargs.get('share_autouser', 0.5), 5213 groupnames=['options', 'modal split'], 5214 perm='rw', 5215 id_mode=mode_to_id('passenger'), 5216 name='Auto user share', 5217 info="""Share of auto users.""", 5218 )) 5219 5220 self.share_motorcycleuser = attrsman.add(cm.AttrConf('share_motorcycleuser', kwargs.get('share_motorcycleuser', 0.1), 5221 groupnames=['options', 'modal split'], 5222 perm='rw', 5223 id_mode=mode_to_id('motorcycle'), 5224 name='Motorcycle user share', 5225 info="""Share of Motorcycle users.""", 5226 )) 5227 5228 self.share_bikeuser = attrsman.add(cm.AttrConf('share_bikeuser', kwargs.get('share_bikeuser', 0.1), 5229 groupnames=['options', 'modal split'], 5230 perm='rw', 5231 id_mode=mode_to_id('bicycle'), 5232 name='Bike user share', 5233 info="""Share of bike users.""", 5234 )) 5235 5236 self.share_ptuser = attrsman.add(cm.AttrConf('share_ptuser', kwargs.get('share_ptuser', 0.2), 5237 groupnames=['options', 'modal split'], 5238 id_mode=mode_to_id('bus'), 5239 perm='rw', 5240 name='PT share', 5241 info="""Share of public transport user.""", 5242 )) 5243 5244 #self.modeshares = attrsman.add( cm.ObjConf(ModeShares('modeshares',self,scenario.net.modes),groupnames = ['options']) ) 5245 5246 def do(self): 5247 print 'PopGenerator.do' 5248 # links 5249 5250 virtualpop = self.parent 5251 virtualpop.clear_population() 5252 logger = self.get_logger() 5253 #logger.w('Update Landuse...') 5254 scenario = virtualpop.get_scenario() 5255 activitytypes = scenario.demand.activitytypes 5256 facilities = scenario.landuse.facilities 5257 edges = scenario.net.edges 5258 5259 ids_fac = facilities.get_ids() 5260 map_id_edge_to_ids_fac = {} 5261 for id_fac, id_edge in zip(ids_fac, facilities.ids_roadedge_closest[ids_fac]): 5262 if map_id_edge_to_ids_fac.has_key(id_edge): 5263 map_id_edge_to_ids_fac[id_edge].append(id_fac) 5264 else: 5265 map_id_edge_to_ids_fac[id_edge] = [id_fac, ] 5266 5267 n_pers = self.n_person 5268 unitvec_int = np.ones(n_pers, dtype=np.int32) 5269 5270 ids_person = virtualpop.make_multiple(n_pers) 5271 virtualpop.traveltimebudgets[ids_person] = self.get_ttb(ids_person) 5272 5273 virtualpop.ids_mode_preferred[ids_person] = self.get_modes_random(n_pers) 5274 5275 # here we could preselect correct landuse based on 5276 # percentage of workers, students, employees 5277 prob_fac_to = facilities.capacities[ids_fac].astype(np.float32) 5278 prob_fac_to /= np.sum(prob_fac_to) 5279 # print ' np.sum(prob_fac_to)',np.sum(prob_fac_to) 5280 ids_fac_to = ids_fac[random_choice(n_pers, prob_fac_to)] 5281 5282 # determine id_fac_from by backward routing from id_fac_to 5283 ids_edge_to = facilities.ids_roadedge_closest[ids_fac_to] 5284 5285 # pre calculate backward star and mode dependent link travel times 5286 bstar = edges.get_bstar() 5287 edgetimes = {} 5288 ids_mode = self.get_ids_mode() 5289 # idea: do also consider gradient of house prices 5290 for id_mode, speed_max in zip(ids_mode, scenario.net.modes.speeds_max[ids_mode]): 5291 edgetimes[id_mode] = edges.get_times(id_mode=id_mode, 5292 speed_max=speed_max, 5293 is_check_lanes=True 5294 ) 5295 # determine home facilities by backwards tracking from work facility 5296 ids_fac_from = np.ones(n_pers, dtype=np.int32) 5297 i = 0 5298 for id_person, id_edge_to, id_mode, ttb\ 5299 in zip(ids_person, 5300 ids_edge_to, 5301 virtualpop.ids_mode_preferred[ids_person], 5302 virtualpop.traveltimebudgets[ids_person], 5303 ): 5304 5305 # print ' Backsearch',id_person,'id_edge_to',id_edge_to,edges.ids_sumo[id_edge_to],'ttb[s]',0.5*ttb 5306 ids_edge_from, costs, btree = routing.edgedijkstra_backwards(id_edge_to, 5307 0.5*ttb, # to be specified better 5308 weights=edgetimes[id_mode], 5309 bstar=bstar, 5310 ) 5311 if len(ids_edge_from) == 0: 5312 # routing failed to deliver edges of origins 5313 # put work and home on same edge 5314 ids_edge_from = [id_edge_to, ] 5315 5316 # look at all edges of origin and pick most likely facility 5317 ids_fac_lim = [] 5318 for id_edge_from in ids_edge_from: 5319 5320 #id_from_check = id_edge_from 5321 # print ' check from',id_from_check,'back to',id_edge_to,'time =%.2fs'%costs[id_from_check] 5322 # while id_from_check != id_edge_to: 5323 # id_from_check = btree[id_from_check] 5324 # #print ' id_edge = ',id_from_check 5325 # print ' success = ',id_from_check==id_edge_to 5326 if map_id_edge_to_ids_fac.has_key(id_edge_from): 5327 ids_fac_lim += map_id_edge_to_ids_fac[id_edge_from] 5328 5329 if len(ids_fac_lim) == 0: 5330 # no facilities at all destinations found 5331 # go edges backawards and search there 5332 # this will reduce travel time 5333 for id_edge_from in ids_edge_from: 5334 # verify if id_edge_from has facilities. 5335 while not map_id_edge_to_ids_fac.has_key(id_edge_from): 5336 # print ' no facility, go backward' 5337 id_edge_from = btree[id_edge_from] 5338 5339 ids_fac_lim = np.array(ids_fac_lim, dtype=np.int32) 5340 5341 prob_fac_from = facilities.capacities[ids_fac_lim].astype(np.float32) 5342 prob_fac_from /= np.sum(prob_fac_from) 5343 # print ' np.sum(prob_fac_to)',np.sum(prob_fac_to) 5344 ids_fac_from[i] = ids_fac[random_choice(1, prob_fac_to)] 5345 i += 1 5346 5347 # idea: adjust wake-up time with employment type 5348 activities = virtualpop.get_activities() 5349 ids_activity_from = activities.add_rows( 5350 n=n_pers, 5351 ids_activitytype=self.ids_acttype_default[0] * unitvec_int, 5352 ids_facility=ids_fac_from, 5353 # use default 5354 #hours_begin_earliest = None, 5355 #hours_begin_latest = None, 5356 #durations_min = None, 5357 #durations_max = None, 5358 ) 5359 5360 ids_activity_to = activities.add_rows( 5361 n=n_pers, 5362 ids_activitytype=self.ids_acttype_default[1] * unitvec_int, 5363 ids_facility=ids_fac_to, 5364 # use default 5365 #hours_begin_earliest = None, 5366 #hours_begin_latest = None, 5367 #durations_min = None, 5368 #durations_max = None, 5369 ) 5370 5371 for id_person, id_activity_from, ids_activity_to in zip(ids_person, ids_activity_from, ids_activity_to): 5372 virtualpop.activitypatterns[id_person] = [id_activity_from, ids_activity_to, ] 5373 5374 return True 5375 5376 def get_ids_mode(self): 5377 modesplitconfigs = self.get_attrsman().get_group('modal split') 5378 ids_mode = np.zeros(len(modesplitconfigs), dtype=np.int32) 5379 i = 0 5380 for modeconfig in modesplitconfigs: 5381 ids_mode[i] = modeconfig.id_mode 5382 i += 1 5383 return ids_mode 5384 5385 def get_modes_random(self, n): 5386 """ 5387 Return a vector with mode IDs of length n. 5388 """ 5389 # print 'get_modes_random',n 5390 modesplitconfigs = self.get_attrsman().get_group('modal split') 5391 ids_mode = np.zeros(len(modesplitconfigs), dtype=np.int32) 5392 shares = np.zeros(len(modesplitconfigs), dtype=np.float32) 5393 i = 0 5394 for modeconfig in modesplitconfigs: 5395 ids_mode[i] = modeconfig.id_mode 5396 shares[i] = modeconfig.get_value() 5397 i += 1 5398 # print ' ids_mode',ids_mode 5399 # print ' shares',shares 5400 return ids_mode[random_choice(n, shares/np.sum(shares))] 5401 5402 def get_ttb(self, ids_pers): 5403 n_pers = len(ids_pers) 5404 5405 # Truncated Normal dist with scipy 5406 # load libraries 5407 #import scipy.stats as stats 5408 # lower, upper, mu, and sigma are four parameters 5409 #lower, upper = 0.5, 1 5410 #mu, sigma = 0.6, 0.1 5411 # instantiate an object X using the above four parameters, 5412 #X = stats.truncnorm((lower - mu) / sigma, (upper - mu) / sigma, loc=mu, scale=sigma) 5413 # generate 1000 sample data 5414 #samples = X.rvs(1000) 5415 5416 return np.random.normal(self.ttb_mean, self.ttb_dev, n_pers).clip(0, 2*3600) 5417 5418 5419class PopFromOdfGenerator(Process): 5420 def __init__(self, ident, virtualpop, logger=None, **kwargs): 5421 print 'PopFromOdfGenerator.__init__' 5422 5423 # TODO: let this be independent, link to it or child?? 5424 5425 self._init_common(ident, 5426 parent=virtualpop, 5427 name='Pop from OD-flow generator', 5428 logger=logger, 5429 info='Create virtual population from origin-to-destination zone flows by disaggregation.', 5430 ) 5431 5432 attrsman = self.set_attrsman(cm.Attrsman(self)) 5433 5434 # make for each possible pattern a field for prob 5435 activitytypes = self.parent.get_scenario().demand.activitytypes 5436 5437 self.hour_offset = attrsman.add(cm.AttrConf('hour_offset', kwargs.get('hour_offset', 8.0), 5438 groupnames=['options'], 5439 perm='rw', 5440 name='Offset hours', 5441 unit='h', 5442 info='Hour when simulation starts. This is the hour (of the day) when simulation time shows zero seconds.', 5443 )) 5444 5445 self.hour_tripbudget = attrsman.add(cm.AttrConf('hour_tripbudget', kwargs.get('hour_tripbudget', 0.5), 5446 groupnames=['options'], 5447 perm='rw', 5448 name='Triptime budget', 5449 unit='h', 5450 info="""Time budget for this trip. This time is used 5451 to initially estimate the time in hours between 5452 the activity at origin and the activity 5453 at destination. 5454 """, 5455 )) 5456 5457 self.scale = attrsman.add(cm.AttrConf('scale', kwargs.get('scale', 1.0), 5458 groupnames=['options'], 5459 perm='rw', 5460 name='Scale', 5461 info='Global scale factor. Scales the number of all OD trips.', 5462 )) 5463 5464 self.is_use_landusetypes = attrsman.add(cm.AttrConf('is_use_landusetypes', kwargs.get('is_use_landusetypes', False), 5465 groupnames=['options'], 5466 perm='rw', 5467 name='use landuse types', 5468 info="""If True, use the landuse type of 5469 facilities when assigning the origin and destination facility. 5470 The landuse type is selected according to the activity type. 5471 Use this option only if landuse types have been correctly defined for 5472 all facilities. 5473 """, 5474 )) 5475 5476 self.is_update_landuse = attrsman.add(cm.AttrConf('is_update_landuse', kwargs.get('is_update_landuse', True), 5477 groupnames=['options'], 5478 perm='rw', 5479 name='update Landuse', 5480 info="""If True, update land use database (zones, facilities, parking) before generating the population. Updating means identifying edges and facilities within zones. 5481 """, 5482 )) 5483 5484 def do(self): 5485 print 'PopFromOdfGenerator.do' 5486 # links 5487 5488 virtualpop = self.parent 5489 logger = self.get_logger() 5490 if self.is_update_landuse: 5491 logger.w('Update Landuse...') 5492 scenario = virtualpop.get_scenario() 5493 scenario.landuse.zones.refresh_zoneedges() 5494 scenario.landuse.facilities.identify_taz() 5495 scenario.landuse.facilities.identify_closest_edge() 5496 scenario.landuse.facilities.update() 5497 5498 logger.w('Create population...') 5499 virtualpop.create_pop_from_odflows(logger=logger, **self.get_kwoptions()) 5500 #activitytypes = virtualpop.activitytypes 5501 return True 5502 5503 5504class Planner(Process): 5505 def __init__(self, ident='planner', virtualpop=None, strategy='all', logger=None, **kwargs): 5506 print 'Planner.__init__' 5507 5508 # TODO: let this be independent, link to it or child?? 5509 5510 self._init_common(ident, 5511 parent=virtualpop, 5512 name='Planner', 5513 logger=logger, 5514 info='Generates mobility plan for population for a specific mobility strategy. Plans are only generated for persons for whome the strategy is applicable.', 5515 ) 5516 5517 attrsman = self.set_attrsman(cm.Attrsman(self)) 5518 5519 # make for each possible pattern a field for prob 5520 strategies = virtualpop.get_strategies() 5521 strategychoices = {'all': -1} 5522 strategychoices.update(strategies.names.get_indexmap()) 5523 self.id_strategy = attrsman.add(cm.AttrConf('id_strategy', strategychoices[strategy], 5524 groupnames=['options'], 5525 choices=strategychoices, 5526 perm='rw', 5527 name='Strategy', 5528 info='Strategy to be used to create mobility plane. In case of all strategies, the planner generates all applicable plans.', 5529 )) 5530 5531 evalcrits = {'apply to all persons if feasible': 0, 5532 'apply only if preferred mode is used': 1, 5533 'apply only if exclusively preferred mode is used': 2, 5534 } 5535 self.evalcrit = attrsman.add(cm.AttrConf('evalcrit', kwargs.get('evalcrit', evalcrits['apply to all persons if feasible']), 5536 groupnames=['options'], 5537 choices=evalcrits, 5538 perm='rw', 5539 name='Application criteria', 5540 info=""" Value that determines for which persons the plans will be generated. 5541 Apply to all persons if feasible:0 5542 Apply only if preferred mode is used:1 5543 Apply only if exclusively preferred mode is used:2 5544 """, 5545 )) 5546 5547 def do(self): 5548 print 'Planner.do' 5549 # links 5550 5551 virtualpop = self.parent 5552 logger = self.get_logger() 5553 #logger.w('Check applicability') 5554 #strategies = virtualpop.strategies.get_value() 5555 5556 if self.id_strategy != -1: 5557 virtualpop.plan_with_strategy(self.id_strategy, evalcrit=self.evalcrit, logger=logger) 5558 5559 else: # plan with all strategies 5560 for id_strategy in virtualpop.get_strategies().get_ids(): 5561 virtualpop.plan_with_strategy(id_strategy, evalcrit=self.evalcrit, logger=logger) 5562 5563 return True 5564 5565 5566class PlanSelector(Process): 5567 def __init__(self, ident='planselector', virtualpop=None, logger=None, **kwargs): 5568 print 'PlanSelector.__init__' 5569 5570 # TODO: let this be independent, link to it or child?? 5571 5572 self._init_common(ident, 5573 parent=virtualpop, 5574 name='Plan Selector', 5575 logger=logger, 5576 info='Selects the plan for each person which will be executed during the next simulation run according to a defined selection method.', 5577 ) 5578 5579 attrsman = self.set_attrsman(cm.Attrsman(self)) 5580 5581 # make for each possible pattern a field for prob 5582 strategies = virtualpop.get_strategies() 5583 # strategychoices.update(strategies.names.get_indexmap()) 5584 5585 methods = {'plan with shortest estim. time': virtualpop.select_plans_min_time_est, 5586 'plan with shortest exec. time': virtualpop.select_plans_min_time_exec, 5587 'plan with preferred mode': virtualpop.select_plans_preferred_mode, 5588 'next plan in list': virtualpop.select_plans_next, 5589 'random plan': virtualpop.select_plans_random, 5590 'plan with shortest exec. time or est. time': virtualpop.select_plans_min_time_exec_est 5591 } 5592 5593 self.method = attrsman.add(cm.AttrConf('method', methods[kwargs.get('methodname', 'plan with shortest estim. time')], 5594 groupnames=['options'], 5595 choices=methods, 5596 perm='rw', 5597 name='Selection method', 5598 info='Selection method used to select current plans.', 5599 )) 5600 5601 self.fraction = attrsman.add(cm.AttrConf('fraction', kwargs.get('fraction', 1.0), 5602 groupnames=['options'], 5603 perm='rw', 5604 name='Change fraction', 5605 info="""Fraction of persons that are randomly chosen to change plans according to the defined method. 5606 A value of 1.0 mens that the plans of oll persons will be changed.""", 5607 )) 5608 5609 self.timedev = attrsman.add(cm.AttrConf('timedev', kwargs.get('timedev', 0.0), 5610 groupnames=['options'], 5611 perm='rw', 5612 name='Time deviation', 5613 info='Time deviation of random time component of estimated or effective time. If zero, no random time is added.', 5614 )) 5615 5616 self.c_probit = attrsman.add(cm.AttrConf('c_probit', kwargs.get('c_probit', 0.0), 5617 groupnames=['options'], 5618 perm='rw', 5619 name='Probit const', 5620 info="""Probit constant used to determine the deviation of the normal distributed random time component. 5621 The deviation is the product of this constant and the travel time. If zero, no random time is added.""", 5622 )) 5623 5624 def do(self): 5625 print 'Planner.do' 5626 # links 5627 5628 #virtualpop = self.parent 5629 logger = self.get_logger() 5630 #logger.w('Check applicability') 5631 return self.method(logger=logger, **self.get_kwoptions()) 5632 5633 5634class VehicleProvider(Process): 5635 def __init__(self, ident='vehicleprovider', virtualpop=None, logger=None, **kwargs): 5636 print 'VehicleProvider.__init__' 5637 5638 # TODO: let this be independent, link to it or child?? 5639 5640 self._init_common(ident, 5641 parent=virtualpop, 5642 name='Vehicle Provider', 5643 logger=logger, 5644 info='Provides individual vehicles to persons according to preferred mode and giveb statistical data.', 5645 ) 5646 5647 attrsman = self.set_attrsman(cm.Attrsman(self)) 5648 5649 # make for each possible pattern a field for prob 5650 5651 self.share_autoowner = attrsman.add(cm.AttrConf('share_autoowner', kwargs.get('share_autoowner', 0.8), 5652 groupnames=['options'], 5653 perm='rw', 5654 name='Car auto share', 5655 info="""Share of auto owners. This specifies the share of auto owners and a car will be created for each car owner. 5656 Attention if prefeered mode has been already defined: persons who have bicicle as preferred mode get automatically a bike assigned. 5657 """, 5658 )) 5659 5660 self.share_motorcycleowner = attrsman.add(cm.AttrConf('share_motorcycleowner', kwargs.get('share_motorcycleowner', 0.3), 5661 groupnames=['options'], 5662 perm='rw', 5663 name='Motorcycle owner share', 5664 info="""Share of Motorcycle owners. This specifies the share of Motorcycle owners and a bike will be created for each Motorcycle owner. 5665 Attention if prefeered mode has been already defined: persons who have Motorcycle as preferred mode get automatically a Motorcycle assigned. 5666 """, 5667 )) 5668 5669 self.share_bikeowner = attrsman.add(cm.AttrConf('share_bikeowner', kwargs.get('share_bikeowner', 0.5), 5670 groupnames=['options'], 5671 perm='rw', 5672 name='Bike owner share', 5673 info="""Share of bike owners. This specifies the share of bike owners and a bike will be created for each bike owner. 5674 Attention if prefeered mode has been already defined: persons who have bicicle as preferred mode get automatically a bike assigned. 5675 """, 5676 )) 5677 5678 def do(self): 5679 print 'VehicleProvider.do' 5680 # links 5681 5682 virtualpop = self.parent 5683 logger = self.get_logger() 5684 logger.w('Provide vehicles...') 5685 5686 ids_person = virtualpop.get_ids() 5687 n_person = len(ids_person) 5688 modes = virtualpop.get_scenario().net.modes 5689 id_mode_bike = modes.get_id_mode('bicycle') 5690 id_mode_auto = modes.get_id_mode('passenger') 5691 id_mode_moto = modes.get_id_mode('motorcycle') 5692 5693 iautos = virtualpop.get_iautos() 5694 ibikes = virtualpop.get_ibikes() 5695 imotos = virtualpop.get_imotos() 5696 5697 logger.w('generate individual vehicles for prefered modes') 5698 ids_prefer_auto = virtualpop.select_ids( 5699 (virtualpop.ids_mode_preferred.get_value() == id_mode_auto) & (virtualpop.ids_iauto.get_value() == -1)) 5700 ids_iauto = iautos.assign_to_persons(ids_prefer_auto) 5701 5702 n_current = iautos.get_share(is_abs=True) 5703 #n_none = int(self.share_autoowner*n_person)-(n_person-n_current) 5704 n_need = int(self.share_autoowner*n_person)-n_current 5705 if n_need > 0: 5706 ids_pers_miss = np.flatnonzero(virtualpop.ids_iauto.get_value() == -1) 5707 # print ' n_person,n_current,n_target,n_need,len(ids_pers_miss)',n_person,n_current,int(self.share_autoowner*n_person),n_need,len(ids_pers_miss) 5708 ids_pers_assign = np.random.choice(ids_pers_miss, n_need, replace=False) 5709 ids_iauto = iautos.assign_to_persons(ids_pers_assign) 5710 5711 print ' created %d autos, target share=%.2f, share = %.2f' % ( 5712 iautos.get_share(is_abs=True), iautos.get_share(), self.share_autoowner) 5713 5714 ids_prefer_bike = virtualpop.select_ids( 5715 (virtualpop.ids_mode_preferred.get_value() == id_mode_bike) & (virtualpop.ids_ibike.get_value() == -1)) 5716 ids_ibikes = ibikes.assign_to_persons(ids_prefer_bike) 5717 5718 n_current = ibikes.get_share(is_abs=True) 5719 n_need = int(self.share_bikeowner*n_person)-n_current 5720 if n_need > 0: 5721 ids_pers_miss = np.flatnonzero(virtualpop.ids_ibike.get_value() == -1) 5722 # print ' n_person,n_current,n_target,n_need,len(ids_pers_miss)',n_person,n_current,int(self.share_autoowner*n_person),n_need,len(ids_pers_miss) 5723 ids_pers_assign = np.random.choice(ids_pers_miss, n_need, replace=False) 5724 ids_ibike = ibikes.assign_to_persons(ids_pers_assign) 5725 5726 print ' created %d bikes, target share=%.2f, share = %.2f' % ( 5727 ibikes.get_share(is_abs=True), ibikes.get_share(), self.share_bikeowner) 5728 5729 ids_prefer_moto = virtualpop.select_ids( 5730 (virtualpop.ids_mode_preferred.get_value() == id_mode_moto) & (virtualpop.ids_imoto.get_value() == -1)) 5731 ids_imoto = imotos.assign_to_persons(ids_prefer_moto) 5732 5733 n_current = imotos.get_share(is_abs=True) 5734 n_need = int(self.share_motorcycleowner*n_person)-n_current 5735 if n_need > 0: 5736 ids_pers_miss = np.flatnonzero(virtualpop.ids_imoto.get_value() == -1) 5737 ids_pers_assign = np.random.choice(ids_pers_miss, n_need, replace=False) 5738 ids_imoto = imotos.assign_to_persons(ids_pers_assign) 5739 5740 print ' created %d moto, target share=%.2f, share = %.2f' % ( 5741 imotos.get_share(is_abs=True), imotos.get_share(), self.share_motorcycleowner) 5742 return True 5743 5744 # TODO: generate and assign additional vehicles 5745 # to satisfy prescribes ownership 5746