wolfhece 2.0.11__py3-none-any.whl → 2.0.13__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
wolfhece/wolf_array.py CHANGED
@@ -1364,15 +1364,30 @@ class Ops_Array(wx.Frame):
1364
1364
  _("Reset"), wx.DefaultPosition,
1365
1365
  wx.DefaultSize, 0)
1366
1366
  self.ResetSelection.SetToolTip(_("Reset the current selection list (keyboard shortcut r)"))
1367
+
1367
1368
  bSizer16.Add(self.ResetSelection, 0, wx.EXPAND)
1369
+
1368
1370
  self.ResetAllSelection = wx.Button(self.selection, wx.ID_ANY,
1369
1371
  _("Reset All"), wx.DefaultPosition,
1370
1372
  wx.DefaultSize, 0)
1371
1373
  self.ResetAllSelection.SetToolTip(_("Reset the current selection list and the indexed lists (keyboard shortcut R)"))
1372
1374
  bSizer16.Add(self.ResetAllSelection, 0, wx.EXPAND)
1373
1375
 
1376
+ self.to_clipboard_str = wx.Button(self.selection, wx.ID_ANY, _("To clipboard (str)"), wx.DefaultPosition,
1377
+ wx.DefaultSize, 0)
1378
+ self.to_clipboard_str.SetToolTip(_("Copy the current selection to the clipboard as a string"))
1379
+
1380
+ self.to_clipboard_script = wx.Button(self.selection, wx.ID_ANY, _("To clipboard (script)"), wx.DefaultPosition,
1381
+ wx.DefaultSize, 0)
1382
+ self.to_clipboard_script.SetToolTip(_("Copy the current selection to the clipboard as a script"))
1383
+
1384
+ bSizer16.Add(self.to_clipboard_str, 0, wx.EXPAND)
1385
+ bSizer16.Add(self.to_clipboard_script, 0, wx.EXPAND)
1386
+
1374
1387
  bSizer21.Add(bSizer16, 1, wx.EXPAND, 5)
1375
1388
 
1389
+
1390
+
1376
1391
  bSizer17 = wx.BoxSizer(wx.VERTICAL)
1377
1392
 
