forked from ZedThree/pyxpad
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatafile.py
More file actions
172 lines (148 loc) · 4.89 KB
/
Copy pathdatafile.py
File metadata and controls
172 lines (148 loc) · 4.89 KB
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
# A wrapper around various NetCDF libraries,
#
# Supported libraries:
# -------------------
#
# netCDF4
#
# Scientific.IO.NetCDF
#
# scipy.io.netcdf
# old version (create_dimension, create_variable)
# new version (createDimension, createVariable)
#
try:
import numpy as np
except ImportError:
print("ERROR: NumPy module not available")
raise
library = None # Record which library to use
try:
from netCDF4 import Dataset
library = "netCDF4"
except ImportError:
#print("netcdf4-python module not found")
try:
from Scientific.IO.NetCDF import NetCDFFile as Dataset
from Scientific.N import Int, Float
library = "Scientific"
#print(" => Using Scientific.IO.NetCDF instead")
except ImportError:
try:
from scipy.io.netcdf import netcdf_file as Dataset
library = "scipy"
#print("Using scipy.io.netcdf library")
except:
print("No supported NetCDF modules available")
raise
import time
from pyxpad_utils import XPadDataItem, XPadDataDim
class NetCDFDataSource:
"""
Functions
read( name , shot) Input variable name (string)
Output is an XPadDataItem object or None
size( name ) Returns variable size as a list. [] for scalar
Attributes
label A short string to describe the source
dimensions A dictionary of XPadDataDim objects
varNames A list of variable names
variables A dictionary of XPadDataItem objects with empty data
"""
handle = None
def open(self, fname=None):
if fname is None:
fname = self.filename
self.handle = Dataset(fname, "r")
def close(self):
if self.handle is not None:
self.handle.close()
self.handle = None
def __init__(self, filename):
self.filename = filename
self.label = filename # May need to shorten
self.open(filename)
self.dimensions = self.getDimensions() # A dictionary of XPadDataDim objects
self.varNames = self.handle.variables.keys() # A list of variable names
for i, v in enumerate(self.varNames):
try:
# Python 2
if isinstance(v, unicode):
v = v.encode('utf-8')
v = str(v).translate(None, '\0')
except NameError:
# Python 3
if isinstance(v, str):
v = v.encode('utf-8')
self.varNames[i] = v
self.variables = {} # A dictionary of XPadDataItem objects with empty data
for name, var in self.handle.variables.items():
item = XPadDataItem()
item.name = name
item.source = self.filename
item.dim = map(lambda d: self.dimensions[d], var.dimensions)
self.variables[name] = item
self.close()
def __del__(self):
self.close()
def read(self, name, shot):
"""Read a variable from the file."""
self.open()
if self.handle is None:
return None
try:
var = self.handle.variables[name]
except KeyError:
# Not found. Try to find using case-insensitive search
var = None
for n in self.handle.variables.keys():
if n.lower() == name.lower():
print("WARNING: Reading '"+n+"' instead of '"+name+"'")
var = self.handle.variables[n]
if var is None:
return None
ndims = len(var.dimensions)
if ndims == 0:
data = var.getValue()
else:
data = var[:]
item = XPadDataItem()
item.name = name
item.source = self.filename
item.data = data
item.dim = map(lambda d: self.dimensions[d], var.dimensions)
self.close()
return item
def getDimensions(self):
if self.handle is None:
return None
dims = {}
for name, dim in self.handle.dimensions.items():
t = type(dim).__name__
if t == 'int':
n = dim
else:
n = len(dim)
newdim = XPadDataDim()
newdim.name = name
newdim.label = name
newdim.data = np.arange(n)
dims[name] = newdim
return dims
def size(self, varname):
"""List of dimension sizes for a variable."""
if self.handle is None:
return []
try:
var = self.handle.variables[varname]
except KeyError:
return []
def dimlen(d):
dim = self.handle.dimensions[d]
if dim is not None:
t = type(dim).__name__
if t == 'int':
return dim
return len(dim)
return 0
return map(lambda d: dimlen(d), var.dimensions)