@@ -203,3 +203,139 @@ def test_getParabolicFit():
203203# print(splitPoint)
204204# print(angle)
205205 assert splitPoint ['s' ] == 50
206+
207+
208+ def test_getSplitPoint_noPointFound ():
209+ """Test getSplitPoint when no point meets slope criteria - should return top point"""
210+ cfg = configparser .ConfigParser ()
211+ cfg ['PATH' ] = {'slopeSplitPoint' : '5' , 'dsMin' : '5' } # Very low slope requirement
212+
213+ # Create profile with steep slope everywhere
214+ avaProfile = {
215+ 'x' : np .array ([0 , 10 , 20 , 30 ]),
216+ 'y' : np .array ([0 , 10 , 20 , 30 ]),
217+ 'z' : np .array ([50 , 30 , 10 , 0 ]), # Steep slope throughout
218+ 's' : np .array ([0 , 14.14 , 28.28 , 42.43 ]),
219+ 'indStartMassAverage' : 0 ,
220+ 'indEndMassAverage' : 3
221+ }
222+ # Parabolic fit with steep slope at bottom
223+ parabolicFit = {'a' : 0.01 , 'b' : - 2 , 'c' : 50 }
224+
225+ splitPoint = DFAPathGeneration .getSplitPoint (cfg ['PATH' ], avaProfile , parabolicFit )
226+
227+ # Should return top point when no split point found
228+ assert splitPoint .get ('isTopSplitPoint' , False ) == True
229+ assert splitPoint ['x' ] == avaProfile ['x' ][0 ]
230+ assert splitPoint ['y' ] == avaProfile ['y' ][0 ]
231+ assert splitPoint ['z' ] == avaProfile ['z' ][0 ]
232+
233+
234+ def test_getMassAvgPathFromFields ():
235+ """Test computing mass-averaged path from field data"""
236+ # Create simple 5x5 field with flow in the middle
237+ fieldsList = [{
238+ 'FT' : np .array ([[0 , 0 , 0 , 0 , 0 ],
239+ [0 , 1 , 2 , 1 , 0 ],
240+ [0 , 2 , 3 , 2 , 0 ],
241+ [0 , 1 , 2 , 1 , 0 ],
242+ [0 , 0 , 0 , 0 , 0 ]]), # Flow thickness
243+ 'FM' : np .array ([[0 , 0 , 0 , 0 , 0 ],
244+ [0 , 5 , 10 , 5 , 0 ],
245+ [0 , 10 , 15 , 10 , 0 ],
246+ [0 , 5 , 10 , 5 , 0 ],
247+ [0 , 0 , 0 , 0 , 0 ]]), # Flow mass
248+ 'FV' : np .array ([[0 , 0 , 0 , 0 , 0 ],
249+ [0 , 2 , 3 , 2 , 0 ],
250+ [0 , 3 , 4 , 3 , 0 ],
251+ [0 , 2 , 3 , 2 , 0 ],
252+ [0 , 0 , 0 , 0 , 0 ]]) # Flow velocity
253+ }]
254+
255+ fieldHeader = {
256+ 'ncols' : 5 ,
257+ 'nrows' : 5 ,
258+ 'xllcenter' : 100 ,
259+ 'yllcenter' : 200 ,
260+ 'cellsize' : 5
261+ }
262+
263+ dem = {
264+ 'rasterData' : np .array ([[50 , 50 , 50 , 50 , 50 ],
265+ [40 , 40 , 40 , 40 , 40 ],
266+ [30 , 30 , 30 , 30 , 30 ],
267+ [20 , 20 , 20 , 20 , 20 ],
268+ [10 , 10 , 10 , 10 , 10 ]])
269+ }
270+
271+ result = DFAPathGeneration .getMassAvgPathFromFields (fieldsList , fieldHeader , dem )
272+
273+ # Verify structure
274+ assert 'x' in result
275+ assert 'y' in result
276+ assert 'z' in result
277+ assert 's' in result
278+ assert 'xstd' in result
279+ assert 'ystd' in result
280+ assert 'zstd' in result
281+
282+ # Verify velocity info is included
283+ assert 'u2' in result
284+ assert 'ekin' in result
285+ assert 'u2std' in result
286+ assert 'ekinstd' in result
287+ assert 'totEKin' in result
288+
289+ # Should have one time step
290+ assert len (result ['x' ]) == 1
291+ assert len (result ['y' ]) == 1
292+ assert len (result ['z' ]) == 1
293+
294+ # Coordinates should be relative to origin (xllcenter and yllcenter subtracted)
295+ # Mass-weighted average should be close to center
296+ assert result ['x' ][0 ] > 0 # Relative to xllcenter
297+ assert result ['y' ][0 ] > 0 # Relative to yllcenter
298+
299+
300+ def test_getMassAvgPathFromFields_noVelocity ():
301+ """Test getMassAvgPathFromFields without velocity data"""
302+ # Create simple field without velocity info
303+ fieldsList = [{
304+ 'FT' : np .array ([[0 , 1 , 0 ],
305+ [0 , 2 , 0 ],
306+ [0 , 0 , 0 ]]),
307+ 'FM' : np .array ([[0 , 5 , 0 ],
308+ [0 , 10 , 0 ],
309+ [0 , 0 , 0 ]])
310+ # No FV field
311+ }]
312+
313+ fieldHeader = {
314+ 'ncols' : 3 ,
315+ 'nrows' : 3 ,
316+ 'xllcenter' : 0 ,
317+ 'yllcenter' : 0 ,
318+ 'cellsize' : 10
319+ }
320+
321+ dem = {
322+ 'rasterData' : np .array ([[30 , 30 , 30 ],
323+ [20 , 20 , 20 ],
324+ [10 , 10 , 10 ]])
325+ }
326+
327+ result = DFAPathGeneration .getMassAvgPathFromFields (fieldsList , fieldHeader , dem )
328+
329+ # Verify basic structure
330+ assert 'x' in result
331+ assert 'y' in result
332+ assert 'z' in result
333+ assert 's' in result
334+
335+ # Velocity info should NOT be present
336+ assert 'u2' not in result
337+ assert 'ekin' not in result
338+ assert 'totEKin' not in result
339+
340+ # Should have one time step
341+ assert len (result ['x' ]) == 1
0 commit comments