1378
1393
  self.m_button2 = wx.Button(self.selection, wx.ID_ANY, _("Manage vectors"), wx.DefaultPosition, wx.DefaultSize,
@@ -1392,7 +1407,7 @@ class Ops_Array(wx.Frame):
1392
1407
 
1393
1408
  bSizer17.Add(self.CurActiveparent, 0, wx.EXPAND)
1394
1409
 
1395
- self.loadvec = wx.Button(self.selection, wx.ID_ANY, _("Read from file..."), wx.DefaultPosition, wx.DefaultSize,
1410
+ self.loadvec = wx.Button(self.selection, wx.ID_ANY, _("Load from file..."), wx.DefaultPosition, wx.DefaultSize,
1396
1411
  0)
1397
1412
  self.loadvec.SetToolTip(_("Load a vector file into the vector manager"))
1398
1413
  bSizer17.Add(self.loadvec, 0, wx.EXPAND)
@@ -1539,6 +1554,9 @@ class Ops_Array(wx.Frame):
1539
1554
  self.MoveSelection.Bind(wx.EVT_BUTTON, self.OnMoveSelect)
1540
1555
  self.ResetSelection.Bind(wx.EVT_BUTTON, self.OnResetSelect)
1541
1556
  self.ResetAllSelection.Bind(wx.EVT_BUTTON, self.OnResetAllSelect)
1557
+ self.to_clipboard_str.Bind(wx.EVT_BUTTON, self.OnToClipboardStr)
1558
+ self.to_clipboard_script.Bind(wx.EVT_BUTTON, self.OnToClipboardStr)
1559
+
1542
1560
  self.m_button2.Bind(wx.EVT_BUTTON, self.OnManageVectors)
1543
1561
  self.loadvec.Bind(wx.EVT_BUTTON, self.OnLoadvec)
1544
1562
  self.saveas.Bind(wx.EVT_BUTTON, self.OnSaveasvec)
@@ -1811,6 +1829,72 @@ class Ops_Array(wx.Frame):
1811
1829
  self.reset_all_selection()
1812
1830
  self.refresh_array()
1813
1831
 
1832
+ def OnToClipboardStr(self, event):
1833
+ """
1834
+ Copy the current selection to the clipboard as a string
1835
+ """
1836
+
1837
+ if event.GetId() == self.to_clipboard_str.GetId():
1838
+ whichtype = 'string'
1839
+ elif event.GetId() == self.to_clipboard_script.GetId():
1840
+ whichtype = 'script'
1841
+
1842
+ if self.parentarray.mngselection is not None:
1843
+
1844
+ selectobj = self.parentarray.mngselection
1845
+
1846
+ if len(selectobj.selections) > 0:
1847
+ choices = [_("Current selection")]
1848
+ for cur in selectobj.selections.items():
1849
+ choices.append(cur[0])
1850
+
1851
+ dlg = wx.MultiChoiceDialog(None, "Choose the selection to copy", "Choices", choices)
1852
+ ret = dlg.ShowModal()
1853
+ if ret == wx.ID_CANCEL:
1854
+ dlg.Destroy()
1855
+ return
1856
+
1857
+ sel = dlg.GetSelections()
1858
+ dlg.Destroy()
1859
+
1860
+ else:
1861
+ sel = [0]
1862
+
1863
+ if len(sel) == 0:
1864
+ return
1865
+ elif len(sel) == 1:
1866
+ sel = int(sel[0])
1867
+
1868
+ if sel == 0:
1869
+ sel = None
1870
+ else:
1871
+ sel =choices[sel]
1872
+
1873
+ self.parentarray.mngselection.copy_to_clipboard(which = sel, typestr=whichtype)
1874
+
1875
+ else:
1876
+ txt = ''
1877
+ for cursel in sel:
1878
+ if cursel == 0:
1879
+ cursel = None
1880
+ else:
1881
+ cursel = choices[cursel]
1882
+
1883
+ if whichtype == 'script':
1884
+ txt += self.parentarray.mngselection.get_script(which = cursel)
1885
+ else:
1886
+ txt += self.parentarray.mngselection.get_string(which = cursel)
1887
+
1888
+ txt += '\n'
1889
+
1890
+ if wx.TheClipboard.Open():
1891
+ wx.TheClipboard.Clear()
1892
+ wx.TheClipboard.SetData(wx.TextDataObject(txt))
1893
+ wx.TheClipboard.Close()
1894
+
1895
+ else:
1896
+ logging.error('Error in OnToClipboardStr')
1897
+
1814
1898
  def OnApplyOpSelect(self, event):
1815
1899
  """ Select nodes based on condition """
1816
1900
 
@@ -1925,6 +2009,7 @@ class Ops_Array(wx.Frame):
1925
2009
  if curViewer.link_shareopsvect:
1926
2010
  curViewer.active_array.myops.myzones = self.myzones
1927
2011
  curViewer.active_array.myops.fnsave = self.fnsave
2012
+ self.mapviewer.Refresh()
1928
2013
 
1929
2014
  def OnSaveasvec(self, event:wx.MouseEvent):
1930
2015
  """ Save vector file """
@@ -1990,6 +2075,10 @@ class Ops_Array(wx.Frame):
1990
2075
  logging.warning(_('Please select an active vector !'))
1991
2076
  return
1992
2077
 
2078
+ if self.active_vector.nbvertices == 0:
2079
+ logging.warning(_('Please add points to vector or select another !'))
2080
+ return
2081
+
1993
2082
  self._select_vector_inside_manager(self.active_vector)
1994
2083
  self.refresh_array()
1995
2084
 
@@ -2314,6 +2403,8 @@ class SelectionData():
2314
2403
  self.parent: WolfArray
2315
2404
  self.parent = parent
2316
2405
 
2406
+ self.wx_exists = wx.GetApp() is not None
2407
+
2317
2408
  #copy of the resolution
2318
2409
  self.dx = parent.dx
2319
2410
  self.dy = parent.dy
@@ -2325,15 +2416,89 @@ class SelectionData():
2325
2416
  self.hideselection = False
2326
2417
  self.numlist_select = 0 # OpenGL list index
2327
2418
 
2419
+ def get_string(self, which:str = None) -> str:
2420
+ """ Get string of the current selection or of a stored one """
2421
+
2422
+ if which is None:
2423
+ curlist = self.myselection
2424
+ txt = 'X\tY'
2425
+ else:
2426
+ if str(which) in self.selections:
2427
+ curlist = self.selections[str(which)]['select']
2428
+ txt = 'Selection {}\n'.format(which) + 'X\tY\n'
2429
+ else:
2430
+ logging.error(_('Selection {} does not exist').format(which))
2431
+ return ''
2432
+
2433
+ for cur in curlist:
2434
+ txt += str(cur[0]) + '\t' + str(cur[1]) + '\n'
2435
+
2436
+ txt += 'i\tj\t1-based indices\n'
2437
+ for cur in curlist:
2438
+ i,j = self.parent.get_ij_from_xy(cur[0], cur[1], aswolf=True)
2439
+ txt += str(i) + '\t' + str(j) + '\n'
2440
+
2441
+ return txt
2442
+
2443
+ def get_script(self, which:int = None) -> str:
2444
+ """ Get script of the current selection or of a stored one """
2445
+
2446
+ txt = '# script adapted to a WolfGPU script\n'
2447
+ txt += '# - (i,j) are 1-based for add_boundary_condition -- Do not forget to adapt BC type, value and direction or use BC Manager\n'
2448
+ txt += '# - (i,j) are 0-based for infiltration zones\n\n'
2449
+
2450
+ if which is None:
2451
+ curlist = self.myselection
2452
+ idx = 0
2453
+ else:
2454
+ if str(which) in self.selections:
2455
+ txt += '# Selection {}\n'.format(which)
2456
+ curlist = self.selections[str(which)]['select']
2457
+ idx = which
2458
+ else:
2459
+ logging.error(_('Selection {} does not exist').format(which))
2460
+ return ''
2461
+
2462
+ txt += '# For boundary conditions :\n'
2463
+ for cur in curlist:
2464
+ i,j = self.parent.get_ij_from_xy(cur[0], cur[1], aswolf=True)
2465
+ txt += "simul.add_boundary_condition(i={}, j={}, bc_type=BoundaryConditionsTypes.FROUDE_NORMAL, bc_value=.3, border=Direction.LEFT)".format(i, j) + '\n'
2466
+
2467
+ txt += '\n\n# For infiltration zones :\n'
2468
+ for cur in curlist:
2469
+ i,j = self.parent.get_ij_from_xy(cur[0], cur[1], aswolf=True)
2470
+ txt += "infiltration_zones.array[{},{}]={}".format(i-1, j-1, idx) + '\n'
2471
+
2472
+ txt += '\n\n"""If needed, selection as string :\n'
2473
+ txt += self.get_string(which)
2474
+ txt += '"""\n'
2475
+
2476
+ return txt
2477
+
2478
+ def copy_to_clipboard(self, which:int = None, typestr:Literal['string', 'script'] = 'string'):
2479
+ """ Copy current selection to clipboard """
2480
+ if self.wx_exists:
2481
+ if wx.TheClipboard.Open():
2482
+ wx.TheClipboard.Clear()
2483
+ if typestr == 'string':
2484
+ wx.TheClipboard.SetData(wx.TextDataObject(self.get_string(which)))
2485
+ else:
2486
+ wx.TheClipboard.SetData(wx.TextDataObject(self.get_script(which)))
2487
+
2488
+ wx.TheClipboard.Close()
2489
+ else:
2490
+ logging.warning(_('Cannot open the clipboard'))
2491
+
2492
+
2328
2493
  def move_selectionto(self, idx:str, color:list[float]):
2329
2494
  """
2330
2495
  Transfer current selection to dictionary
2331
2496
 
2332
2497
  :param idx: id/key of the selection
2333
- :param color: color of the selection - list of 3 floats between 0 and 255
2498
+ :param color: color of the selection - list of 4 integers between 0 and 255
2334
2499
  """
2335
2500
 
2336
- assert len(color) == 3, "color must be a list of 3 floats between 0 and 255"
2501
+ assert len(color) == 4, "color must be a list of 4 integers between 0 and 255"
2337
2502
 
2338
2503
  # force idx to be a string
2339
2504
  idtxt = str(idx)
@@ -2440,7 +2605,8 @@ class SelectionData():
2440
2605
  # le but est de ne conserver que les coordonnées des CG de mailles
2441
2606
  i, j = self.parent.get_ij_from_xy(x, y)
2442
2607
 
2443
- if i>=0 and j>=0 and i<self.parent.nbx and j<self.parent.nby:
2608
+ if self.parent.check_bounds_ij(i, j):
2609
+ # if i>=0 and j>=0 and i<self.parent.nbx and j<self.parent.nby:
2444
2610
  self.add_node_to_selectionij(i, j, verif)
2445
2611
 
2446
2612
  def add_nodes_to_selection(self, xy:list[float], verif:bool=True):
@@ -2515,9 +2681,12 @@ class SelectionData():
2515
2681
  sel = [tuple(x[1]) for x in locsort]
2516
2682
 
2517
2683
  # on recherche le premier 1
2518
- idx = counts.index(1)
2519
- # on ne conserve que la portion de liste utile
2520
- self.myselection = sel[idx:]
2684
+ if 1 in counts:
2685
+ idx = counts.index(1)
2686
+ # on ne conserve que la portion de liste utile
2687
+ self.myselection = sel[idx:]
2688
+ else:
2689
+ self.myselection = []
2521
2690
  else:
2522
2691
  self.myselection = np.unique(self.myselection, axis=0)
2523
2692
 
@@ -2531,12 +2700,17 @@ class SelectionData():
2531
2700
  path = mpltPath.Path(myvect.asnparray())
2532
2701
  inside = path.contains_points(mypoints)
2533
2702
 
2534
- if self.parent.myops.selectrestricttomask.IsChecked():
2535
- self.hideselection=True
2703
+ self.hideselection=False
2704
+ if self.parent.myops is not None:
2705
+ if self.parent.myops.selectrestricttomask.IsChecked():
2706
+ self.hideselection=True
2536
2707
 
2537
2708
  self.add_nodes_to_selection(mypoints[np.where(inside)], verif=nbini != 0)
2538
- if self.parent.myops.selectrestricttomask.IsChecked():
2539
- self.condition_select('Mask',0)
2709
+
2710
+ if self.parent.myops is not None:
2711
+ if len(self.myselection) > 0:
2712
+ if self.parent.myops.selectrestricttomask.IsChecked():
2713
+ self.condition_select('Mask',0)
2540
2714
 
2541
2715
  self.hideselection=False
2542
2716
  self.update_nb_nodes_sections()
@@ -2551,13 +2725,14 @@ class SelectionData():
2551
2725
 
2552
2726
  self.add_nodes_to_selectionij(mypoints, verif=nbini != 0)
2553
2727
 
2554
- if self.parent.myops.selectrestricttomask.IsChecked():
2555
- self.condition_select('Mask',0)
2728
+ if self.parent.myops is not None:
2729
+ if self.parent.myops.selectrestricttomask.IsChecked():
2730
+ self.condition_select('Mask',0)
2556
2731
 
2557
2732
  self.update_nb_nodes_sections()
2558
2733
 
2559
2734
  def update_nb_nodes_sections(self):
2560
-
2735
+ """ Update the number of selected nodes """
2561
2736
  if self.myselection=='all':
2562
2737
  nb = self.parent.nbnotnull
2563
2738
  else:
@@ -2579,12 +2754,13 @@ class SelectionData():
2579
2754
  else:
2580
2755
  self.update_plot_selection = True
2581
2756
 
2582
- self.parent.myops.nbselect.SetLabelText(str(nb))
2583
- if nb>0:
2584
- self.parent.myops.minx.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 0])))
2585
- self.parent.myops.miny.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 1])))
2586
- self.parent.myops.maxx.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 0])))
2587
- self.parent.myops.maxy.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 1])))
2757
+ if self.parent.myops is not None:
2758
+ self.parent.myops.nbselect.SetLabelText(str(nb))
2759
+ if nb>0:
2760
+ self.parent.myops.minx.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 0])))
2761
+ self.parent.myops.miny.SetLabelText(str(np.min(np.asarray(self.myselection)[:, 1])))
2762
+ self.parent.myops.maxx.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 0])))
2763
+ self.parent.myops.maxy.SetLabelText(str(np.max(np.asarray(self.myselection)[:, 1])))
2588
2764
 
