PaIRS-UniNa 0.2.3__cp312-cp312-macosx_10_9_universal2.whl → 0.2.5__cp312-cp312-macosx_10_9_universal2.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.

Potentially problematic release.


This version of PaIRS-UniNa might be problematic. Click here for more details.

Files changed (53) hide show
  1. PaIRS_UniNa/Changes.txt +50 -6
  2. PaIRS_UniNa/Custom_Top.py +1 -1
  3. PaIRS_UniNa/Explorer.py +70 -42
  4. PaIRS_UniNa/Input_Tab.py +17 -5
  5. PaIRS_UniNa/Input_Tab_CalVi.py +1 -0
  6. PaIRS_UniNa/Input_Tab_tools.py +85 -40
  7. PaIRS_UniNa/Output_Tab.py +110 -17
  8. PaIRS_UniNa/PaIRS_PIV.py +56 -1
  9. PaIRS_UniNa/PaIRS_pypacks.py +148 -9
  10. PaIRS_UniNa/Process_Tab.py +6 -11
  11. PaIRS_UniNa/Process_Tab_Disp.py +11 -4
  12. PaIRS_UniNa/TabTools.py +121 -42
  13. PaIRS_UniNa/Vis_Tab.py +423 -126
  14. PaIRS_UniNa/Vis_Tab_CalVi.py +23 -5
  15. PaIRS_UniNa/Whatsnew.py +15 -6
  16. PaIRS_UniNa/_PaIRS_PIV.so +0 -0
  17. PaIRS_UniNa/__init__.py +2 -2
  18. PaIRS_UniNa/addwidgets_ps.py +50 -39
  19. PaIRS_UniNa/gPaIRS.py +500 -148
  20. PaIRS_UniNa/icons/bugfix.png +0 -0
  21. PaIRS_UniNa/icons/pylog.png +0 -0
  22. PaIRS_UniNa/icons/python_warning.png +0 -0
  23. PaIRS_UniNa/icons/queue.png +0 -0
  24. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  25. PaIRS_UniNa/icons/star.png +0 -0
  26. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  27. PaIRS_UniNa/icons/uninitialized.png +0 -0
  28. PaIRS_UniNa/icons/window.png +0 -0
  29. PaIRS_UniNa/parForMulti.py +7 -5
  30. PaIRS_UniNa/parForWorkers.py +101 -124
  31. PaIRS_UniNa/pivParFor.py +2 -2
  32. PaIRS_UniNa/preProcParFor.py +4 -4
  33. PaIRS_UniNa/procTools.py +25 -13
  34. PaIRS_UniNa/rqrdpckgs.txt +8 -0
  35. PaIRS_UniNa/stereoPivParFor.py +2 -2
  36. PaIRS_UniNa/tabSplitter.py +4 -2
  37. PaIRS_UniNa/ui_Log_Tab.py +8 -6
  38. PaIRS_UniNa/ui_Output_Tab.py +6 -3
  39. PaIRS_UniNa/ui_Process_Tab.py +19 -19
  40. PaIRS_UniNa/ui_Process_Tab_Disp.py +173 -2
  41. PaIRS_UniNa/ui_Vis_Tab.py +331 -195
  42. PaIRS_UniNa/ui_gPairs.py +81 -39
  43. PaIRS_UniNa/ui_infoPaIRS.py +128 -6
  44. PaIRS_UniNa/whatsnew.txt +6 -7
  45. {PaIRS_UniNa-0.2.3.dist-info → pairs_unina-0.2.5.dist-info}/METADATA +39 -23
  46. {PaIRS_UniNa-0.2.3.dist-info → pairs_unina-0.2.5.dist-info}/RECORD +48 -44
  47. {PaIRS_UniNa-0.2.3.dist-info → pairs_unina-0.2.5.dist-info}/WHEEL +1 -1
  48. PaIRS_UniNa/icons/order.png +0 -0
  49. PaIRS_UniNa/icons/order_reverse.png +0 -0
  50. PaIRS_UniNa/icons/pencil_bw.png +0 -0
  51. PaIRS_UniNa/icons/run_piv.png +0 -0
  52. PaIRS_UniNa-0.2.3.dist-info/LICENSE +0 -19
  53. {PaIRS_UniNa-0.2.3.dist-info → pairs_unina-0.2.5.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/Changes.txt CHANGED
@@ -1,11 +1,55 @@
1
- ********* Changes to version 0.2.2 (0.2.3 - 2024.11.06) **********
1
+ ********* Changes in version 0.2.5 (2025.07.18) **********
2
+ Bug fixes:
3
+ - fixed bugs in launching PIV and stereoscopic PIV processes in special cases;
4
+ - fixed tooltip crash introduced by PySide 6.9;
5
+ - corrected package import errors and context menu bugs;
6
+ - resolved multiple visual glitches in image tree selection and map visualization.
7
+
8
+ New features:
9
+ - implemented version control of required Python packages with automatic compatibility check and warning;
10
+ - disparity maps are now automatically saved in the output folder and can be visualized in Vis;
11
+ - added support for restricting view in Vis based on interrogation window size and shifting the view window interactively.
12
+
13
+ User-interface enhancements:
14
+ - redesigned the execution logic of internal workers for improved control and robustness;
15
+ - improved formatting and display of coordinates and variable values when moving the cursor during map visualization;
16
+ - updated button labels and layout for clarity and consistency.
17
+
18
+ Distribution:
19
+ - Support for Python 3.9 has been discontinued;
20
+ - Python 3.13 builds have been successfully created and tested.
21
+
22
+
23
+
24
+ ********* Changes in version 0.2.4 (2024.12.01) **********
25
+ Bug fixes:
26
+ - fixed critical bugs in process handling and calibration step (CalVi usage, closing PaIRS during CalVi operation, resetting steps while running);
27
+ - resolved issues with velocity field visualization and stereo-PIV streamline representation;
28
+ - fixed undo/redo functionality, image tree selection issues, logging errors and focus-out signal handling.
29
+
30
+ New features:
31
+ - extended Vis features, including reference frame system plotting and vorticity field visualization;
32
+ - introduced the ability to copy input and output information from other steps within the same process;
33
+ - introduced functionality to interrupt processing before it starts if issues are detected.
34
+
35
+ Performance improvements:
36
+ - optimized thread usage and resource management for PIV and stereo-PIV;
37
+ - streamlined process workflows, including faster and more reliable parameter updates.
38
+
39
+ User-interface enhancements:
40
+ - updated the CalVi Stop button to function as Save and improved its conditional display;
41
+ - improved handling of project/process information and added better feedback for user actions.
42
+
43
+
44
+
45
+ ********* Changes in version 0.2.3 (2024.11.06) **********
2
46
  - Fixed bug in the functionality for replicating processes with changed input folders introduced in version v0.2.2.
3
47
 
4
48
  - Fixed bug in the compatibility check for the common region in disparity and stereoscopic PIV analysis steps.
5
49
 
6
50
 
7
51
 
8
- ********* Changes to version 0.2.1 (0.2.2 - 2024.10.15) **********
52
+ ********* Changes in version 0.2.2 (2024.10.15) **********
9
53
  - [!!! Critical !!!] Fixed critical errors in the calculation of Reynolds stresses for stereoscopic PIV processes. Please consider reviewing the results from processes executed with version 0.2.1, as the w'w', u'w', and v'w' stresses were incorrectly calculated.
10
54
 
11
55
  - Introduced the "Laser Equation Plane" box in the Output tab to specify the initial attempt in the disparity step or to independently assign the constant values of the laser plane during the stereoscopic PIV step.
@@ -20,7 +64,7 @@
20
64
 
21
65
 
22
66
 
23
- ********* Changes to version 0.1.13 (0.2.1 - 2024.07.08) **********
67
+ ********* Changes in version 0.2.1 (2024.07.08) **********
24
68
  - Fixed bugs for Python 3.11 and 3.12.
25
69
 
26
70
  - Fixed bugs related to use of historical minimum background image in disparity and image analysis steps.
@@ -29,7 +73,7 @@
29
73
 
30
74
 
31
75
 
32
- ********** Changes to version 0.1.13 (0.2.0 - 2024.07.03) **********
76
+ ********** Changes in 0.2.0 (2024.07.03) **********
33
77
  - The latest version of PaIRS marks a departure from its predecessors. PaIRS now boasts a completely redesigned interface aimed at quick, simple, and efficient usability. Users bid farewell to Past, Present, and Future trees in favor of a new, more intuitive process management system (the Explorer): processes are organized into groups called projects and each project or process can be queued for later execution. Processes within each project can be modified until they are launched, and if necessary, reset and restarted from scratch. Each project also features a tree of deleted processes, allowing retrieval of outdated or abandoned processes.
34
78
 
35
79
  - Currently, PaIRS includes four types of processes: preprocessing, PIV (Particle Image Velocimetry), calibration, and stereoscopic PIV. Each of these processes consists of one or more steps, which can be optional or mandatory. Similar to the first version of PaIRS, these steps are editable via PaIRS iconic tabs (Input, Output, Process, etc.). The process tree provides immediate visibility into the status of each step, further streamlining management.
@@ -42,14 +86,14 @@
42
86
 
43
87
 
44
88
 
45
- ********** Changes to version 0.1.12 (0.1.13 - 2024.02.07) **********
89
+ ********** Changes in version 0.1.13 (2024.02.07) **********
46
90
  - Fixed bugs related to navigation across the Past, Present and Future trees in the Queue tab.
47
91
 
48
92
  - Minor changes in Vis.
49
93
 
50
94
 
51
95
 
52
- ********** Changes to version 0.1.11 (0.1.12 - 2024.02.02) **********
96
+ ********** Changes in version 0.1.12 (2024.02.02) **********
53
97
  - PaIRS now includes the possibility to customize the windowing parameters for each iteration of a PIV process. The user can choose the windowing parameters for each iteration in the initial phase of the PIV process. This is possible by operating in the Windowing box at the bottom of the Process tab (visible only in the expert mode). A table widget has been added to this section, where the user can find all relevant information the windowing scheme for the PIV process and modify it iteration by iteration. By selecting the corresponding row of the table, the user can choose for the current iteration the type of weighting window to be used in the calculation of the absolute velocity and in the determination of the correlation map, if using the direct correlations or not and the maximum displacement allowed in the interrogation window. The latter parameter is an innovation of the present version itself and adds to the custom settings selectable by the user to build affordable validation strategies. In addition, in the table an indication about the stability of the windowing scheme for each iteration is reported. In conclusion, a larger degree of customization of the PIV process comes with the present modification of PaIRS.
54
98
 
55
99
  - CalVi now fully supports optical camera calibration for transparent cylindrical geometries. In the version 0.1.10 this camera model was available only in debug mode for beta testers and developers, now it is fully working. The calibration of this camera model is however a delicate task and the user is referred to the CalVi guide for reliable experimental procedures that could be used in this direction.
PaIRS_UniNa/Custom_Top.py CHANGED
@@ -224,7 +224,7 @@ class Custom_Top(QDialog):
224
224
  def loadPastProc(self,*args):
225
225
  if len(args): inpath=args[0]
226
226
  else: inpath='./'
227
- ext_pro=f'*{outExt.min}; *{outExt.piv}; *.cfg'
227
+ ext_pro=f'*{outExt.min} *{outExt.piv} *.cfg'
228
228
  filename, _ = QFileDialog.getOpenFileName(self,\
229
229
  "Select an image file of the sequence", filter=ext_pro,\
230
230
  dir=inpath,\
PaIRS_UniNa/Explorer.py CHANGED
@@ -110,6 +110,7 @@ class TreeIcons():
110
110
  'warning_circle.png': None,
111
111
  'running_warn.png': None,
112
112
  'paused.png': None,
113
+ 'queue.png': None,
113
114
  'warning.png': None,
114
115
  'workspace.png': None,
115
116
  'uninitialized.png':None,
@@ -309,7 +310,7 @@ class ModernSwitch(QWidget):
309
310
  if hasattr(parent,'gui'):
310
311
  self.gui:gPaIRS=parent.gui
311
312
  else:
312
- self.gui:gPaIRS=parent
313
+ self.gui:gPaIRS=parent.window()
313
314
  self.name=name
314
315
  self.par=par
315
316
 
@@ -317,7 +318,7 @@ class ModernSwitch(QWidget):
317
318
  FlagWindowRun=self.gui.FlagRun if hasattr(self.gui,'FlagRun') else False
318
319
  self.setFixedSize(self.switchWidth, self.switchHeight)
319
320
  if par:
320
- self._checked = par.FlagQueue and not FlagWindowRun
321
+ self._checked = par.FlagQueue #and not FlagWindowRun
321
322
  else:
322
323
  self._checked = True
323
324
  par.FlagQueue=self._checked
@@ -353,6 +354,9 @@ class ModernSwitch(QWidget):
353
354
 
354
355
  self.setEnabled(not FlagWindowRun)
355
356
  self.setSwitch(self._checked)
357
+ if par and self.gui.procdata:
358
+ if self.gui.procdata.ind[:-2]==par.ind[:-2]:
359
+ self.startTimer()
356
360
  #self.timer.start(50) # Aggiorna ogni 50 ms
357
361
 
358
362
  def startTimer(self):
@@ -456,8 +460,9 @@ class ModernSwitch(QWidget):
456
460
  self.set_handle_position(self.switchHandlePosition())
457
461
 
458
462
  def setSwitch(self,FlagChecked):
459
- self._checked=FlagChecked
460
- self.setSwitchLayout()
463
+ if FlagChecked!=self._checked:
464
+ self._checked=FlagChecked
465
+ self.setSwitchLayout()
461
466
 
462
467
  class ActionButtonBar(QWidget):
463
468
  FlagShortCuts = True
@@ -472,7 +477,6 @@ class ActionButtonBar(QWidget):
472
477
  self.buttonData=buttonData
473
478
  self.additionalButtonBars=additionalButtonBars
474
479
  self.globalButtons=globalButtons
475
- self.additionalButtonBars={}
476
480
  self.buttonSize = bs = buttonSize
477
481
  self.FlagInvisible=FlagInvisible
478
482
  self.tree:QWidget=None
@@ -878,6 +882,8 @@ class ProjectTree(PaIRSTree):
878
882
 
879
883
  def finishEditing(self, item, column):
880
884
  line_edit = self.itemWidget(item, column)
885
+ if not hasattr(line_edit,'text'):
886
+ return
881
887
  new_text = line_edit.text()
882
888
  k=self.indexOfTopLevelItem(item)
883
889
  TRE:TREpar=self.itemList[0][k]
@@ -944,7 +950,7 @@ class ProjectTree(PaIRSTree):
944
950
  self.editItem(item, 1)
945
951
 
946
952
  def button_info_action(self):
947
- warningDialog(self,self.TREpar.InfoMessage(),pixmap=TreeIcons.pixmaps[self.TREpar.icon])
953
+ warningDialog(self,self.TREpar.InfoMessage(),pixmap=TreeIcons.pixmaps[self.TREpar.icon],title='Project information')
948
954
 
949
955
  def button_new_action(self):
950
956
  item=self.createProjectItem()
@@ -1178,7 +1184,7 @@ class StepButtonBar(QWidget):
1178
1184
  self.buttonLayout.addSpacerItem(QSpacerItem(self.buttonSize[0], 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
1179
1185
 
1180
1186
  def setButtonIcon(self,button:QToolButton):
1181
- if button.isChecked() or not button.isVisible():
1187
+ if button.isChecked(): #or not button.isVisible():
1182
1188
  button.setIcon(button.iconOn)
1183
1189
  else:
1184
1190
  button.setIcon(button.iconOff)
@@ -1391,7 +1397,7 @@ class ProcessTree(PaIRSTree):
1391
1397
  event.setDropAction(Qt.MoveAction)
1392
1398
  event.accept()
1393
1399
  elif event.mimeData().hasFormat('application/x-button') and not self.FlagBin:
1394
- if not self.hovered_item:
1400
+ if not self.hovered_item or self.gui.FlagRun:
1395
1401
  ind=self.topLevelItemCount()
1396
1402
  else:
1397
1403
  ind=self.indexOfTopLevelItem(self.hovered_item)+1
@@ -1632,6 +1638,8 @@ class ProcessTree(PaIRSTree):
1632
1638
 
1633
1639
  def finishEditing(self, item, column):
1634
1640
  line_edit = self.itemWidget(item, column)
1641
+ if not hasattr(line_edit,'text'):
1642
+ return
1635
1643
  new_text = line_edit.text()
1636
1644
  k=self.indexOfTopLevelItem(item)
1637
1645
  data=self.itemList[0][k]
@@ -1673,8 +1681,8 @@ class ProcessTree(PaIRSTree):
1673
1681
  def button_import_action(self):
1674
1682
  exts=[f'*{e}' for e in [outExt.min,outExt.piv,outExt.cal,outExt.spiv]]
1675
1683
  dirname=os.path.dirname(self.TREpar.outName) if self.TREpar.outName else ''
1676
- filename, _ = QFileDialog.getOpenFileName(self,\
1677
- "Select a PaIRS process file", filter=';'.join(exts),\
1684
+ filename, _ = QFileDialog.getOpenFileName(self.gui,\
1685
+ "Select a PaIRS process file", filter=' '.join(exts),\
1678
1686
  dir=dirname,\
1679
1687
  options=optionNativeDialog)
1680
1688
  if not filename: return
@@ -1759,7 +1767,7 @@ class ProcessTree(PaIRSTree):
1759
1767
  self.save_current_process(filename)
1760
1768
 
1761
1769
  def button_info_action(self):
1762
- warningDialog(self,self.ITEpar.InfoMessage(),pixmap=TreeIcons.pixmaps[self.ITEpar.icon])
1770
+ warningDialog(self,self.ITEpar.InfoMessage(),pixmap=TreeIcons.pixmaps[self.ITEpar.icon],title='Process information')
1763
1771
 
1764
1772
  def button_rename_action(self):
1765
1773
  selected_items = self.selectedItems()
@@ -1916,14 +1924,16 @@ class ProcessTree(PaIRSTree):
1916
1924
  ind_master[3]=j
1917
1925
  ind_slave[3]=j
1918
1926
  if opts[j] in (0,2):
1919
- ind_new=self.gui.copy_pars(ind_slave,ind_master,FlagNew=True,FlagSet=False)
1927
+ ind_new=self.gui.copy_pars(ind_slave,ind_master,FlagNew=True)
1928
+ item_child=item.child(j)
1929
+ ITE:ITEpar=self.Explorer.ITEfromInd(ind_new)
1930
+ item_child.setHidden(not ITE.active)
1920
1931
  if opts[j]==2:
1921
1932
  INP: INPpar=self.gui.w_Input.TABpar_at(ind_new)
1922
1933
  INP.path=myStandardPath(path)
1923
1934
  self.gui.w_Input.scanImList(ind_new)
1924
1935
  self.gui.w_Input.checkINPpar(ind_new)
1925
1936
  self.gui.w_Input.setINPwarn(ind_new)
1926
- ITE:ITEpar=self.Explorer.ITEfromInd(ind_new)
1927
1937
  self.Explorer.setITElayout(ITE)
1928
1938
 
1929
1939
  TABname=self.gui.w_Input.TABname
@@ -1973,8 +1983,8 @@ class ProcessTree(PaIRSTree):
1973
1983
  self.actionBar.button_info.setEnabled(FlagEnabled)
1974
1984
  self.actionBar.button_rename.setEnabled(FlagEnabled)
1975
1985
  self.actionBar.button_copy.setEnabled(FlagEnabled)
1976
- self.actionBar.button_paste_below.setEnabled(FlagPaste)
1977
- self.actionBar.button_paste_above.setEnabled(FlagPaste)
1986
+ self.actionBar.button_paste_below.setEnabled(FlagPaste and not self.gui.FlagRun)
1987
+ self.actionBar.button_paste_above.setEnabled(FlagPaste and not self.gui.FlagRun)
1978
1988
  self.actionBar.button_process_loop.setEnabled(FlagEnabled and not self.FlagBin)
1979
1989
  self.actionBar.button_restore.setVisible(self.FlagBin)
1980
1990
  self.actionBar.sep_restore.setVisible(self.FlagBin)
@@ -1989,16 +1999,18 @@ class StepItemWidget(QWidget):
1989
1999
  'warning' : 'warning_circle.png',
1990
2000
  'running_warn' : 'running_warn.png',
1991
2001
  'paused' : 'paused.png',
2002
+ 'queue' : 'queue.png',
1992
2003
  'uninitialized' : 'uninitialized.png'
1993
2004
  }
1994
2005
 
1995
- colors={'error' : 'rgb(254, 61, 61)', #'#C9302C',
2006
+ colors={'error' : 'rgb(254, 61, 61)', #'#C9302C',
1996
2007
  'done' : 'rgb( 46,204,113)', #'#4CAE4C',
1997
2008
  'running' : 'rgb( 48,107,255)', #'#3A70C7',
1998
2009
  'warning' : 'rgb(255,212, 42)', #'#EC971F',
1999
2010
  'running_warn' : 'rgb( 48,107,255)', #'#3A70C7',
2000
2011
  'paused' : 'rgb(255,127, 42)', #'#3A70C7',
2001
- 'uninitialized' : 'rgb( 0,0,0,0)',
2012
+ 'queue' : 'rgb(181,170,255)', #'#B5AAFF',
2013
+ 'uninitialized' : 'rgb( 0,0,0)',
2002
2014
  }
2003
2015
 
2004
2016
  label_size=secondLevelHeight-4
@@ -2013,7 +2025,7 @@ class StepItemWidget(QWidget):
2013
2025
  if hasattr(parent,'gui'):
2014
2026
  self.gui:gPaIRS=parent.gui
2015
2027
  else:
2016
- self.gui:gPaIRS=parent
2028
+ self.gui:gPaIRS=parent.window()
2017
2029
 
2018
2030
  # Create the layout
2019
2031
  layout = QHBoxLayout(self)
@@ -2103,9 +2115,10 @@ class StepItemWidget(QWidget):
2103
2115
  if hasattr(self.gui,'procdata') and self.gui.procdata is ITE.procdata:
2104
2116
  FlagGif=True
2105
2117
  if FlagGif:
2106
- self.label.setPixmap(QPixmap())
2118
+ self.label.moviePixmap=TreeIcons.pixmaps[pixmap_path]
2107
2119
  self.label.setMovie(self.gui.runningMovie)
2108
2120
  else:
2121
+ self.label.moviePixmap=None
2109
2122
  self.label.setPixmap(TreeIcons.pixmaps[pixmap_path])
2110
2123
  self.label.setToolTip(ITE.warningMessage)
2111
2124
  self.label.setStatusTip(ITE.warningMessage)
@@ -2118,12 +2131,14 @@ class StepItemWidget(QWidget):
2118
2131
  elif ITE.Step==StepTypes.disp:
2119
2132
  self.progressBar.setVisible(ITE.procdata.Nit>0)
2120
2133
  self.progressBar.setMaximum(ITE.procdata.Nit)
2121
- self.progressBar.setValue(ITE.procdata.numFinalized)
2134
+ self.progressBar.setValue(ITE.progress)
2135
+ #self.progressBar.setValue(ITE.procdata.numFinalized)
2122
2136
  #self.progressBar.setFormat(f'{ITE.progress}/{ITE.procdata.Nit}')
2123
2137
  else:
2124
2138
  self.progressBar.setVisible(ITE.procdata.nimg>0)
2125
2139
  self.progressBar.setMaximum(ITE.procdata.nimg)
2126
- self.progressBar.setValue(ITE.procdata.numFinalized) # Set the initial value of the progress bar
2140
+ self.progressBar.setValue(ITE.progress)
2141
+ #self.progressBar.setValue(ITE.procdata.numFinalized) # Set the initial value of the progress bar
2127
2142
 
2128
2143
 
2129
2144
  bar_color=StepItemWidget.colors[ITE.label]
@@ -2172,10 +2187,10 @@ class PaIRS_Explorer(gPaIRS_Tab):
2172
2187
  self.processButtonBar = ProcessButtonBar(processData,buttonSize=processButtonSize)
2173
2188
  self.processTree_layout.addWidget(self.processButtonBar)
2174
2189
  self.processTree_layout.addItem(QSpacerItem(0,spa,QSizePolicy.Minimum, QSizePolicy.Minimum))
2175
- self.processActioBar = ActionButtonBar(buttonData=processActionButtons,globalButtons=processGlobalActionButtons,buttonSize=processActionButtonSize)
2176
- self.processTree_layout.addWidget(self.processActioBar)
2177
- self.binActioBar = ActionButtonBar(buttonData=processActionButtons,globalButtons=processGlobalActionButtons,buttonSize=processActionButtonSize)
2178
- self.processTree_layout.addWidget(self.binActioBar)
2190
+ self.processActionBar = ActionButtonBar(buttonData=processActionButtons,globalButtons=processGlobalActionButtons,buttonSize=processActionButtonSize)
2191
+ self.processTree_layout.addWidget(self.processActionBar)
2192
+ self.binActionBar = ActionButtonBar(buttonData=processActionButtons,globalButtons=processGlobalActionButtons,buttonSize=processActionButtonSize)
2193
+ self.processTree_layout.addWidget(self.binActionBar)
2179
2194
 
2180
2195
  self.stepButton_layout=QHBoxLayout()
2181
2196
  self.stepButton_layout.setContentsMargins(0, 0, 0, 0)
@@ -2184,11 +2199,11 @@ class PaIRS_Explorer(gPaIRS_Tab):
2184
2199
  self.stepButtonBar=StepButtonBar(stepData,buttonSize=stepButtonSize)
2185
2200
  self.stepButton_layout.addWidget(self.stepButtonBar)
2186
2201
 
2187
- self.processActioBar.additionalButtonBars={'globals': [self.processButtonBar], 'items': [self.stepButtonBar]}
2188
- self.binActioBar.additionalButtonBars={'items': [self.stepButtonBar]}
2202
+ self.processActionBar.additionalButtonBars={'globals': [self.processButtonBar], 'items': [self.stepButtonBar]}
2203
+ self.binActionBar.additionalButtonBars={'items': [self.stepButtonBar]}
2189
2204
 
2190
- self.processTree = ProcessTree(self,processActionBar=self.processActioBar,widgets=widgets,Explorer=self)
2191
- self.binTree = ProcessTree(self,restoreTree=self.processTree,processActionBar=self.binActioBar,widgets=widgets,Explorer=self)
2205
+ self.processTree = ProcessTree(self,processActionBar=self.processActionBar,widgets=widgets,Explorer=self)
2206
+ self.binTree = ProcessTree(self,restoreTree=self.processTree,processActionBar=self.binActionBar,widgets=widgets,Explorer=self)
2192
2207
  self.processTree.restoreTree=self.binTree
2193
2208
  itemWidths=[
2194
2209
  titleNameWidth+ModernSwitch.switchWidth+6, #first level
@@ -2282,7 +2297,7 @@ class PaIRS_Explorer(gPaIRS_Tab):
2282
2297
 
2283
2298
  #------------------------------------- Declaration of parameters
2284
2299
  self.ITEpar:ITEpar=self.TABpar
2285
- self.ITEpar.FlagNone=True
2300
+ self.ITEpar.FlagNone=False
2286
2301
  self.processTree.ITEpar=self.ITEpar
2287
2302
  self.TREpar=self.projectTree.TREpar
2288
2303
  self.processTree.TREpar=self.projectTree.TREpar
@@ -2444,7 +2459,7 @@ class PaIRS_Explorer(gPaIRS_Tab):
2444
2459
  else:
2445
2460
  child=0
2446
2461
  index=tree.indexOfTopLevelItem(item)
2447
- if index<0:
2462
+ if index<0 or index>len(tree.itemList[0])-1:
2448
2463
  index=None
2449
2464
  return index, child
2450
2465
  ITEs=tree.itemList[0][index]
@@ -2456,17 +2471,23 @@ class PaIRS_Explorer(gPaIRS_Tab):
2456
2471
  self.setProcessFlagRun(ITEs[0].ind)
2457
2472
  if c in ITEs[0].children:
2458
2473
  ind=list(ITEs[0].children).index(c)
2474
+ if c in ITEs[0].mandatory: ITEs[ind+1].active=True
2475
+ if item.childCount()>ind:
2476
+ item_child=item.child(ind)
2477
+ item_child.setHidden(not ITEs[ind+1].active)
2459
2478
  b.setVisible(c not in ITEs[0].mandatory) #b.setVisible(True)
2460
2479
  lab.setVisible(c in ITEs[0].mandatory)
2461
2480
  flagRunnable=all([ITEs[j].flagRun==0 for j in range(ind+2,nsteps+1)]) if ind<nsteps else True
2462
2481
  flagRunnable=flagRunnable and ITEs[ind+1].flagRun==0 and ITEs[0].flagRun!=-2 #and len(ITEs[ind+1].link)==0
2463
2482
  b.setEnabled(flagRunnable)
2483
+ lab.setEnabled(flagRunnable)
2464
2484
  b.setChecked(ITEs[ind+1].active)
2465
2485
  else:
2466
2486
  flagRunnable=False
2467
2487
  b.setVisible(False)
2468
2488
  lab.setVisible(False)
2469
2489
  b.setEnabled(False)
2490
+ lab.setEnabled(False)
2470
2491
  b.setChecked(False)
2471
2492
  b.setButtonIcon()
2472
2493
  if self.stepPage:
@@ -2478,13 +2499,16 @@ class PaIRS_Explorer(gPaIRS_Tab):
2478
2499
  pageButton.setIcon(b.iconOn)
2479
2500
  else:
2480
2501
  self.ITEpar.FlagNone=True
2481
- for c in list(stepData):
2482
- b:QToolButton=self.stepButtonBar.buttons[c]
2483
- lab:QLabel=self.stepButtonBar.labels[c]
2484
- b.setVisible(False)
2485
- lab.setVisible(False)
2502
+ self.hideStepButtons()
2486
2503
  return index, child
2487
2504
 
2505
+ def hideStepButtons(self):
2506
+ for c in list(stepData):
2507
+ b:QToolButton=self.stepButtonBar.buttons[c]
2508
+ lab:QLabel=self.stepButtonBar.labels[c]
2509
+ b.setVisible(False)
2510
+ lab.setVisible(False)
2511
+
2488
2512
  def setProcessFlagRun(self,ind):
2489
2513
  ITEs:ITEpar=self.ITEsfromInd(ind)
2490
2514
  ITEs[0].flagRun=-2 if any([i.flagRun==-2 for i in ITEs[1:] if i.active]) else -1 if any([i.flagRun==-1 for i in ITEs[1:] if i.active]) else 2 if all([i.flagRun==2 for i in ITEs[1:] if i.active]) else 1 if all([i.flagRun>0 for i in ITEs[1:] if i.active]) else 0
@@ -2693,15 +2717,16 @@ class PaIRS_Explorer(gPaIRS_Tab):
2693
2717
  ind=[self.TREpar.project, self.TREpar.tree, self.TREpar.process, self.TREpar.step-1 if self.TREpar.step else -1, -1]
2694
2718
  if self.undoInd and self.undoInd[:-1]!=ind[:-1]:
2695
2719
  self.undoInd[-1]=-1
2696
- self.gui.checkProcesses(FlagInit=True,ind=self.undoInd)
2697
- self.setITElayout(self.ITEfromInd(self.undoInd))
2720
+ if self.gui.checkProcesses(FlagInit=True,ind=self.undoInd):
2721
+ self.setITElayout(self.ITEfromInd(self.undoInd))
2698
2722
  self.undoInd=None
2699
2723
 
2700
2724
  def setITElayout(self,ITE:ITEpar=None):
2701
2725
  if ITE is None:
2702
2726
  FlagCurrentITE=True
2703
2727
  ITE=self.ITEpar
2704
- else: FlagCurrentITE=False
2728
+ else:
2729
+ FlagCurrentITE=False
2705
2730
  if ITE.FlagNone: return
2706
2731
  self.cancelUndo(ITE.ind)
2707
2732
  FlagDone=True
@@ -2762,7 +2787,7 @@ class PaIRS_Explorer(gPaIRS_Tab):
2762
2787
  # return
2763
2788
  #ITE.progress=procdata.numFinalized
2764
2789
  if ITE.flagRun==-2:
2765
- ITE.warningMessage='Process step currently running..'
2790
+ ITE.warningMessage='Process step currently running.'
2766
2791
  ITE.label='running'
2767
2792
  else:
2768
2793
  if not FlagDone:
@@ -2776,8 +2801,11 @@ class PaIRS_Explorer(gPaIRS_Tab):
2776
2801
  ITE.warningMessage='Some errors occured in this process step! See Log for more information.'
2777
2802
  ITE.label='error'
2778
2803
  elif ITE.flagRun==-1:
2779
- ITE.warningMessage='Process step stopped by user..'
2804
+ ITE.warningMessage='Process step stopped by user.'
2780
2805
  ITE.label='paused'
2806
+ elif ITE.flagRun==-10:
2807
+ ITE.warningMessage='Process step in the queue for execution.'
2808
+ ITE.label='queue'
2781
2809
  else:
2782
2810
  ITE.warningMessage='Process step correctly completed! 💪🏻'
2783
2811
  ITE.label='done'
@@ -2922,7 +2950,7 @@ class StartingPage(QFrame):
2922
2950
  button_layout.setContentsMargins(0, self.BUTTON_LAYOUT_TOP_MARGIN, 0, button_margin)
2923
2951
 
2924
2952
  icon_button = QPushButton()
2925
- pixmap = QPixmap(icons_path+process['icon']).scaled(self.ICON_SIZE, self.ICON_SIZE)
2953
+ pixmap = QPixmap(icons_path+process['icon']).scaled(self.ICON_SIZE, self.ICON_SIZE, mode=Qt.TransformationMode.SmoothTransformation)
2926
2954
  icon_button.setIcon(pixmap)
2927
2955
  icon_button.setIconSize(pixmap.size())
2928
2956
  icon_button.setFixedSize(self.ICON_SIZE, self.ICON_SIZE)
PaIRS_UniNa/Input_Tab.py CHANGED
@@ -14,7 +14,7 @@ spin_tips={
14
14
  'frame': 'Current frame number',
15
15
  }
16
16
  check_tips={
17
- 'TR': 'Time-resolved sequence',
17
+ 'TR_Import': 'Time-resolved sequence',
18
18
  }
19
19
  radio_tips={}
20
20
  line_edit_tips={
@@ -323,6 +323,13 @@ class Input_Tab(gPaIRS_Tab):
323
323
  self.layoutExampleImageList()
324
324
  self.ui.button_import.setEnabled(not self.INPpar.FlagImport)
325
325
 
326
+ """
327
+ if self.INPpar.ind[-1]<len(self.TABpar_prev_at(self.INPpar.ind))-1:
328
+ self.ui.imTreeWidget.w_button.setVisible(False)
329
+ else:
330
+ self.ui.imTreeWidget.w_button.setVisible(True)
331
+ """
332
+
326
333
  self.checkINPpar(FlagRescan=False)
327
334
  self.setINPwarn()
328
335
  self.setTABWarnLabel()
@@ -531,6 +538,7 @@ class Input_Tab(gPaIRS_Tab):
531
538
  INPpar.FlagExample=False
532
539
  self.INPpar.imList,self.INPpar.imEx=self.INPpar.imSet.genListsFromFrame(self.INPpar.frame_1,self.INPpar.frame_2,self.INPpar.ind_in,self.INPpar.npairs,self.INPpar.step,self.INPpar.FlagTR_Import)
533
540
  self.INPpar.selection=[1,1,1]
541
+ self.InputAdjustSelection()
534
542
  if self.INPpar.isDifferentFrom(self.INPpar_old,fields=['imList','imEx']):
535
543
  self.INPpar.FlagImport=True
536
544
  self.INPpar.importPar.copyfrom(self.INPpar,exceptions=['name','surname'])
@@ -669,13 +677,17 @@ class Input_Tab(gPaIRS_Tab):
669
677
  w=self.ui.imTreeWidget
670
678
  if w.imTree.FlagSetting: return
671
679
  self.INPpar.selection=[w.spin_img.value(),w.spin_cam.value(),w.spin_frame.value()]
672
- if len(self.TABpar_prev_at(self.INPpar.ind)):
673
- self.TABpar_at(self.INPpar.ind).selection=[w.spin_img.value(),w.spin_cam.value(),w.spin_frame.value()]
680
+ self.InputAdjustSelection()
674
681
  if not TABpar.FlagSettingPar and not self.FlagSettingPar:
675
682
  FlagAdjustPar=True
676
- self.setTABpar_bridge(FlagAdjustPar)
683
+ self.setTABpar_bridge(FlagAdjustPar,FlagCallback=True)
677
684
  return True
678
685
 
686
+ def InputAdjustSelection(self,INP:INPpar=None):
687
+ if INP is None: INP=self.INPpar
688
+ if len(self.TABpar_prev_at(INP.ind)):
689
+ self.TABpar_at(INP.ind).selection=copy.deepcopy(INP.selection)
690
+
679
691
  #******************** Settings
680
692
  def image_list_set(self):
681
693
  FlagNewLists=self.INPpar.isDifferentFrom(self.ui.imTreeWidget.imTree,fields=['imList','imEx'])
@@ -685,7 +697,7 @@ class Input_Tab(gPaIRS_Tab):
685
697
  self.ui.imTreeWidget.imTree.signals.updateLists.connect(self.restoreSignal)
686
698
  self.ui.imTreeWidget.setLists(self.INPpar.path,self.INPpar.imList,self.INPpar.imEx,selection=self.INPpar.selection,FlagOnlyPrepare=not FlagNewLists)
687
699
  if not FlagNewLists: self.restoreSignal()
688
- self.ui.imTreeWidget.imTree.spinSelection(self.INPpar.selection)
700
+ self.ui.imTreeWidget.imTree.spinSelection(self.INPpar.selection)
689
701
 
690
702
  def emptyImTreeInd(self):
691
703
  self.ImTreeInd=[]
@@ -566,6 +566,7 @@ class Input_Tab_CalVi(gPaIRS_Tab):
566
566
  return
567
567
 
568
568
  def adjust_image_sizes(self):
569
+ if not self.INPpar.imageFile or not os.path.exists(self.INPpar.imageFile): return
569
570
  try:
570
571
  im = Image.open(self.INPpar.imageFile)
571
572
  self.INPpar.ext=os.path.splitext(self.INPpar.imageFile)[-1]