11#! python3
22
3+ import csv
4+ import os
5+ import typing
36
47from ghpythonlib .componentbase import executingcomponent as component
58
6- from diffCheck .df_error_estimation import DFInvalidData
7- import csv
8- import os
9+ from diffCheck .df_error_estimation import DFInvalidData , DFVizResults
910
1011
1112class DFCsvExporter (component ):
@@ -14,7 +15,10 @@ def __init__(self):
1415 self .prefix = ""
1516 self .counter = 0
1617
17- def _get_id (self , idx , i_result ):
18+ def _get_id (self ,
19+ idx : int ,
20+ i_result : DFVizResults
21+ ) -> str :
1822 """ Get the ID of the element """
1923 counter = 0
2024
@@ -34,15 +38,18 @@ def _get_id(self, idx, i_result):
3438 return f"{ idx_b } --{ idx_j } --{ idx_f } "
3539 counter += 1
3640
37- def _write_csv (self , file_path , rows ):
38- """ Write the CSV file """
39- with open (file_path , mode = 'w' , newline = '' ) as file :
40- writer = csv .writer (file )
41- writer .writerow ([f"{ self .prefix } id" , "distances" , "min_deviation" , "max_deviation" , "std_deviation" , "rmse" , "mean" ])
42- writer .writerows (rows )
41+ def _prepare_row (self ,
42+ idx : int ,
43+ i_result : DFVizResults
44+ ) -> typing .Dict :
45+ """
46+ Convert the results contained in the DFVizResults object to a dict to be written in the CSV file
47+
48+ :param idx: Index of the element
49+ :param i_result: DFVizResults object containing all the values
4350
44- def _prepare_row ( self , idx , i_result ):
45- """ Prepare a row for the CSV file """
51+ :return: Dict of values containng as keys the header and as items the values to be written in the CSV file
52+ """
4653 if i_result .sanity_check [idx ].value != DFInvalidData .VALID .value :
4754 invalid_type = i_result .sanity_check [idx ].name
4855 return [self ._get_id (idx , i_result ), invalid_type , invalid_type , invalid_type , invalid_type , invalid_type , invalid_type ]
@@ -53,16 +60,57 @@ def _prepare_row(self, idx, i_result):
5360 std_dev = round (i_result .distances_sd_deviation [idx ], 4 )
5461 rmse = round (i_result .distances_rmse [idx ], 4 )
5562 mean = round (i_result .distances_mean [idx ], 4 )
56- distances_str = ";" .join (map (str , distances ))
57- return [self ._get_id (idx , i_result ), distances_str , min_dev , max_dev , std_dev , rmse , mean ]
63+
64+ row : typing .Dict = {
65+ f"{ self .prefix } id" : self ._get_id (idx , i_result ),
66+ "distances" : distances ,
67+ "min_deviation" : min_dev ,
68+ "max_deviation" : max_dev ,
69+ "std_deviation" : std_dev ,
70+ "rmse" : rmse ,
71+ "mean" : mean
72+ }
73+ return row
74+
75+ def _write_csv (self ,
76+ csv_path : str ,
77+ rows : typing .List [typing .Dict ],
78+ is_writing_only_distances : bool = False
79+ ) -> None :
80+ """
81+ Write the CSV file
82+
83+ :param csv_path: Path of the CSV file
84+ :param rows: Dict of values to be written in the CSV file
85+ :param is_writing_only_distances: Flag to check if to write ONLY distances or the whole analysis
86+
87+ :return: None
88+ """
89+ with open (csv_path , mode = 'w' , newline = '' ) as file :
90+ writer = csv .writer (file , quoting = csv .QUOTE_MINIMAL )
91+ if is_writing_only_distances :
92+ writer .writerow (list (rows [0 ].keys ())[:2 ]) # header
93+ element_id = [row [f"{ self .prefix } id" ] for row in rows ]
94+ dist_rows = [row ["distances" ] for row in rows ]
95+ for idx , dist_row in enumerate (dist_rows ):
96+ for dist in dist_row :
97+ writer .writerow ([element_id [idx ], dist ])
98+ else :
99+ rows = [{k : v for k , v in row .items () if k != "distances" } for row in rows ] # no distances
100+ writer .writerow (list (rows [0 ].keys ())) # header
101+ writer .writerows ([list (row .values ()) for row in rows ])
58102
59103 def RunScript (self ,
60104 i_dump : bool ,
61105 i_export_dir : str ,
62106 i_file_name : str ,
63107 i_export_seperate_files : bool ,
108+ i_export_distances : bool ,
64109 i_result ):
65110
111+ csv_analysis_path : str = None
112+ csv_distances_path : str = None
113+
66114 if i_dump :
67115 os .makedirs (i_export_dir , exist_ok = True )
68116
@@ -75,10 +123,17 @@ def RunScript(self,
75123
76124 if i_export_seperate_files :
77125 for idx in range (len (i_result .source )):
78- element_id = self ._get_id ( idx , i_result )
79- file_path = os .path .join (i_export_dir , f"{ i_file_name } _{ self .prefix } _{ element_id } .csv" )
80- self ._write_csv (file_path , [self ._prepare_row (idx , i_result )])
126+ element_id = self ._get_id (idx , i_result )
127+ csv_analysis_path = os .path .join (i_export_dir , f"{ i_file_name } _{ self .prefix } _{ element_id } .csv" )
128+ rows = [self ._prepare_row (idx , i_result )]
129+ self ._write_csv (csv_analysis_path , rows )
130+ if i_export_distances :
131+ csv_distances_path = os .path .join (i_export_dir , f"{ i_file_name } _{ self .prefix } _{ element_id } _distances.csv" )
132+ self ._write_csv (csv_distances_path , rows , is_writing_only_distances = True )
81133 else :
82- file_path = os .path .join (i_export_dir , f"{ i_file_name } .csv" )
83- rows = [self ._prepare_row (idx , i_result ) for idx in range (len (i_result .source ))]
84- self ._write_csv (file_path , rows )
134+ csv_analysis_path = os .path .join (i_export_dir , f"{ i_file_name } .csv" )
135+ merged_rows = [self ._prepare_row (idx , i_result ) for idx in range (len (i_result .source ))]
136+ self ._write_csv (csv_analysis_path , merged_rows )
137+ if i_export_distances :
138+ csv_distances_path = os .path .join (i_export_dir , f"{ i_file_name } _distances.csv" )
139+ self ._write_csv (csv_distances_path , merged_rows , is_writing_only_distances = True )
0 commit comments