2589
2765
  def condition_select(self, cond, condval, condval2=0, usemask=False):
2590
2766
  array = self.parent.array
@@ -2616,145 +2792,161 @@ class SelectionData():
2616
2792
  if usemask :
2617
2793
  mask=np.logical_not(array.mask)
2618
2794
  if nbini == 0:
2619
- if cond == 0 or cond=='<':
2620
- # <
2621
- ij = np.argwhere((array < condval) & mask)
2622
- elif cond == 1 or cond=='<=':
2623
- # <=
2624
- ij = np.argwhere((array <= condval) & mask)
2625
- elif cond == 2 or cond=='==':
2626
- # ==
2627
- ij = np.argwhere((array == condval) & mask)
2628
- elif cond == 3 or cond=='>=':
2629
- # >=
2630
- ij = np.argwhere((array >= condval) & mask)
2631
- elif cond == 4 or cond=='>':
2632
- # >
2633
- ij = np.argwhere((array > condval) & mask)
2634
- elif cond == 5 or cond=='NaN':
2635
- # NaN
2636
- ij = np.argwhere((np.isnan(array)) & mask)
2637
- elif cond == 6 or cond=='>=<=':
2638
- # interval with equality
2639
- ij = np.argwhere(((array>=condval) & (array<=condval2)) & mask)
2640
- elif cond == 7 or cond=='><':
2641
- # interval without equality
2642
- ij = np.argwhere(((array>condval) & (array<condval2)) & mask)
2643
- elif cond == 8 or cond=='<>':
2644
- # interval without equality
2645
- ij = np.argwhere(((array<condval) | (array>condval2)) & mask)
2646
-
2647
- self.add_nodes_to_selectionij(ij, nbini != 0)
2795
+ try:
2796
+ if cond == 0 or cond=='<':
2797
+ # <
2798
+ ij = np.argwhere((array < condval) & mask)
2799
+ elif cond == 1 or cond=='<=':
2800
+ # <=
2801
+ ij = np.argwhere((array <= condval) & mask)
2802
+ elif cond == 2 or cond=='==':
2803
+ # ==
2804
+ ij = np.argwhere((array == condval) & mask)
2805
+ elif cond == 3 or cond=='>=':
2806
+ # >=
2807
+ ij = np.argwhere((array >= condval) & mask)
2808
+ elif cond == 4 or cond=='>':
2809
+ # >
2810
+ ij = np.argwhere((array > condval) & mask)
2811
+ elif cond == 5 or cond=='NaN':
2812
+ # NaN
2813
+ ij = np.argwhere((np.isnan(array)) & mask)
2814
+ elif cond == 6 or cond=='>=<=':
2815
+ # interval with equality
2816
+ ij = np.argwhere(((array>=condval) & (array<=condval2)) & mask)
2817
+ elif cond == 7 or cond=='><':
2818
+ # interval without equality
2819
+ ij = np.argwhere(((array>condval) & (array<condval2)) & mask)
2820
+ elif cond == 8 or cond=='<>':
2821
+ # interval without equality
2822
+ ij = np.argwhere(((array<condval) | (array>condval2)) & mask)
2823
+
2824
+ self.add_nodes_to_selectionij(ij, nbini != 0)
2825
+ except:
2826
+ logging.error(_('Error in condition_select -- nbini == 0 ! -- Please report this bug, specifying the context'))
2827
+ return
2648
2828
  else:
