Skip to content

Commit e95a29f

Browse files
Dave DeMarlekwrobot
authored andcommitted
Merge topic 'cinema_specA_tweaks' into next
7194b6a if saving cinema don't save standard images too 9f99528 bring in cleaned up cinema IO library ba04856 make cinema respect users choice of image file format
2 parents 789a38f + 7194b6a commit e95a29f

File tree

4 files changed

+130
-82
lines changed

4 files changed

+130
-82
lines changed

Wrapping/Python/paraview/cinemaIO/cinema_store.py

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
"""
22
Module defining classes and methods for managing cinema data storage.
3-
4-
TODO:
5-
child stores (for workbench)
6-
cost data
7-
expand beyond parametric-image-stack type use case
83
"""
94

105
import sys
@@ -18,7 +13,8 @@ class Document(object):
1813
"""
1914
This refers to a document in the cinema data storage. A document is
2015
uniquely identified by a 'descriptor'. A descriptor is a dictionary with
21-
key-value pairs, where key is the component name and value is its value.
16+
key-value pairs, where key is a parameter name and value is the value for
17+
that particular parameter.
2218
2319
A document can have arbitrary meta-data (as 'attributes') and data (as
2420
'data') associated with it.
@@ -57,19 +53,21 @@ def data(self, val):
5753
self.__data = val
5854

5955
class Store(object):
60-
"""Base class for a cinema store. This class is an abstract class defining
61-
the API and storage independent logic. Storage specific subclasses handle
62-
the 'database' access.
56+
"""Base class for a cinema store. A store is a collection of Documents,
57+
with API to add, find, and access them.
58+
59+
This class is an abstract class defining the API and storage independent
60+
logic. Storage specific subclasses handle the 'database' access.
6361
6462
The design of cinema store is based on the following principles:
6563
66-
The store comprises of documents (Document instances). Each document has an
67-
unique descriptor associated with it. This can be thought of as the 'unique
68-
key' in database terminology.
64+
The store comprises of documents (Document instances). Each document has a
65+
unique set of parameters, aka a "descriptor" associated with it. This
66+
can be thought of as the 'unique key' in database terminology.
6967
70-
One can define the components for descriptors for documents in a Store on
71-
the store itself. This is referred to as 'descriptor_definition'. One can
72-
use 'add_descriptor()' calls to add new descriptor definitions for a new
68+
One defines the parameters (contents of the descriptor) for documents
69+
on the store itself. The set of them is is referred to as 'parameter_list'.
70+
One uses 'add_parameter()' calls to add new parameter definitions for a new
7371
store instance.
7472
7573
Users insert documents in the store using 'insert'. One can find
@@ -79,16 +77,16 @@ class Store(object):
7977

8078
def __init__(self):
8179
self.__metadata = None #better name is view hints
82-
self.__descriptor_definition = {}
80+
self.__parameter_list = {}
8381
self.__loaded = False
8482

8583
@property
86-
def descriptor_definition(self):
87-
return self.__descriptor_definition
84+
def parameter_list(self):
85+
return self.__parameter_list
8886

89-
def _set_descriptor_definition(self, val):
87+
def _set_parameter_list(self, val):
9088
"""For use by subclasses alone"""
91-
self.__descriptor_definition = val
89+
self.__parameter_list = val
9290

9391
@property
9492
def metadata(self):
@@ -103,33 +101,34 @@ def add_metadata(self, keyval):
103101
self.__metadata = {}
104102
self.__metadata.update(keyval)
105103

106-
def get_full_descriptor(self, desc):
107-
# FIXME: bad name!!!
104+
def get_complete_descriptor(self, partial_desc):
108105
full_desc = dict()
109-
for name, properties in self.descriptor_definition.items():
106+
for name, properties in self.parameter_list.items():
110107
if properties.has_key("default"):
111108
full_desc[name] = properties["default"]
112-
full_desc.update(desc)
109+
full_desc.update(partial_desc)
113110
return full_desc
114111

115-
def add_descriptor(self, name, properties):
116-
"""Add a descriptor.
112+
def add_parameter(self, name, properties):
113+
"""Add a parameter.
117114
118-
:param name: Name for the descriptor.
115+
:param name: Name for the parameter.
119116
120117
:param properties: Keyword arguments can be used to associate miscellaneous
121-
meta-data with this descriptor.
118+
meta-data with this parameter.
122119
"""
123120
#if self.__loaded:
124-
# raise RuntimeError("Updating descriptors after loading/creating a store is not supported.")
125-
properties = self.validate_descriptor(name, properties)
126-
self.__descriptor_definition[name] = properties
121+
# raise RuntimeError("Updating parameters after loading/creating a store is not supported.")
122+
# TODO: except when it is, in the important case of adding new time steps to a collection
123+
# probably can only add safely to outermost parameter (loop)
124+
properties = self.validate_parameter(name, properties)
125+
self.__parameter_list[name] = properties
127126

128-
def get_descriptor_properties(self, name):
129-
return self.__descriptor_definition[name]
127+
def get_parameter(self, name):
128+
return self.__parameter_list[name]
130129

