11from __future__ import annotations
22
3+ import csv
4+
35from warnings import warn
46from typing import Sequence , TYPE_CHECKING
57
@@ -25,7 +27,7 @@ def format_alias(names: Sequence[str], units: Sequence[str]) -> list[str]:
2527 return aliases
2628
2729
28- t_names = ['t' , 'time' , 'testtime' ]
30+ t_names = ['t' , 'time' , 'testtime' , 'totaltime' ]
2931t_units = ['s' , 'sec' , 'seconds' , 'min' , 'minutes' , 'h' , 'hrs' , 'hours' ]
3032
3133i_names = ['i' , 'amperage' , 'current' ]
@@ -34,10 +36,10 @@ def format_alias(names: Sequence[str], units: Sequence[str]) -> list[str]:
3436v_names = ['voltage' , 'potential' , 'ecell' ]
3537v_units = ['v' , 'volts' ]
3638
37- q_names = ['capacity' ]
39+ q_names = ['capacity' , 'amphours' ]
3840q_units = ['ah' , 'ahr' , 'amphr' , 'mah' , 'mahr' , 'mamphr' ]
3941
40- e_names = ['energy' ]
42+ e_names = ['energy' , 'watthours' ]
4143e_units = ['wh' , 'whr' , 'watthr' ]
4244
4345HEADER_ALIASES = {
@@ -47,20 +49,20 @@ def format_alias(names: Sequence[str], units: Sequence[str]) -> list[str]:
4749
4850 'Cycle' : ['cycle' , 'cyc' , 'cycleindex' , 'cyclenumber' , 'cyclec' , 'cyclep' ],
4951 'Step' : ['step' , 'ns' , 'stepindex' ],
50- 'State' : ['state' , 'md' ],
52+ 'State' : ['state' , 'md' , 'mode' ],
5153
5254 'Ah' : format_alias (q_names , q_units ),
5355 'Wh' : format_alias (e_names , e_units ),
5456
55- 'DateTime' : ['datetime' , 'dpttime' ],
57+ 'DateTime' : ['datetime' , 'dpttime' , 'realtime' ],
5658}
5759
5860REQUIRED_HEADERS = ['Seconds' , 'Amps' , 'Volts' ]
5961
6062
6163# Remove unnecessary characters from header strings
6264def strip_chars (string : str ) -> str :
63- transmap = str .maketrans ('(/' , '..' , ' _-#<>)' )
65+ transmap = str .maketrans ('(/, ' , '. ..' , ' _-#<>)' )
6466 return string .lower ().translate (transmap )
6567
6668
@@ -124,6 +126,9 @@ def standardize_headers(data: pd.DataFrame) -> Dataset:
124126
125127 # Guarantee sign 'Amps' sign convention (+ charge, - discharge)
126128 if 'State' in df .columns :
129+ rename_bitrode = {'REST' : 'R' , 'DCHG' : 'D' , 'CHRG' : 'C' }
130+ df ['State' ] = df ['State' ].replace (rename_bitrode )
131+
127132 df ['Amps' ] = df ['Amps' ].astype (float )
128133 df ['State' ] = df ['State' ].astype (str )
129134
@@ -152,13 +157,14 @@ def standardize_headers(data: pd.DataFrame) -> Dataset:
152157 # Convert types
153158 if std_header in df .columns :
154159 if std_header in ['State' , 'DateTime' ]:
155- df [std_header ] = df [std_header ].astype (str )
160+ df [std_header ] = df [std_header ].astype ('string' )
156161 elif std_header in ['Cycle' , 'Step' ]:
157- df [std_header ] = df [std_header ].astype (int )
162+ df [std_header ] = df [std_header ].astype ('Int64' )
158163 else :
159164 df [std_header ] = df [std_header ].replace ('#' , '' , regex = True )
160165 df [std_header ] = df [std_header ].replace (',' , '' , regex = True )
161- df [std_header ] = df [std_header ].astype (float )
166+
167+ df [std_header ] = pd .to_numeric (df [std_header ], errors = 'coerce' )
162168 else :
163169 missing .append (std_header )
164170
@@ -172,16 +178,19 @@ def read_table(filepath: PathLike) -> Dataset:
172178 """Read tab-delimited file."""
173179 from ampworks import Dataset
174180
175- with open (filepath , encoding = 'utf-8' ) as datafile :
181+ options = {'separator' : '\t ' , 'skip_rows' : 0 , 'ignore_errors' : True }
182+ with open (filepath , encoding = 'latin1' ) as datafile :
183+ reader = csv .reader (datafile , delimiter = '\t ' )
176184
177- skiprows , found_header = 0 , False
178- for idx , line in enumerate (datafile ):
179- if header_matches (line .rstrip ('\n ' ).split ('\t ' ), REQUIRED_HEADERS ):
180- skiprows , found_header = idx , True
185+ found_header = False
186+ for idx , line in enumerate (reader ):
187+ if header_matches (line , REQUIRED_HEADERS ):
188+ options ['skip_rows' ] = idx
189+ found_header = True
181190 break
182191
183192 if found_header :
184- df = pl .read_csv (filepath , separator = ' \t ' , skip_rows = skiprows )
193+ df = pl .read_csv (filepath , ** options )
185194 return standardize_headers (df .to_pandas ())
186195
187196 return Dataset ()
@@ -286,16 +295,19 @@ def read_csv(filepath: PathLike) -> Dataset:
286295 """Read csv file."""
287296 from ampworks import Dataset
288297
289- with open (filepath , encoding = 'utf-8' ) as datafile :
298+ options = {'separator' : ',' , 'skip_rows' : 0 , 'ignore_errors' : True }
299+ with open (filepath , encoding = 'latin1' ) as datafile :
300+ reader = csv .reader (datafile , delimiter = ',' )
290301
291- skiprows , found_header = 0 , False
292- for idx , line in enumerate (datafile ):
293- if header_matches (line .rstrip ('\n ' ).split (',' ), REQUIRED_HEADERS ):
294- skiprows , found_header = idx , True
302+ found_header = False
303+ for idx , line in enumerate (reader ):
304+ if header_matches (line , REQUIRED_HEADERS ):
305+ options ['skip_rows' ] = idx
306+ found_header = True
295307 break
296308
297309 if found_header :
298- df = pl .read_csv (filepath , separator = ',' , skip_rows = skiprows )
310+ df = pl .read_csv (filepath , ** options )
299311 return standardize_headers (df .to_pandas ())
300312
301313 return Dataset ()
0 commit comments