def __setSavePathFile(self, save=False, path_result=None): # Fields: Origin, Node, Predecessor # Number of records: Origins * Nodes a = AequilibraeData() d1 = max(1, self.zones) d2 = 1 memory_mode = True if save: if path_result is None: warnings.warn( "Path file not set properly. Need to specify output file too" ) else: # This is the only place where we keep 32bits, as going 64 bits would explode the file size if self.nodes > 0 and self.zones > 0: d1 = self.zones d2 = self.nodes memory_mode = False a.create_empty( file_path=path_result, entries=d1 * d2, field_names=["origin", "node", "predecessor", "connector"], data_types=[np.uint32, np.uint32, np.uint32, np.uint32], memory_mode=memory_mode, ) self.path_file = {"save": save, "results": a}
def test___init__(self): # Generates the dataset dataset = AequilibraeData() dataset.create_empty(**args) dataset.index[:] = np.arange(dataset.entries) + 100 dataset.d[:] = dataset.index[:]**2 if dataset.index[70] != 170: self.fail() if int(dataset.d[70]) != 28900: self.fail() # removes the dataset del dataset
def get_load_results(self) -> AequilibraeData: """ Translates the assignment results from the graph format into the network format Returns: dataset (:obj:`AequilibraeData`): AequilibraE data with the traffic class assignment results """ fields = ['link_id'] for n in self.classes['names']: fields.extend([f'{n}_ab', f'{n}_ba', f'{n}_tot']) types = [np.float64] * len(fields) entries = int(np.unique(self.lids).shape[0]) res = AequilibraeData() res.create_empty(memory_mode=True, entries=entries, field_names=fields, data_types=types) res.data.fill(np.nan) res.index[:] = np.unique(self.lids)[:] res.link_id[:] = res.index[:] indexing = np.zeros(int(self.lids.max()) + 1, np.uint64) indexing[res.index[:]] = np.arange(entries) # Indices of links BA and AB ABs = self.direcs > 0 BAs = self.direcs < 0 ab_ids = indexing[self.lids[ABs]] ba_ids = indexing[self.lids[BAs]] # Link flows link_flows = self.link_loads[:, :] for i, n in enumerate(self.classes["names"]): # AB Flows res.data[n + "_ab"][ab_ids] = np.nan_to_num(link_flows[ABs, i]) # BA Flows res.data[n + "_ba"][ba_ids] = np.nan_to_num(link_flows[BAs, i]) # Tot Flow res.data[n + "_tot"] = np.nan_to_num( res.data[n + "_ab"]) + np.nan_to_num(res.data[n + "_ba"]) return res
def results(self) -> pd.DataFrame: """Prepares the assignment results as a Pandas DataFrame Returns: *DataFrame* (:obj:`pd.DataFrame`): Pandas dataframe with all the assignment results indexed on link_id """ idx = self.classes[0].graph.graph.__supernet_id__ assig_results = [cls.results.get_load_results() for cls in self.classes] class1 = self.classes[0] res1 = assig_results[0] tot_flow = self.assignment.fw_total_flow[idx] voc = tot_flow / self.capacity[idx] congested_time = self.congested_time[idx] free_flow_tt = self.free_flow_tt[idx] entries = res1.data.shape[0] fields = [ "Congested_Time_AB", "Congested_Time_BA", "Congested_Time_Max", "Delay_factor_AB", "Delay_factor_BA", "Delay_factor_Max", "VOC_AB", "VOC_BA", "VOC_max", "PCE_AB", "PCE_BA", "PCE_tot", ] types = [np.float64] * len(fields) agg = AequilibraeData() agg.create_empty(memory_mode=True, entries=entries, field_names=fields, data_types=types) agg.data.fill(np.nan) agg.index[:] = res1.data.index[:] link_ids = class1.results.lids ABs = class1.results.direcs > 0 BAs = class1.results.direcs < 0 indexing = np.zeros(int(link_ids.max()) + 1, np.uint64) indexing[agg.index[:]] = np.arange(entries) # Indices of links BA and AB ab_ids = indexing[link_ids[ABs]] ba_ids = indexing[link_ids[BAs]] agg.data["Congested_Time_AB"][ab_ids] = np.nan_to_num(congested_time[ABs]) agg.data["Congested_Time_BA"][ba_ids] = np.nan_to_num(congested_time[BAs]) agg.data["Congested_Time_Max"][:] = np.nanmax([agg.data.Congested_Time_AB, agg.data.Congested_Time_BA], axis=0) agg.data["Delay_factor_AB"][ab_ids] = np.nan_to_num(congested_time[ABs] / free_flow_tt[ABs]) agg.data["Delay_factor_BA"][ba_ids] = np.nan_to_num(congested_time[BAs] / free_flow_tt[BAs]) agg.data["Delay_factor_Max"][:] = np.nanmax([agg.data.Delay_factor_AB, agg.data.Delay_factor_BA], axis=0) agg.data["VOC_AB"][ab_ids] = np.nan_to_num(voc[ABs]) agg.data["VOC_BA"][ba_ids] = np.nan_to_num(voc[BAs]) agg.data["VOC_max"][:] = np.nanmax([agg.data.VOC_AB, agg.data.VOC_BA], axis=0) agg.data["PCE_AB"][ab_ids] = np.nan_to_num(tot_flow[ABs]) agg.data["PCE_BA"][ba_ids] = np.nan_to_num(tot_flow[BAs]) agg.data["PCE_tot"][:] = np.nansum([agg.data.PCE_AB, agg.data.PCE_BA], axis=0) assig_results.append(agg) dfs = [pd.DataFrame(aed.data) for aed in assig_results] dfs = [df.rename(columns={"index": "link_id"}).set_index("link_id") for df in dfs] df = pd.concat(dfs, axis=1) return df
from unittest import TestCase from aequilibrae.matrix import AequilibraeData, AequilibraeMatrix from aequilibrae.distribution import SyntheticGravityModel, GravityApplication import numpy as np import tempfile import os zones = 10 # row vector args = {"entries": zones, "field_names": [u"rows"], "data_types": [np.float64], "memory_mode": True} row_vector = AequilibraeData() row_vector.create_empty(**args) row_vector.index[:] = np.arange(row_vector.entries) + 100 row_vector.rows[:] = row_vector.index[:] + np.random.rand(zones)[:] # column vector args["field_names"] = ["columns"] column_vector = AequilibraeData() column_vector.create_empty(**args) column_vector.index[:] = np.arange(column_vector.entries) + 100 column_vector.columns[:] = column_vector.index[:] + np.random.rand(zones)[:] # balance vectors column_vector.columns[:] = column_vector.columns[:] * (row_vector.rows.sum() / column_vector.columns.sum()) # Impedance matrix_procedures name_test = os.path.join(tempfile.gettempdir(), "aequilibrae_matrix_test.aem") args = {"file_name": name_test, "zones": zones, "matrix_names": ["impedance"]}
# %% # We compute the vectors from our matrix origins = np.sum(demand.matrix_view, axis=1) destinations = np.sum(demand.matrix_view, axis=0) args = { "file_path": join(fldr, "synthetic_future_vector.aed"), "entries": demand.zones, "field_names": ["origins", "destinations"], "data_types": [np.float64, np.float64], "memory_mode": False, } vectors = AequilibraeData() vectors.create_empty(**args) vectors.index[:] = demand.index[:] # Then grow them with some random growth between 0 and 10% - Plus balance them vectors.origins[:] = origins * (1 + np.random.rand(vectors.entries) / 10) vectors.destinations[:] = destinations * (1 + np.random.rand(vectors.entries) / 10) vectors.destinations *= vectors.origins.sum() / vectors.destinations.sum() # %% # Impedance imped = proj_matrices.get_matrix("base_year_assignment_skims") imped.computational_view(["final_time_with_intrazonals"])
class LoadDataset(WorkerThread): def __init__(self, parent_thread, layer, index_field, fields, file_name): WorkerThread.__init__(self, parent_thread) self.layer = layer self.index_field = index_field self.fields = fields self.error = None self.python_version = 8 * struct.calcsize("P") self.output = AequilibraeData() self.output_name = file_name def doWork(self): feat_count = self.layer.featureCount() self.ProgressMaxValue.emit(feat_count) # Create specification for the output file datafile_spec = {"entries": feat_count} if self.output_name is None: datafile_spec["memory_mode"] = True else: datafile_spec["memory_mode"] = False fields = [] types = [] idxs = [] empties = [] for field in self.layer.dataProvider().fields().toList(): if field.name() in self.fields: if field.type() in integer_types: types.append("<i8") empties.append(np.iinfo(np.int64).min) elif field.type() in float_types: types.append("<f8") empties.append(np.nan) elif field.type() in string_types: types.append("S" + str(field.length())) empties.append("") else: self.error = "Field {} does has a type not supported.".format( str(field.name())) break fields.append(str(field.name())) idxs.append(self.layer.dataProvider().fieldNameIndex( field.name())) index_idx = self.layer.dataProvider().fieldNameIndex(self.index_field) datafile_spec["field_names"] = fields datafile_spec["data_types"] = types datafile_spec["file_path"] = self.output_name if self.error is None: self.output.create_empty(**datafile_spec) # Get all the data for p, feat in enumerate(self.layer.getFeatures()): for idx, field, empty in zip(idxs, fields, empties): if feat.attributes()[idx] == QVariant(): self.output.data[field][p] = empty else: self.output.data[field][p] = feat.attributes()[idx] self.output.index[p] = feat.attributes()[index_idx] self.ProgressValue.emit(p) self.ProgressValue.emit(feat_count) self.finished_threaded_procedure.emit("Done")
def test_fit(self): proj = Project() proj.open(self.proj_dir) mats = proj.matrices mats.update_database() seed = mats.get_matrix('SiouxFalls_omx') seed.computational_view('matrix') # row vector args = { "entries": seed.zones, "field_names": ["rows"], "data_types": [np.float64], "memory_mode": True } row_vector = AequilibraeData() row_vector.create_empty(**args) row_vector.rows[:] = np.random.rand(seed.zones)[:] * 1000 row_vector.index[:] = seed.index[:] # column vector args["field_names"] = ["columns"] column_vector = AequilibraeData() column_vector.create_empty(**args) column_vector.columns[:] = np.random.rand(seed.zones)[:] * 1000 column_vector.index[:] = seed.index[:] # balance vectors column_vector.columns[:] = column_vector.columns[:] * ( row_vector.rows.sum() / column_vector.columns.sum()) # The IPF per se args = { "matrix": seed, "rows": row_vector, "row_field": "rows", "columns": column_vector, "column_field": "columns", "nan_as_zero": False, } with self.assertRaises(TypeError): fratar = Ipf(data='test', test='data') fratar.fit() with self.assertRaises(ValueError): fratar = Ipf(**args) fratar.parameters = ['test'] fratar.fit() fratar = Ipf(**args) fratar.fit() result = fratar.output self.assertAlmostEqual(np.nansum(result.matrix_view), np.nansum(row_vector.data["rows"]), 4, "Ipf did not converge") self.assertGreater(fratar.parameters["convergence level"], fratar.gap, "Ipf did not converge") mr = fratar.save_to_project('my_matrix_ipf', 'my_matrix_ipf.aem') self.assertTrue( os.path.isfile(os.path.join(mats.fldr, 'my_matrix_ipf.aem')), 'Did not save file to the appropriate place') self.assertEqual(mr.procedure_id, fratar.procedure_id, 'procedure ID saved wrong') proj.close()