131-
def validate_descriptor(self, name, properties):
132-
"""Validates a new descriptor and return updated descriptor properties.
130+
def validate_parameter(self, name, properties):
131+
"""Validates a new parameter and return updated parameter properties.
133132
Subclasses should override this as needed.
134133
"""
135134
return properties
@@ -150,6 +149,9 @@ def create(self):
150149
def find(self, q=None):
151150
raise RuntimeError("Subclasses must define this method")
152151

152+
def get_image_type(self):
153+
return None
154+
153155
class FileStore(Store):
154156
"""Implementation of a store based on files and directories"""
155157

@@ -164,14 +166,16 @@ def load(self):
164166
super(FileStore, self).load()
165167
with open(self.__dbfilename, mode="rb") as file:
166168
info_json = json.load(file)
167-
self._set_descriptor_definition(info_json['arguments'])
169+
#for legacy reasons, the parameters are called
170+
#arguments" in the files
171+
self._set_parameter_list(info_json['arguments'])
168172
self.metadata = info_json['metadata']
169173
self.__filename_pattern = info_json['name_pattern']
170174

171175
def save(self):
172176
""" writes out a modified file store """
173177
info_json = dict(
174-
arguments = self.descriptor_definition,
178+
arguments = self.parameter_list,
175179
name_pattern = self.filename_pattern,
176180
metadata = self.metadata
177181
)
@@ -188,12 +192,23 @@ def create(self):
188192

189193
@property
190194
def filename_pattern(self):
195+
"""
196+
Files corresponding to Documents are arranged on disk
197+
according the the directory and filename structure described
198+
by the filename_pattern. The format is a regular expression
199+
consisting of parameter names enclosed in '{' and '}' and
200+
separated by spacers. "/" spacer characters produce sub
201+
directories.
202+
"""
191203
return self.__filename_pattern
192204

193205
@filename_pattern.setter
194206
def filename_pattern(self, val):
195207
self.__filename_pattern = val
196208

209+
def get_image_type(self):
210+
return self.filename_pattern[self.filename_pattern.rfind("."):]
211+
197212
def insert(self, document):
198213
super(FileStore, self).insert(document)
199214

@@ -213,13 +228,14 @@ def insert(self, document):
213228

214229

215230
def get_filename(self, document):
216-
desc = self.get_full_descriptor(document.descriptor)
231+
desc = self.get_complete_descriptor(document.descriptor)
217232
suffix = self.filename_pattern.format(**desc)
218233
dirname = os.path.dirname(self.__dbfilename)
219234
return os.path.join(dirname, suffix)
220235

221236
def find(self, q=None):
222-
"""Currently support empty query or direct values queries e.g.
237+
"""
238+
Currently support empty query or direct values queries e.g.
223239
for doc in store.find({'phi': 0}):
224240
print doc.data
225241
for doc in store.find({'phi': 0, 'theta': 100}):
@@ -229,7 +245,7 @@ def find(self, q=None):
229245
p = q
230246

231247
# build a file name match pattern based on the query.
232-
for name, properties in self.descriptor_definition.items():
248+
for name, properties in self.parameter_list.items():
233249
if not name in q:
234250
p[name] = "*"
235251
dirname = os.path.dirname(self.__dbfilename)
@@ -253,7 +269,7 @@ def load_document(self, doc_file):
253269
return doc
254270

255271

256-
def make_cinema_descriptor_properties(name, values, **kwargs):
272+
def make_parameter(name, values, **kwargs):
257273
default = kwargs['default'] if 'default' in kwargs else values[0]
258274
typechoice = kwargs['typechoice'] if 'typechoice' in kwargs else 'range'
259275
label = kwargs['label'] if 'label' in kwargs else name

Wrapping/Python/paraview/cinemaIO/explorers.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,30 @@
44
class Explorer(object):
55
"""
66
Middleman that connects an arbitrary producing codes to the CinemaStore.
7-
The purpose of this class is to run through the argument sets, and tell a
8-
set of tracks (in order) to do something with the arguments it cares about.
7+
The purpose of this class is to run through the parameter sets, and tell a
8+
set of tracks (in order) to do something with the parameter values
9+
it cares about.
910
"""
1011

1112
def __init__(self,
1213
cinema_store,
13-
arguments, #these are the things that this explorer is responsible for and their ranges
14-
tracks #the thing we pass off values to to do the work
14+
parameters, #these are the things that this explorer is responsible for and their ranges
15+
tracks #the things we pass off values to in order to do the work
1516
):
1617

1718
self.__cinema_store = cinema_store
18-
self.arguments = arguments
19+
self.parameters = parameters
1920
self.tracks = tracks
2021

2122
@property
2223
def cinema_store(self):
2324
return self.__cinema_store
2425

25-
def list_arguments(self):
26+
def list_parameters(self):
2627
"""
27-
arguments is an ordered list of parameters that the Explorer varies over
28+
parameters is an ordered list of parameters that the Explorer varies over
2829
"""
29-
return self.arguments
30+
return self.parameters
3031

3132
def prepare(self):
3233
""" Give tracks a chance to get ready for a run """
@@ -45,11 +46,11 @@ def explore(self, fixedargs=None):
4546
"""Explore the problem space to populate the store"""
4647
self.prepare()
4748

48-
ordered = self.list_arguments()
49+
ordered = self.list_parameters()
4950
args = []
5051
values = []
5152
for name in ordered:
52-
vals = self.cinema_store.get_descriptor_properties(name)['values']
53+
vals = self.cinema_store.get_parameter(name)['values']
5354
args.append(name)
5455
values.append(vals)
5556

@@ -76,7 +77,7 @@ class Track(object):
7677
7778
to use this:
7879
caller should set up some visualization
79-
then tie a particular set of arguments to an action with a track
80+
then tie a particular set of parameters to an action with a track
8081
"""
8182

8283
def __init__(self):
@@ -91,5 +92,5 @@ def finish(self):
9192
pass
9293

9394
def execute(self, document):
94-
""" subclasses operate on arguments here"""
95+
""" subclasses operate on parameters here"""
9596
pass

0 commit comments

Comments
 (0)