2649
- sel = np.asarray(self.myselection)
2650
- ijall = np.asarray(self.parent.get_ij_from_xy(sel[:, 0], sel[:, 1])).transpose()
2651
- if cond == 0 or cond=='<':
2652
- # <
2653
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] < condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2654
- elif cond == 1 or cond=='<=':
2655
- # <=
2656
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] <= condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2657
- elif cond == 2 or cond=='==':
2658
- # ==
2659
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] == condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2660
- elif cond == 3 or cond=='>=':
2661
- # >=
2662
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] >= condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2663
- elif cond == 4 or cond=='>':
2664
- # >
2665
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] > condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2666
- elif cond == 5 or cond=='NaN':
2667
- # NaN
2668
- ij = np.argwhere((np.isnan(array[ijall[:, 0], ijall[:, 1]])) & (mask[ijall[:, 0], ijall[:, 1]]))
2669
- elif cond == 6 or cond=='>=<=':
2670
- # interval with equality
2671
- ij = np.argwhere(((array[ijall[:, 0], ijall[:, 1]]>=condval) & (array[ijall[:, 0], ijall[:, 1]]<=condval2)) & (mask[ijall[:, 0], ijall[:, 1]]))
2672
- elif cond == 7 or cond=='><':
2673
- # interval without equality
2674
- ij = np.argwhere(((array[ijall[:, 0], ijall[:, 1]]>condval) & (array[ijall[:, 0], ijall[:, 1]]<condval2)) & (mask[ijall[:, 0], ijall[:, 1]]))
2675
- elif cond == 8 or cond=='<>':
2676
- # interval without equality
2677
- ij = np.argwhere(((array[ijall[:, 0], ijall[:, 1]]<condval) | (array[ijall[:, 0], ijall[:, 1]]>condval2)) & (mask[ijall[:, 0], ijall[:, 1]]))
2678
-
2679
- ij = ij.flatten()
2680
- self.add_nodes_to_selectionij(ijall[ij], nbini != 0)
2829
+ try:
2830
+ sel = np.asarray(self.myselection)
2831
+ ijall = np.asarray(self.parent.get_ij_from_xy(sel[:, 0], sel[:, 1])).transpose()
2832
+ if cond == 0 or cond=='<':
2833
+ # <
2834
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] < condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2835
+ elif cond == 1 or cond=='<=':
2836
+ # <=
2837
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] <= condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2838
+ elif cond == 2 or cond=='==':
2839
+ # ==
2840
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] == condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2841
+ elif cond == 3 or cond=='>=':
2842
+ # >=
2843
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] >= condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2844
+ elif cond == 4 or cond=='>':
2845
+ # >
2846
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]] > condval) & (mask[ijall[:, 0], ijall[:, 1]]))
2847
+ elif cond == 5 or cond=='NaN':
2848
+ # NaN
2849
+ ij = np.argwhere((np.isnan(array[ijall[:, 0], ijall[:, 1]])) & (mask[ijall[:, 0], ijall[:, 1]]))
2850
+ elif cond == 6 or cond=='>=<=':
2851
+ # interval with equality
2852
+ ij = np.argwhere(((array[ijall[:, 0], ijall[:, 1]]>=condval) & (array[ijall[:, 0], ijall[:, 1]]<=condval2)) & (mask[ijall[:, 0], ijall[:, 1]]))
2853
+ elif cond == 7 or cond=='><':
2854
+ # interval without equality
2855
+ ij = np.argwhere(((array[ijall[:, 0], ijall[:, 1]]>condval) & (array[ijall[:, 0], ijall[:, 1]]<condval2)) & (mask[ijall[:, 0], ijall[:, 1]]))
2856
+ elif cond == 8 or cond=='<>':
2857
+ # interval without equality
2858
+ ij = np.argwhere(((array[ijall[:, 0], ijall[:, 1]]<condval) | (array[ijall[:, 0], ijall[:, 1]]>condval2)) & (mask[ijall[:, 0], ijall[:, 1]]))
2859
+
2860
+ ij = ij.flatten()
2861
+ self.add_nodes_to_selectionij(ijall[ij], nbini != 0)
2862
+ except:
2863
+ logging.error(_('Error in condition_select ! -- Please report this bug, specifying the context'))
2864
+ return
2681
2865
  else:
