@@ -21,8 +21,10 @@ class Param(dict):
21
21
-------
22
22
23
23
"""
24
- def __init__ (self , comp_name , name , val , min = - 1e38 , max = 1e38 ,
25
- fmt = "{:.4g}" , frozen = False ):
24
+
25
+ def __init__ (
26
+ self , comp_name , name , val , min = - 1e38 , max = 1e38 , fmt = "{:.4g}" , frozen = False
27
+ ):
26
28
dict .__init__ (self )
27
29
self .comp_name = comp_name
28
30
self .name = name
@@ -42,6 +44,7 @@ def __getattr__(self, attr):
42
44
43
45
class ModelComponent (object ):
44
46
"""Model component base class"""
47
+
45
48
def __init__ (self , model ):
46
49
# This class overrides __setattr__ with a method that requires
47
50
# the `pars` and `pars_dict` attrs to be visible. So do this
@@ -64,8 +67,7 @@ def model_plotdate(self):
64
67
self ._model_plotdate = cxctime2plotdate (self .model .times )
65
68
return self ._model_plotdate
66
69
67
- def add_par (self , name , val = None , min = - 1e38 , max = 1e38 , fmt = "{:.4g}" ,
68
- frozen = False ):
70
+ def add_par (self , name , val = None , min = - 1e38 , max = 1e38 , fmt = "{:.4g}" , frozen = False ):
69
71
param = Param (self .name , name , val , min = min , max = max , fmt = fmt , frozen = frozen )
70
72
self .pars_dict [name ] = param
71
73
self .pars .append (param )
@@ -104,8 +106,7 @@ def get_par(self, name):
104
106
if par .name == name :
105
107
return par
106
108
else :
107
- raise ValueError ('No par named "{}" in {}' ,
108
- self .__class__ .__name__ )
109
+ raise ValueError ('No par named "{}" in {}' , self .__class__ .__name__ )
109
110
110
111
@property
111
112
def name (self ):
@@ -136,28 +137,34 @@ def dvals(self):
136
137
if self .data is None :
137
138
dvals = self .get_dvals_tlm ()
138
139
elif isinstance (self .data , np .ndarray ):
139
- dvals = self .model .interpolate_data (self .data , self .data_times ,
140
- str (self ))
141
- elif isinstance (self .data , (six .integer_types , float , np .integer , np .floating ,
142
- bool , str )):
140
+ dvals = self .model .interpolate_data (
141
+ self .data , self .data_times , str (self )
142
+ )
143
+ elif isinstance (
144
+ self .data ,
145
+ (six .integer_types , float , np .integer , np .floating , bool , str ),
146
+ ):
143
147
if isinstance (self .data , six .string_types ):
144
148
dtype = 'S{}' .format (len (self .data ))
145
149
else :
146
150
dtype = type (self .data )
147
151
dvals = np .empty (self .model .n_times , dtype = dtype )
148
152
dvals [:] = self .data
149
153
else :
150
- raise ValueError ("Data value '{}' and type '{}' for '{}' component "
151
- "not allowed " .format (self .data , type (self .data ).__name__ , self ))
154
+ raise ValueError (
155
+ "Data value '{}' and type '{}' for '{}' component "
156
+ "not allowed " .format (self .data , type (self .data ).__name__ , self )
157
+ )
152
158
self ._dvals = dvals
153
159
return self ._dvals
154
160
155
161
156
162
class TelemData (ModelComponent ):
157
163
times = property (lambda self : self .model .times )
158
164
159
- def __init__ (self , model , msid , mval = True , data = None ,
160
- fetch_attr = 'vals' , units = None ):
165
+ def __init__ (
166
+ self , model , msid , mval = True , data = None , fetch_attr = 'vals' , units = None
167
+ ):
161
168
super (TelemData , self ).__init__ (model )
162
169
self .msid = msid
163
170
self .n_mvals = 1 if mval else 0
@@ -173,8 +180,9 @@ def get_dvals_tlm(self):
173
180
def plot_data__time (self , fig , ax ):
174
181
lines = ax .get_lines ()
175
182
if not lines :
176
- plot_cxctime (self .model .times , self .dvals , ls = '-' , color = '#386cb0' ,
177
- fig = fig , ax = ax )
183
+ plot_cxctime (
184
+ self .model .times , self .dvals , ls = '-' , color = '#386cb0' , fig = fig , ax = ax
185
+ )
178
186
ax .grid ()
179
187
ax .set_title ('{}: data' .format (self .name ))
180
188
ylabel = '%s' % self .name
@@ -226,11 +234,23 @@ class Node(TelemData):
226
234
-------
227
235
228
236
"""
229
- def __init__ (self , model , msid , sigma = - 10 , quant = None ,
230
- predict = True , mask = None , name = None , data = None ,
231
- fetch_attr = 'vals' , units = 'degC' ):
232
- TelemData .__init__ (self , model , msid , data = data ,
233
- fetch_attr = fetch_attr , units = units )
237
+
238
+ def __init__ (
239
+ self ,
240
+ model ,
241
+ msid ,
242
+ sigma = - 10 ,
243
+ quant = None ,
244
+ predict = True ,
245
+ mask = None ,
246
+ name = None ,
247
+ data = None ,
248
+ fetch_attr = 'vals' ,
249
+ units = 'degC' ,
250
+ ):
251
+ TelemData .__init__ (
252
+ self , model , msid , data = data , fetch_attr = fetch_attr , units = units
253
+ )
234
254
self ._sigma = sigma
235
255
self .quant = quant
236
256
self .predict = predict
@@ -254,8 +274,9 @@ def randx(self):
254
274
"""
255
275
if not hasattr (self , '_randx' ):
256
276
dx = self .quant or 1.0
257
- self ._randx = np .random .uniform (low = - dx / 2.0 , high = dx / 2.0 ,
258
- size = self .model .n_times )
277
+ self ._randx = np .random .uniform (
278
+ low = - dx / 2.0 , high = dx / 2.0 , size = self .model .n_times
279
+ )
259
280
return self ._randx
260
281
261
282
@property
@@ -278,17 +299,28 @@ def calc_stat(self):
278
299
resids = self .resids
279
300
if self .mask is not None :
280
301
resids = resids [self .mask .mask ]
281
- return np .sum (resids ** 2 / self .sigma ** 2 )
302
+ return np .sum (resids ** 2 / self .sigma ** 2 )
282
303
283
304
def plot_data__time (self , fig , ax ):
284
305
lines = ax .get_lines ()
285
306
if not lines :
286
- plot_cxctime (self .model .times , self .mvals , ls = '-' , color = '#d92121' , fig = fig , ax = ax )
287
- plot_cxctime (self .model .times , self .dvals , ls = '-' , color = '#386cb0' , fig = fig , ax = ax )
307
+ plot_cxctime (
308
+ self .model .times , self .mvals , ls = '-' , color = '#d92121' , fig = fig , ax = ax
309
+ )
310
+ plot_cxctime (
311
+ self .model .times , self .dvals , ls = '-' , color = '#386cb0' , fig = fig , ax = ax
312
+ )
288
313
# Overplot bad time regions in cyan
289
314
for i0 , i1 in self .model .bad_times_indices :
290
- plot_cxctime (self .model .times [i0 :i1 ], self .dvals [i0 :i1 ], '-c' ,
291
- fig = fig , ax = ax , linewidth = 5 , alpha = 0.5 )
315
+ plot_cxctime (
316
+ self .model .times [i0 :i1 ],
317
+ self .dvals [i0 :i1 ],
318
+ '-c' ,
319
+ fig = fig ,
320
+ ax = ax ,
321
+ linewidth = 5 ,
322
+ alpha = 0.5 ,
323
+ )
292
324
ax .grid ()
293
325
ax .set_title ('{}: model (red) and data (blue)' .format (self .name ))
294
326
ax .set_ylabel ('Temperature (%s)' % self .units )
@@ -304,11 +336,20 @@ def plot_resid__time(self, fig, ax):
304
336
resids [i0 :i1 ] = np .nan
305
337
306
338
if not lines :
307
- plot_cxctime (self .model .times , resids , ls = '-' , color = '#386cb0' , fig = fig , ax = ax )
339
+ plot_cxctime (
340
+ self .model .times , resids , ls = '-' , color = '#386cb0' , fig = fig , ax = ax
341
+ )
308
342
# Overplot bad time regions in cyan
309
343
for i0 , i1 in self .model .bad_times_indices :
310
- plot_cxctime (self .model .times [i0 :i1 ], resids [i0 :i1 ], '-c' ,
311
- fig = fig , ax = ax , linewidth = 5 , alpha = 0.5 )
344
+ plot_cxctime (
345
+ self .model .times [i0 :i1 ],
346
+ resids [i0 :i1 ],
347
+ '-c' ,
348
+ fig = fig ,
349
+ ax = ax ,
350
+ linewidth = 5 ,
351
+ alpha = 0.5 ,
352
+ )
312
353
ax .grid ()
313
354
ax .set_title ('{}: residuals (data - model)' .format (self .name ))
314
355
ax .set_ylabel ('Temperature (%s)' % self .units )
@@ -326,8 +367,14 @@ def plot_resid__data(self, fig, ax):
326
367
resids [i0 :i1 ] = np .nan
327
368
328
369
if not lines :
329
- ax .plot (self .dvals + self .randx , resids , 'o' ,
330
- markersize = 0.25 , color = '#386cb0' , markeredgecolor = '#386cb0' )
370
+ ax .plot (
371
+ self .dvals + self .randx ,
372
+ resids ,
373
+ 'o' ,
374
+ markersize = 0.25 ,
375
+ color = '#386cb0' ,
376
+ markeredgecolor = '#386cb0' ,
377
+ )
331
378
ax .grid ()
332
379
ax .set_title ('{}: residuals (data - model) vs data' .format (self .name ))
333
380
ax .set_ylabel ('Residuals (%s)' % self .units )
@@ -352,17 +399,19 @@ class Coupling(ModelComponent):
352
399
-------
353
400
354
401
"""
402
+
355
403
def __init__ (self , model , node1 , node2 , tau ):
356
404
ModelComponent .__init__ (self , model )
357
405
self .node1 = self .model .get_comp (node1 )
358
406
self .node2 = self .model .get_comp (node2 )
359
407
self .add_par ('tau' , tau , min = 2.0 , max = 200.0 )
360
408
361
409
def update (self ):
362
- self .tmal_ints = (tmal .OPCODES ['coupling' ],
363
- self .node1 .mvals_i , # y1 index
364
- self .node2 .mvals_i # y2 index
365
- )
410
+ self .tmal_ints = (
411
+ tmal .OPCODES ['coupling' ],
412
+ self .node1 .mvals_i , # y1 index
413
+ self .node2 .mvals_i , # y2 index
414
+ )
366
415
self .tmal_floats = (self .tau ,)
367
416
368
417
def __str__ (self ):
@@ -377,6 +426,7 @@ class Delay(ModelComponent):
377
426
``delay`` ksec. Conversely for a negative delay the values at the end will
378
427
be constant for ``delay`` ksec.
379
428
"""
429
+
380
430
def __init__ (self , model , node , delay = 0 ):
381
431
super ().__init__ (model )
382
432
self .node = self .model .get_comp (node )
@@ -388,17 +438,16 @@ def __str__(self):
388
438
389
439
class HeatSink (ModelComponent ):
390
440
"""Fixed temperature external heat bath"""
441
+
391
442
def __init__ (self , model , node , T = 0.0 , tau = 20.0 ):
392
443
ModelComponent .__init__ (self , model )
393
444
self .node = self .model .get_comp (node )
394
445
self .add_par ('T' , T , min = - 100.0 , max = 100.0 )
395
446
self .add_par ('tau' , tau , min = 2.0 , max = 200.0 )
396
447
397
448
def update (self ):
398
- self .tmal_ints = (tmal .OPCODES ['heatsink' ],
399
- self .node .mvals_i ) # dy1/dt index
400
- self .tmal_floats = (self .T ,
401
- self .tau )
449
+ self .tmal_ints = (tmal .OPCODES ['heatsink' ], self .node .mvals_i ) # dy1/dt index
450
+ self .tmal_floats = (self .T , self .tau )
402
451
403
452
def __str__ (self ):
404
453
return 'heatsink__{0}' .format (self .node )
@@ -425,6 +474,7 @@ class HeatSinkRef(ModelComponent):
425
474
-------
426
475
427
476
"""
477
+
428
478
def __init__ (self , model , node , T = 0.0 , tau = 20.0 , T_ref = 20.0 ):
429
479
ModelComponent .__init__ (self , model )
430
480
self .node = self .model .get_comp (node )
@@ -433,10 +483,8 @@ def __init__(self, model, node, T=0.0, tau=20.0, T_ref=20.0):
433
483
self .add_par ('T_ref' , T_ref , min = - 100 , max = 100 )
434
484
435
485
def update (self ):
436
- self .tmal_ints = (tmal .OPCODES ['heatsink' ],
437
- self .node .mvals_i ) # dy1/dt index
438
- self .tmal_floats = (self .P * self .tau + self .T_ref ,
439
- self .tau )
486
+ self .tmal_ints = (tmal .OPCODES ['heatsink' ], self .node .mvals_i ) # dy1/dt index
487
+ self .tmal_floats = (self .P * self .tau + self .T_ref , self .tau )
440
488
441
489
def __str__ (self ):
442
490
return 'heatsink__{0}' .format (self .node )
@@ -473,6 +521,7 @@ class AcisFPtemp(Node):
473
521
-------
474
522
475
523
"""
524
+
476
525
def __init__ (self , model , mask = None ):
477
526
Node .__init__ (self , model , 'fptemp_11' , mask = mask )
478
527
0 commit comments