44
55import numpy as np
66import re
7+ import pybamm
78
89examples = """
910
@@ -211,15 +212,15 @@ def read_string(self, cond, drive_cycles):
211212 else :
212213 period = self .period
213214
214- # Read temperature
215- temperature = self .read_temperature (cond )
215+ # Temperature part of the condition is removed here
216+ unprocessed_cond = cond
217+ temperature , cond = self ._read_and_drop_temperature (cond )
216218
217219 # Read instructions
218220 if "Run" in cond :
219221 cond_list = cond .split ()
220- if "oC" not in cond :
221- if "at" in cond :
222- raise ValueError (f"Instruction must be of the form: { examples } " )
222+ if "at" in cond :
223+ raise ValueError (f"Instruction must be of the form: { examples } " )
223224 dc_types = ["(A)" , "(V)" , "(W)" ]
224225 if all (x not in cond for x in dc_types ):
225226 raise ValueError (
@@ -255,43 +256,23 @@ def read_string(self, cond, drive_cycles):
255256 electric = self .convert_electric (cond_list [:idx_for ])
256257
257258 time = self .convert_time_to_seconds (cond_list [idx_for + 1 : idx_until ])
259+ events = self .convert_electric (cond_list [idx_until + 2 :])
258260
259- # remove temperture part of string
260- reduced_cond_list = cond_list [idx_until + 2 :]
261- if "at" in reduced_cond_list :
262- at_idx = reduced_cond_list .index ("at" )
263- reduced_cond_list = reduced_cond_list [:at_idx ]
264-
265- events = self .convert_electric (reduced_cond_list )
266261 elif "for" in cond :
267262 # e.g. for 3 hours
268263 cond_list = cond .split ()
269264 idx = cond_list .index ("for" )
270265
271266 electric = self .convert_electric (cond_list [:idx ])
272-
273- # remove temperture part of string
274- reduced_cond_list = cond_list [idx + 1 :]
275- if "at" in reduced_cond_list :
276- at_idx = reduced_cond_list .index ("at" )
277- reduced_cond_list = reduced_cond_list [:at_idx ]
278-
279- time = self .convert_time_to_seconds (reduced_cond_list )
267+ time = self .convert_time_to_seconds (cond_list [idx + 1 :])
280268 events = None
281269 elif "until" in cond :
282270 # e.g. until 4.2 V
283271 cond_list = cond .split ()
284272 idx = cond_list .index ("until" )
285273 electric = self .convert_electric (cond_list [:idx ])
286274 time = None
287-
288- # remove temperture part of string
289- reduced_cond_list = cond_list [idx + 1 :]
290- if "at" in reduced_cond_list :
291- at_idx = reduced_cond_list .index ("at" )
292- reduced_cond_list = reduced_cond_list [:at_idx ]
293-
294- events = self .convert_electric (reduced_cond_list )
275+ events = self .convert_electric (cond_list [idx + 1 :])
295276 else :
296277 raise ValueError (
297278 "Operating conditions must contain keyword 'for' or 'until' or "
@@ -307,7 +288,7 @@ def read_string(self, cond, drive_cycles):
307288 "period" : period ,
308289 "temperature" : temperature ,
309290 "dc_data" : dc_data ,
310- "string" : cond ,
291+ "string" : unprocessed_cond ,
311292 "events" : events ,
312293 }
313294
@@ -421,7 +402,7 @@ def convert_electric(self, electric):
421402 )
422403 )
423404
424- def read_temperature (self , cond ):
405+ def _read_and_drop_temperature (self , cond ):
425406
426407 if (len (re .findall ("at" , cond )) > 1 or ("Run" in cond and "at" in cond )) and (
427408 "oC" not in cond
@@ -434,38 +415,45 @@ def read_temperature(self, cond):
434415 f"{ cond } "
435416 )
436417
437- if "oC" in cond :
438- matches = re .findall ("(\-*[0-9]*\.*[0-9]*)(\s*oC)" , cond )
418+ matches = re .findall (r"at\s-*\d+\.*\d*\s*oC" , cond )
439419
440- non_empty_matches = [m for m in matches [0 ] if m ]
420+ if len (matches ) == 0 and "oC" in cond :
421+ raise ValueError (
422+ f"Temperature not written "
423+ f"correctly on step: '{ cond } '"
424+ )
441425
442- first_match = non_empty_matches [ 0 ]
426+ if len ( matches ) == 0 :
443427
444- try :
445- temperature = float (first_match )
446- except ValueError :
447- raise ValueError (
448- f"Temperature not found correctly "
449- f"on step: { cond } . "
450- f"Cannot convert { first_match } to a float."
451- f" Regex matches found: { non_empty_matches } . "
452- "If the temperature value is found by regex but is "
453- "not the first match, please restucture your input."
428+ if self .temperature is None :
429+
430+ pybamm .logger .warning (
431+ "Temperature not found on step: "
432+ f"'{ cond } ', using temperature "
433+ "from parameter values."
454434 )
455435
456- # try to find 'at" keyword before temperature
457- matches = re .findall (f"at\s*{ first_match } " , cond )
458- if len (matches ) == 0 :
459- raise ValueError (
460- f"Temperature not written correctly "
461- f"on step: { cond } . "
462- f"Cannot find 'at' keyword before temperature value: { first_match } ."
436+ else :
437+
438+ pybamm .logger .warning (
439+ f"Temperature not found on step: '{ cond } ', "
440+ f"using global temperature "
441+ f"({ self .temperature } oC) instead"
463442 )
464443
465- else :
466444 temperature = self .temperature
445+ reduced_cond = cond
446+
447+ elif len (matches ) == 1 :
448+ match = matches [0 ]
449+ numerical_part = re .findall (r"-*\d+\.*\d*" , match )[0 ]
450+ temperature = float (numerical_part )
451+ reduced_cond = cond .replace (match , "" )
452+
453+ else :
454+ raise ValueError (f"More than one temperature found on step: '{ cond } '" )
467455
468- return temperature
456+ return temperature , reduced_cond
469457
470458 def convert_time_to_seconds (self , time_and_units ):
471459 """Convert a time in seconds, minutes or hours to a time in seconds"""
0 commit comments