@@ -155,38 +155,69 @@ def setpar(key, val, file, delim="=", match_partial=False):
155155 f .writelines (lines )
156156
157157
158- def getpar_vel_model ( file ):
158+ def _getidx_vel_model ( lines ):
159159 """
160- SPECFEM2D doesn't follow standard formatting when defining its internal
161- velocity models so we need a special function to address this specifically.
162- Velocity models are ASSUMED to be formatted in the following way in the
163- SPECFEM2D Par_file (with any number of comment lines in between)
160+ Get the line indices of a velocity model, which can be used to retrieve
161+ or replace the model values in a SPECFEM2D paramter file. Used by
162+ `getpar_vel_model` and `setpar_vel_model`
163+
164+ :type lines: list
165+ :param lines: list of strings read from the par_file
166+ :rtype idxs: list
167+ :param idxs: list of integer indices of the velocity model lines
168+ """
169+ idxs = []
170+ for l , line in enumerate (lines ):
171+ # Skip over all other parameters, comments, newlines etc.
172+ if "=" in line :
173+ continue
174+ elif line .startswith (" " ):
175+ continue
176+ elif line .startswith ("#" ):
177+ continue
178+ elif line .startswith ("\n " ):
179+ continue
180+
181+ # Matches formatting expected by velocity model and starts with integer
182+ # Should be enough to avoid matching other strings
183+ lines = line .strip ().split ()
184+ if len (lines ) == 15 and lines [0 ].isdigit ():
185+ idxs .append (l )
186+
187+ return idxs
188+
189+
190+ def getpar_vel_model (file , strip = False ):
191+ """
192+ SPECFEM2D doesn't follow standard key = val formatting when defining its
193+ internal velocity models so we need a special function to address this
194+ specifically.
195+
196+ Velocity models are ASSUMED to be formatted in the following way
164197
165- nbmodels = 4
166198 1 1 2700.d0 3000.d0 1732.051d0 0 0 9999 9999 0 0 0 0 0 0
167- 2 1 2500.d0 2700.d0 0 0 0 9999 9999 0 0 0 0 0 0
168- 3 1 2200.d0 2500.d0 1443.375d0 0 0 9999 9999 0 0 0 0 0 0
169- 4 1 2200.d0 2200.d0 1343.375d0 0 0 9999 9999 0 0 0 0 0 0
170- TOMOGRAPHY_FILE = ./DATA/tomo_file.xyz
171199
200+ That is, 15 entries separated by spaces. We use that to find all relevant
201+ lines of the model.
202+
172203 :type file: str
173204 :param file: The SPECFEM Par_file to match against
205+ :type strip: bool
206+ :param strip: strip newline '\n ' from each of the model lines
174207 :rtype: list of str
175208 :return: list of all the layers of the velocity model as strings
176209 """
177- _ , _ , i_start = getpar ("nbmodels" , file )
178- _ , _ , i_end = getpar ("tomography_file" , file )
179-
180210 # i_start + 1 to skip over the 'nbmodels' parameter
181- lines = open (file , "r" ).readlines ()[i_start + 1 :i_end ]
211+ lines = open (file , "r" ).readlines ()
212+ idxs = _getidx_vel_model (lines )
182213 vel_model = []
183- for line in lines :
184- # Skip comments, empty lines, newlines
185- for not_allowed in [" " , "#" , "\n " ]:
186- if line .startswith (not_allowed ):
187- break
214+ for idx in idxs :
215+ if strip :
216+ line = lines [idx ].strip ()
188217 else :
189- vel_model .append (line .strip ())
218+ line = lines [idx ]
219+ vel_model .append (line )
220+
190221 return vel_model
191222
192223
@@ -207,34 +238,19 @@ def setpar_vel_model(file, model):
207238 model = ["1 1 2700.d0 3000.d0 1732.051d0 0 0 9999 9999 0 0 0 0 0 0",
208239 "2 1 2500.d0 2700.d0 0 0 0 9999 9999 0 0 0 0 0 0"]
209240 """
210- _ , nbmodels , i_start = getpar ("nbmodels" , file )
211- i_start += 1 # increase by one to start AFTER nbmodels line
212- _ , _ , i_end = getpar ("tomography_file" , file )
213-
214241 lines = open (file , "r" ).readlines ()
215- model_lines = []
216- # i_start + 1 to skip over the 'nbmodels' parameter
217- for i , line in enumerate (lines [i_start :i_end ]):
218- # Skip comments, empty lines, newlines
219- for not_allowed in [" " , "#" , "\n " ]:
220- if line .startswith (not_allowed ):
221- break
222- else :
223- # We will use these indices to delete the original model
224- model_lines .append (i )
225-
226- # Make sure that our indices are relative to the list and not enumeration
227- model_lines = [_ + i_start for _ in model_lines ]
242+ model_lines = _getidx_vel_model (open (file , "r" ).readlines ())
228243
229- # one-liner to get rid of the original model
244+ # one-liner to get rid of the original model from the file
230245 lines = [i for j , i in enumerate (lines ) if j not in model_lines ]
246+ model_idx_start = model_lines [0 ]
231247
232248 # Throw a new line onto the last line of the model to get proper formatting
233249 model [- 1 ] = model [- 1 ] + "\n "
234250
235251 # Drop in the new model one line at a time
236252 for i , val in enumerate (model ):
237- lines .insert (i + model_lines [ 0 ] , f"{ val .strip ()} \n " )
253+ lines .insert (model_idx_start + i , f"{ val .strip ()} \n " )
238254
239255 # Overwrite with new lines containing updated velocity model
240256 with open (file , "w" ) as f :
0 commit comments