22
22
import matplotlib .pyplot as plt
23
23
import numpy as np
24
24
import pandas as pd
25
+ from pylocker import Locker
25
26
from rich .console import Console
26
27
from rich .table import Table
27
28
@@ -291,8 +292,13 @@ def get_output(output):
291
292
result_s = result_s .strip (' ' ).strip (',' ) # get rid of last space and comma
292
293
result_s += '\n '
293
294
294
- with open (output_file , 'a' ) as f :
295
- f .write (result_s )
295
+ # write the result to a file in a concurrent thread safe way
296
+ lock_pass = str (uuid .uuid1 ())
297
+ FL = Locker (filePath = output_file , lockPass = lock_pass , timeout = 10 , mode = 'a' )
298
+ with FL as r :
299
+ acquired , code , fd = r
300
+ if fd is not None :
301
+ fd .write (result_s )
296
302
297
303
298
304
def main (command_line_args = None ):
@@ -440,19 +446,14 @@ def main(command_line_args=None):
440
446
result_count = result_count + 1
441
447
if '-9999.0' not in line and len (s ) > 1 :
442
448
line = line .strip ()
443
- if len (line ) > 3 :
449
+ if len (line ) > 10 :
444
450
line , sep , tail = line .partition (', (' ) # strip off the Input Variable Values
445
451
line = line .replace ('(' , '' ).replace (')' , '' ) # strip off the ()
446
452
results .append ([float (y ) for y in line .split (',' )])
447
453
else :
448
454
logger .warning (f'-9999.0 or space found in line { result_count !s} ' )
449
455
450
456
actual_records_count = len (results )
451
-
452
- # Load the results into a pandas dataframe
453
- results_pd = pd .read_csv (output_file )
454
- df = pd .DataFrame (results_pd )
455
-
456
457
if len (results ) < 1 :
457
458
# TODO surface actual exceptions instead of giving this generic message
458
459
raise RuntimeError (
@@ -469,25 +470,72 @@ def main(command_line_args=None):
469
470
means = np .nanmean (results , 0 )
470
471
std = np .nanstd (results , 0 )
471
472
473
+ # Load the results into a pandas dataframe
474
+ results_pd = pd .read_csv (output_file )
475
+ df = pd .DataFrame (results_pd )
476
+
477
+ # Build a second dataframe to contain the input data. In the df dataframe, it is too encoded to be useful
478
+ input_df = pd .DataFrame ()
479
+
480
+ # add the columns
481
+ input_row = df [df .columns [len (outputs )]].tolist ()[0 ]
482
+ input_row = input_row .replace ('(' , '' ).replace (')' , '' )
483
+ input_row = input_row .strip ().strip (';' )
484
+ input_columns_data = input_row .split (';' )
485
+ for input_column_data in input_columns_data :
486
+ input_column_name , input_column_value = input_column_data .split (':' )
487
+ input_df [input_column_name ] = []
488
+
489
+ # add the data
490
+ for i in range (actual_records_count ):
491
+ input_row = str (df [df .columns [len (outputs )]].tolist ()[i ])
492
+ if len (input_row ) < 10 :
493
+ continue
494
+ input_row = input_row .replace ('(' , '' ).replace (')' , '' )
495
+ input_row = input_row .strip ().strip (';' )
496
+ input_columns_data = input_row .split (';' )
497
+ data = []
498
+ for input_column_data in input_columns_data :
499
+ input_column_name , input_column_value = input_column_data .split (':' )
500
+ data .append (float (input_column_value ))
501
+ input_df .loc [i ] = data
502
+
472
503
logger .info (f'Calculation Time: { time .time () - tic :10.3f} sec' )
473
504
logger .info (f'Calculation Time per iteration: { (time .time () - tic ) / actual_records_count :10.3f} sec' )
474
505
if iterations != actual_records_count :
475
- logger .warning (
476
- f'NOTE: { actual_records_count !s} iterations finished successfully and were used to calculate the '
477
- f'statistics.'
478
- )
506
+ msg = f'NOTE: { actual_records_count !s} iterations finished successfully and were used to calculate the statistics.'
507
+ logger .warning (msg )
479
508
480
- # write them out
509
+ # write them out and make the graphs
481
510
annotations = ''
482
511
outputs_result : dict [str , dict ] = {}
512
+
513
+ input = ''
483
514
full_names : set = set ()
484
515
short_names : set = set ()
485
516
with open (output_file , 'a' ) as f :
486
- if iterations != actual_records_count :
487
- f .write (
488
- f'\n \n { actual_records_count !s} iterations finished successfully and were used to calculate the '
489
- f'statistics\n \n '
490
- )
517
+
518
+ # First do the input graphs
519
+ for i in range (len (inputs )):
520
+ input = inputs [i ][0 ]
521
+ plt .figure (figsize = (8 , 6 ))
522
+ ax = plt .subplot ()
523
+ ax .set_title (input )
524
+ ax .set_xlabel ('Random Values' )
525
+ ax .set_ylabel ('Probability' )
526
+
527
+ plt .figtext (0.11 , 0.74 , annotations , fontsize = 8 )
528
+ ret = plt .hist (input_df [input_df .columns [i ]].tolist (), bins = 50 , density = True )
529
+ fname = input_df .columns [i ].strip ().replace ('/' , '-' )
530
+ save_path = Path (Path (output_file ).parent , f'{ fname } .png' )
531
+ if html_path :
532
+ save_path = Path (Path (html_path ).parent , f'{ fname } .png' )
533
+ plt .savefig (save_path )
534
+ plt .close ()
535
+ full_names .add (save_path )
536
+ short_names .add (fname )
537
+
538
+ # Now do the output graphs
491
539
for i in range (len (outputs )):
492
540
output = outputs [i ]
493
541
f .write (f'{ output } :\n ' )
@@ -519,6 +567,7 @@ def main(command_line_args=None):
519
567
if html_path :
520
568
save_path = Path (Path (html_path ).parent , f'{ fname } .png' )
521
569
plt .savefig (save_path )
570
+ plt .close ()
522
571
full_names .add (save_path )
523
572
short_names .add (fname )
524
573
annotations = ''
0 commit comments