2682
2866
  if nbini == 0:
2683
- if cond == 0 or cond=='<':
2684
- # <
2685
- ij = np.argwhere(array < condval)
2686
- elif cond == 1 or cond=='<=':
2687
- # <=
2688
- ij = np.argwhere(array <= condval)
2689
- elif cond == 2 or cond=='==':
2690
- # ==
2691
- ij = np.argwhere(array == condval)
2692
- elif cond == 3 or cond=='>=':
2693
- # >=
2694
- ij = np.argwhere(array >= condval)
2695
- elif cond == 4 or cond=='>':
2696
- # >
2697
- ij = np.argwhere(array > condval)
2698
- elif cond == 5 or cond=='NaN':
2699
- # NaN
2700
- ij = np.argwhere(np.isnan(array))
2701
- elif cond == 6 or cond=='>=<=':
2702
- # interval with equality
2703
- ij = np.argwhere((array>=condval) & (array<=condval2))
2704
- elif cond == 7 or cond=='><':
2705
- # interval without equality
2706
- ij = np.argwhere((array>condval) & (array<condval2))
2707
- elif cond == 8 or cond=='<>':
2708
- # interval without equality
2709
- ij = np.argwhere((array<condval) | (array>condval2))
2710
- elif cond == -1 or cond=='Mask':
2711
- # Mask
2712
- ij = np.argwhere(array.mask)
2713
- elif cond == -2 or cond=='NotMask':
2714
- # Mask
2715
- ij = np.argwhere(np.logical_not(array.mask))
2716
-
2717
- self.add_nodes_to_selectionij(ij, nbini != 0)
2867
+ try:
2868
+ if cond == 0 or cond=='<':
2869
+ # <
2870
+ ij = np.argwhere(array < condval)
2871
+ elif cond == 1 or cond=='<=':
2872
+ # <=
2873
+ ij = np.argwhere(array <= condval)
2874
+ elif cond == 2 or cond=='==':
2875
+ # ==
2876
+ ij = np.argwhere(array == condval)
2877
+ elif cond == 3 or cond=='>=':
2878
+ # >=
2879
+ ij = np.argwhere(array >= condval)
2880
+ elif cond == 4 or cond=='>':
2881
+ # >
2882
+ ij = np.argwhere(array > condval)
2883
+ elif cond == 5 or cond=='NaN':
2884
+ # NaN
2885
+ ij = np.argwhere(np.isnan(array))
2886
+ elif cond == 6 or cond=='>=<=':
2887
+ # interval with equality
2888
+ ij = np.argwhere((array>=condval) & (array<=condval2))
2889
+ elif cond == 7 or cond=='><':
2890
+ # interval without equality
2891
+ ij = np.argwhere((array>condval) & (array<condval2))
2892
+ elif cond == 8 or cond=='<>':
2893
+ # interval without equality
2894
+ ij = np.argwhere((array<condval) | (array>condval2))
2895
+ elif cond == -1 or cond=='Mask':
2896
+ # Mask
2897
+ ij = np.argwhere(array.mask)
2898
+ elif cond == -2 or cond=='NotMask':
2899
+ # Mask
2900
+ ij = np.argwhere(np.logical_not(array.mask))
2901
+
2902
+ self.add_nodes_to_selectionij(ij, nbini != 0)
2903
+ except:
2904
+ logging.error(_('Error in condition_select -- nbini == 0 ! -- Please report this bug, specifying the context'))
2905
+ return
2718
2906
  else:
