-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtcw_mtx.py
174 lines (151 loc) · 6.81 KB
/
tcw_mtx.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# -------------------------------------------------------------------------------
# Name: Importing TransCad Matrices into Python (Numpy/Scipy) arrays
# Purpose:
#
# Author: Pedro Camargo
#
# Created: 15/05/2014
# Copyright: (c) pcamargo 2016
# Licence: See LICENSE.TXT
# -------------------------------------------------------------------------------
import numpy as np
from ctypes import *
import ctypes
class TCWMtx:
def __init__(self):
self.data = None
self.rows = -1
self.columns = -1
self.type = -1
self.cores = -1
self.matrix = {}
self.RIndex = -1 #Dictionary with all indices for the rows
self.CIndex = -1 #Dictionary with all indices for the columns
self.datafile = 'No file loaded yet'
self.RHash = False
self.CHash = False
# self.RIndex= {} #Dictionary with all indices for the rows
# self.CIndex= {} #Dictionary with all indices for the columns
self.indexcount = -1 #Tuple with the number of indices for each dimension
def info(self):
print 'Number of matrix Cores: ', self.cores
print 'Matrix Cores: ', self.matrix.keys()
print 'Number of rows: ', self.rows
print 'Number of columns: ', self.columns
print 'Number of indices for rows: ', self.indexcount[0]
print 'Number of indices for columns: ', self.indexcount[1]
def load(self, filename, justcores=None, verbose=False, null_is_zero=True):
# We load the DLL and initiate it
tcw = cdll.LoadLibrary('C:\\Program Files\\TransCAD 6.0\\CaliperMtx.dll')
initdll = ctypes.c_short(0)
idll = ctypes.pointer(initdll)
tcw.InitMatDLL(idll)
mat = tcw.MATRIX_LoadFromFile(filename, True)
self.rows = tcw.MATRIX_GetBaseNRows(mat)
self.columns = tcw.MATRIX_GetBaseNCols(mat)
self.type = tcw.MATRIX_GetDataType(mat)
self.indexcount = (tcw.MATRIX_GetNIndices(mat, 0), tcw.MATRIX_GetNIndices(mat, 1))
self.cores = tcw.MATRIX_GetNCores(mat)
self.datafile = filename
v = (self.rows * c_long)()
tcw.MATRIX_GetIDs(mat, 0, v)
self.RIndex = np.zeros(self.rows, np.int64)
self.RIndex[:] = v[:]
i = np.max(self.RIndex) + 1
self.RHash = np.zeros(i, np.int64)
self.RHash[self.RIndex] = np.arange(self.rows)
v = (self.columns * c_long)()
tcw.MATRIX_GetIDs(mat, 1, v)
self.CIndex = np.zeros(self.columns, np.int64)
self.CIndex[:] = v[:]
i = np.max(self.CIndex) + 1
self.CHash = np.zeros(i, np.int64)
self.CHash[self.CIndex] = np.arange(self.columns)
# #Reads all the indices for rows and put them in the dictionary
# for i in range(self.indexcount[0]):
# tcw.MATRIX_SetIndex(mat, 0, i)
# v = (tcw.MATRIX_GetNRows(mat) * c_long)()
# tcw.MATRIX_GetIDs(mat, 0, v)
# t = np.zeros(tcw.MATRIX_GetNRows(mat), np.int64)
# t[:] = v[:]
# self.RIndex[i] = t.copy()
#
# #Do the same for columns
# for i in range(self.indexcount[1]):
# f = tcw.MATRIX_SetIndex(mat, 1, i)
# v = (tcw.MATRIX_GetNCols(mat) * c_long)()
# tcw.MATRIX_GetIDs(mat, 1, v)
# t = np.zeros(tcw.MATRIX_GetNCols(mat), np.int64)
# t[:] = v[:]
# self.CIndex[i] = t.copy()
if justcores is not None:
if not isinstance(justcores, list):
justcores = [justcores]
else:
justcores = []
for i in range(self.cores):
tcw.MATRIX_SetCore(mat, i)
nameC = ctypes.create_string_buffer(50)
tcw.MATRIX_GetLabel(mat, i, nameC)
nameC = repr(nameC.value)
nameC = nameC[1:len(nameC) - 1]
justcores.append(nameC)
if verbose:
print "Matrix has ", self.cores, " cores. Loading " + str(len(justcores)) + " core(s)"
for C in justcores:
for k in range(self.cores):
tcw.MATRIX_SetCore(mat, k)
nameC = ctypes.create_string_buffer(50)
tcw.MATRIX_GetLabel(mat, k, nameC)
nameC = repr(nameC.value)
nameC = nameC[1:len(nameC) - 1]
if C == nameC:
if verbose:
print " Loading core: ", nameC # If verbose, we list the matrices being loaded
# Define the data type Numpy will have according to the data type of the matrix in question
dt = np.float64
v = (self.columns * c_double)()
if self.type == 1:
dt = np.int16
v = (self.columns * c_long)()
if self.type == 2:
dt = np.int64
v = (self.columns * c_longlong)()
if self.type == 3:
dt = np.float64
v = (self.columns * c_float)()
# Instantiate the matrix
self.matrix[nameC] = np.zeros((self.rows, self.columns), dtype=dt)
replace_by = np.NaN
if null_is_zero:
replace_by = 0
# Read matrix and puts in the numpy array
for i in range(self.rows):
# tcw.MATRIX_GetBaseVector.restype = None
tcw.MATRIX_GetBaseVector(mat, i, 0, self.type, v)
self.matrix[nameC][i, :] = v[:]
if self.type == 4:
self.matrix[nameC][self.matrix[nameC] <= -1.79769e+308] = replace_by
if self.type == 3:
self.matrix[nameC][self.matrix[nameC] <= -3.40282e+38] = replace_by
if self.type == 2:
self.matrix[nameC][self.matrix[nameC] <= -2147483647] = replace_by
if self.type == 1:
self.matrix[nameC][self.matrix[nameC] <= -32767] = replace_by
# raise NameError('Not possible to open file. TranCad returned '+ str(tc_value))
tcw.MATRIX_CloseFile(mat)
tcw.MATRIX_Done(mat)
def export(self, core, name, all_cells=False):
m = self.matrix[core]
O = open(name, 'w')
print >> O, 'O,D,VALUE'
for i, k in enumerate(self.RIndex):
for j, l in enumerate(self.CIndex):
if m[i, j] > 0 or all_cells:
print >> O, k, ',', l, ',', m[i, j]
O.flush()
O.close()
def value(self, core, i, j):
return self.matrix[core][self.RHash[i], self.CHash[j]]
def changevalue(self, core, i, j, new_value):
self.matrix[core][self.RHash[i], self.CHash[j]] = new_value