2719
- sel = np.asarray(self.myselection)
2720
- ijall = np.asarray(self.parent.get_ij_from_xy(sel[:, 0], sel[:, 1])).transpose()
2721
-
2722
- if cond == 0 or cond=='<':
2723
- # <
2724
- ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] < condval)
2725
- elif cond == 1 or cond=='<=':
2726
- # <=
2727
- ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] <= condval)
2728
- elif cond == 2 or cond=='==':
2729
- # ==
2730
- ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] == condval)
2731
- elif cond == 3 or cond=='>=':
2732
- # >=
2733
- ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] >= condval)
2734
- elif cond == 4 or cond=='>':
2735
- # >
2736
- ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] > condval)
2737
- elif cond == 5 or cond=='NaN':
2738
- # NaN
2739
- ij = np.argwhere(np.isnan(array[ijall[:, 0], ijall[:, 1]]))
2740
- elif cond == 6 or cond=='>=<=':
2741
- # interval with equality
2742
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]]>=condval) & (array[ijall[:, 0], ijall[:, 1]]<=condval2))
2743
- elif cond == 7 or cond=='><':
2744
- # interval without equality
2745
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]]>condval) & (array[ijall[:, 0], ijall[:, 1]]<condval2))
2746
- elif cond == 8 or cond=='<>':
2747
- # interval without equality
2748
- ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]]<condval) | (array[ijall[:, 0], ijall[:, 1]]>condval2) )
2749
- elif cond == -1 or cond=='Mask':
2750
- # Mask
2751
- ij = np.argwhere(array.mask[ijall[:, 0], ijall[:, 1]])
2752
- elif cond == -2 or cond=='NotMask':
2753
- # Mask
2754
- ij = np.argwhere(np.logical_not(array.mask[ijall[:, 0], ijall[:, 1]]))
2755
-
2756
- ij = ij.flatten()
2757
- self.add_nodes_to_selectionij(ijall[ij], nbini != 0)
2907
+ try:
2908
+ sel = np.asarray(self.myselection)
2909
+ ijall = np.asarray(self.parent.get_ij_from_xy(sel[:, 0], sel[:, 1])).transpose()
2910
+
2911
+ if cond == 0 or cond=='<':
2912
+ # <
2913
+ ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] < condval)
2914
+ elif cond == 1 or cond=='<=':
2915
+ # <=
2916
+ ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] <= condval)
2917
+ elif cond == 2 or cond=='==':
2918
+ # ==
2919
+ ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] == condval)
2920
+ elif cond == 3 or cond=='>=':
2921
+ # >=
2922
+ ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] >= condval)
2923
+ elif cond == 4 or cond=='>':
2924
+ # >
2925
+ ij = np.argwhere(array[ijall[:, 0], ijall[:, 1]] > condval)
2926
+ elif cond == 5 or cond=='NaN':
2927
+ # NaN
2928
+ ij = np.argwhere(np.isnan(array[ijall[:, 0], ijall[:, 1]]))
2929
+ elif cond == 6 or cond=='>=<=':
2930
+ # interval with equality
2931
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]]>=condval) & (array[ijall[:, 0], ijall[:, 1]]<=condval2))
2932
+ elif cond == 7 or cond=='><':
2933
+ # interval without equality
2934
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]]>condval) & (array[ijall[:, 0], ijall[:, 1]]<condval2))
2935
+ elif cond == 8 or cond=='<>':
2936
+ # interval without equality
2937
+ ij = np.argwhere((array[ijall[:, 0], ijall[:, 1]]<condval) | (array[ijall[:, 0], ijall[:, 1]]>condval2) )
2938
+ elif cond == -1 or cond=='Mask':
2939
+ # Mask
2940
+ ij = np.argwhere(array.mask[ijall[:, 0], ijall[:, 1]])
2941
+ elif cond == -2 or cond=='NotMask':
2942
+ # Mask
2943
+ ij = np.argwhere(np.logical_not(array.mask[ijall[:, 0], ijall[:, 1]]))
2944
+
2945
+ ij = ij.flatten()
2946
+ self.add_nodes_to_selectionij(ijall[ij], nbini != 0)
2947
+ except:
2948
+ logging.error(_('Error in condition_select ! -- Please report this bug, specifying the context'))
2949
+ return
2758
2950
 
2759
2951
  self.update_nb_nodes_sections()
2760
2952
 
@@ -3248,6 +3440,16 @@ class WolfArray(Element_To_Draw, header_wolf):
3248
3440
 
3249
3441
  self.add_ops_sel() # Ajout d'un gestionnaire de sélection et d'opérations
3250
3442
 
3443
+
3444
+ def check_bounds_ij(self, i:int, j:int):
3445
+ """Check if i and j are inside the array bounds"""
3446
+ return i>=0 and j>=0 and i<self.nbx and j<self.nby
3447
+
3448
+ def check_bounds_xy(self, x:float, y:float):
3449
+ """Check if i and j are inside the array bounds"""
3450
+ i,j = self.get_ij_from_xy(x,y)
3451
+ return self.check_bounds_ij(i,j)
3452
+
3251
3453
  def show_properties(self):
3252
3454
  """ Affichage des propriétés de la matrice dans une fenêtre wxPython """
3253
3455
  if self.wx_exists and self.myops is not None:
@@ -3322,6 +3524,15 @@ class WolfArray(Element_To_Draw, header_wolf):
3322
3524
  - mask data outisde linkedvec
3323
3525
  """
3324
3526
  self.array[np.where(self.array<eps)] = 0.
3527
+
3528
+ idx_nan = np.where(np.isnan(self.array))
3529
+ if len(idx_nan[0])>0:
3530
+ self.array[idx_nan] = 0.
3531
+ self.array.mask[idx_nan] = True
3532
+ logging.warning(_('NaN values found in the array'))
3533
+ for i,j in zip(idx_nan[0],idx_nan[1]):
3534
+ logging.warning(f'NaN at {i+1},{j+1} -- 1-based')
3535
+
3325
3536
  if self.linkedvec is not None:
3326
3537
  self.mask_outsidepoly(self.linkedvec)
3327
3538
 
@@ -5491,7 +5702,6 @@ class WolfArray(Element_To_Draw, header_wolf):
5491
5702
 
5492
5703
  self.plotting = False
5493
5704
 
5494
- # glFinish()
5495
5705
  # Plot selected nodes
5496
5706
  if self.mngselection is not None:
5497
5707
  self.mngselection.plot_selection()
@@ -5503,7 +5713,7 @@ class WolfArray(Element_To_Draw, header_wolf):
5503
5713
  def delete_lists(self):
5504
5714
  """ Delete OpenGL lists """
5505
5715
 
5506
- logging.info(_('OpenGL lists - deletion -- array {}'.format(self.idx)))
5716
+ logging.debug(_('OpenGL lists - deletion -- array {}'.format(self.idx)))
5507
5717
  for idx, cursize in enumerate(self.mygrid):
5508
5718
  curlist = self.mygrid[cursize]
5509
5719
  nbx = curlist['nbx']
@@ -5828,6 +6038,18 @@ class WolfArrayMB(WolfArray):
5828
6038
  super().__init__(fname, mold, masknull, crop, whichtype, preload, create, mapviewer, nullvalue, srcheader)
5829
6039
  # self.wolftype = whichtype
5830
6040
 
6041
+ def check_bounds_ij(self, i:int, j:int):
6042
+ """Check if i and j are inside the array bounds"""
6043
+ x,y = self.get_xy_from_ij(i,j)
6044
+ return self.check_bounds_xy(x,y)
6045
+
6046
+ def check_bounds_xy(self, x:float, y:float):
6047
+ """Check if i and j are inside the array bounds"""
6048
+
6049
+ xmin, xmax, ymin, ymax = self.get_bounds()
6050
+
6051
+ return x>=xmin and x<=xmax and y>=ymin and y<=ymax
6052
+
5831
6053
  def __getitem__(self, block_key:Union[int,str]) -> WolfArray:
5832
6054
  """Access a block of this multi-blocks array."""
5833
6055
  if isinstance(block_key,int):