PaIRS-UniNa 0.2.5__cp313-cp313-win_amd64.whl → 0.2.9__cp313-cp313-win_amd64.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.
Files changed (42) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +15 -0
  2. PaIRS_UniNa/Changes.txt +54 -2
  3. PaIRS_UniNa/Explorer.py +118 -19
  4. PaIRS_UniNa/FolderLoop.py +196 -6
  5. PaIRS_UniNa/Input_Tab.py +167 -55
  6. PaIRS_UniNa/Input_Tab_CalVi.py +15 -17
  7. PaIRS_UniNa/Input_Tab_tools.py +9 -10
  8. PaIRS_UniNa/Output_Tab.py +2 -4
  9. PaIRS_UniNa/PaIRS_pypacks.py +227 -56
  10. PaIRS_UniNa/Process_Tab.py +2 -2
  11. PaIRS_UniNa/Process_Tab_Disp.py +1 -1
  12. PaIRS_UniNa/SPIVCalHelp.py +155 -0
  13. PaIRS_UniNa/Saving_tools.py +7 -7
  14. PaIRS_UniNa/TabTools.py +7 -4
  15. PaIRS_UniNa/Vis_Tab.py +129 -60
  16. PaIRS_UniNa/Whatsnew.py +15 -3
  17. PaIRS_UniNa/_PaIRS_PIV.pyd +0 -0
  18. PaIRS_UniNa/__init__.py +4 -4
  19. PaIRS_UniNa/addwidgets_ps.py +28 -20
  20. PaIRS_UniNa/calibView.py +7 -0
  21. PaIRS_UniNa/gPaIRS.py +179 -34
  22. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  23. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  24. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  25. PaIRS_UniNa/icons/information.png +0 -0
  26. PaIRS_UniNa/icons/information2.png +0 -0
  27. PaIRS_UniNa/icons/pencil_bw.png +0 -0
  28. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  29. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  30. PaIRS_UniNa/icons/spiv_setup_no.png +0 -0
  31. PaIRS_UniNa/icons/spiv_setup_ok.png +0 -0
  32. PaIRS_UniNa/pivParFor.py +1 -1
  33. PaIRS_UniNa/procTools.py +51 -3
  34. PaIRS_UniNa/rqrdpckgs.txt +6 -5
  35. PaIRS_UniNa/stereoPivParFor.py +1 -1
  36. PaIRS_UniNa/ui_Calibration_Tab.py +90 -57
  37. PaIRS_UniNa/ui_gPairs.py +9 -3
  38. PaIRS_UniNa/whatsnew.txt +4 -4
  39. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.9.dist-info}/METADATA +32 -17
  40. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.9.dist-info}/RECORD +42 -32
  41. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.9.dist-info}/WHEEL +0 -0
  42. {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.9.dist-info}/top_level.txt +0 -0
@@ -143,7 +143,7 @@ def save_list_to_file_serialized(l, filename, flagJSON=False):
143
143
  print(f'Error while saving the file {filename}!\n{e}\n')
144
144
 
145
145
  if pickle_counter:
146
- pri.Info.yellow(f'The following non-json serializable items were found in {filename}:\n'+"\n".join(info_pickle))
146
+ pri.IOError.yellow(f'The following non-json serializable items were found in {filename}:\n'+"\n".join(info_pickle))
147
147
  pickle_filename = basename+'.pairs_data'
148
148
  try:
149
149
  with open(pickle_filename, 'wb') as file:
@@ -177,7 +177,7 @@ def load_list_from_file_serialized(filename):
177
177
  except Exception as e:
178
178
  error=e
179
179
  if error:
180
- print(f'Error while loading the file {filename}!\n{error}\n')
180
+ pri.IOError.red(f'Error while loading the file {filename}!\n{error}\n')
181
181
  return serialized_list, str(error)
182
182
 
183
183
  error=''
@@ -187,7 +187,7 @@ def load_list_from_file_serialized(filename):
187
187
  with open(pickle_filename, 'rb') as file:
188
188
  pickle_data = pickle.load(file)
189
189
  except Exception as e:
190
- print(f'Error while loading the file {pickle_filename}!\n{e}\n')
190
+ pri.IOError.red(f'Error while loading the file {pickle_filename}!\n{e}\n')
191
191
  error+=str(e)
192
192
 
193
193
  info_pickle=[]
@@ -228,7 +228,7 @@ def load_list_from_file_serialized(filename):
228
228
  else:
229
229
  setattr(new_instance,f,v_loaded)
230
230
  except Exception as e:
231
- pri.Error.red(f'Error while reading the file {filename} (setting "{key}" field of {cls_name} item)\n{traceback.format_exc()}\n')
231
+ pri.IOError.red(f'Error while reading the file {filename} (setting "{key}" field of {cls_name} item)\n{traceback.format_exc()}\n')
232
232
  fields[key] = new_instance
233
233
  elif isinstance(value, dict) and '__file_ref__' in value:
234
234
  ref_key = value['__file_ref__']
@@ -253,12 +253,12 @@ def load_list_from_file_serialized(filename):
253
253
  return deserialize_element(lst)
254
254
 
255
255
  if info_pickle:
256
- pri.Info.red(f'The following non-json serializable items were not found in {filename}:\n'+"\n".join(info_pickle))
256
+ pri.IOError.red(f'The following non-json serializable items were not found in {filename}:\n'+"\n".join(info_pickle))
257
257
  l=None
258
258
  try:
259
259
  l=deserialize_list(serialized_list)
260
260
  except Exception as e:
261
- print(f'Error while loading the file {filename}!\n{e}\n{traceback.format_exc()}\n')
261
+ pri.IOError.red(f'Error while loading the file {filename}!\n{e}\n{traceback.format_exc()}\n')
262
262
  error+=str(e)
263
263
  return l, error
264
264
 
@@ -285,7 +285,7 @@ def load_list_from_file(filename):
285
285
  l=pickle.load(file)
286
286
  except Exception as e:
287
287
  errorMessage=f'Error while loading the file {filename}!\n{e}\n'
288
- print(errorMessage)
288
+ pri.IOError.red(errorMessage)
289
289
  return l, errorMessage
290
290
 
291
291
  if FLAG_SERIALIZED:
PaIRS_UniNa/TabTools.py CHANGED
@@ -877,7 +877,10 @@ class gPaIRS_Tab(QWidget):
877
877
  self.button_link_step.setStatusTip(self.button_link_step.toolTip())
878
878
  self.button_link_step.setChecked(len(self.TABpar.link)!=0)
879
879
 
880
- FlagProcessTree=self.gui.ui.Explorer.currentTree==self.gui.ui.Explorer.processTree
880
+ if self.gui.ui.Explorer.TREpar.step is None:
881
+ FlagProcessTree=False
882
+ else:
883
+ FlagProcessTree=self.gui.ui.Explorer.currentTree==self.gui.ui.Explorer.processTree and self.gui.ui.Explorer.TREpar.step>0
881
884
  FlagLabel=(self.TABpar.flagRun!=0 and len(self.TABpar.link)==0) or len(self.TABpar.link)>0
882
885
  FlagReset=self.TABpar.flagRun!=0 and len(self.TABpar.link)==0
883
886
  FlagInherit=self.TABpar.flagRun==0 and len(self.TABpar.link)==0 and len(self.gui.IOVheritableSteps())>0
@@ -1129,11 +1132,11 @@ def setFontPixelSize(self,fPixSize):
1129
1132
 
1130
1133
  def setFontSizeText(lab:QLabel,fPixSizes):
1131
1134
  text=lab.text()
1132
- text=re.sub("font-size:\d+pt",f"font-size:{fPixSizes[0]}px",text)
1133
- text=re.sub("font-size:\d+px",f"font-size:{fPixSizes[0]}px",text)
1135
+ text=re.sub(r"font-size:\d+pt",f"font-size:{fPixSizes[0]}px",text)
1136
+ text=re.sub(r"font-size:\d+px",f"font-size:{fPixSizes[0]}px",text)
1134
1137
  if len(fPixSizes)>1:
1135
1138
  for k in range(len(fPixSizes)-1,0,-1):
1136
- text=re.sub("font-size:\d+px",f"font-size:{fPixSizes[k]}px",text,k)
1139
+ text=re.sub(r"font-size:\d+px",f"font-size:{fPixSizes[k]}px",text,k)
1137
1140
  lab.setText(text)
1138
1141
  font=lab.font()
1139
1142
  font.setPixelSize(fPixSizes[0])
PaIRS_UniNa/Vis_Tab.py CHANGED
@@ -234,8 +234,7 @@ class NamesPIV(TABpar):
234
234
 
235
235
  class VISpar(TABpar):
236
236
  FlagVis=True
237
- FlagAutoLevels=True
238
- FlagAutoSizes=True
237
+
239
238
  class OUT(TABpar):
240
239
  def __init__(self):
241
240
  self.x = 0
@@ -269,7 +268,7 @@ class VISpar(TABpar):
269
268
  def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
270
269
  self.setup(Process,Step)
271
270
  super().__init__('VISpar','Vis')
272
- self.unchecked_fields+=['FlagAutomaticLevels','FlagAutomaticSizes','setPage']
271
+ self.unchecked_fields+=['setPage']
273
272
  self.uncopied_fields+=['graphics_fields']
274
273
 
275
274
  def setup(self,Process,Step):
@@ -314,6 +313,8 @@ class VISpar(TABpar):
314
313
  self.variableKey=''
315
314
  self.field_rep=0
316
315
 
316
+ self.FlagAutoLevels=True
317
+ self.FlagAutoSizes=True
317
318
  self.FlagYInvert=[False,False]
318
319
  self.FlagResetLevels=True
319
320
  self.FlagResetSizes=True
@@ -420,6 +421,9 @@ class Vis_Tab(gPaIRS_Tab):
420
421
  #------------------------------------- Graphical interface: miscellanea
421
422
  self.brush_cursor= QCursor(QPixmap(icons_path+"brush_cursor.png").scaled(24,24,mode=Qt.TransformationMode.SmoothTransformation))
422
423
  self.FlagNormalCursor=True
424
+ self.CursorTimer = QTimer(self)
425
+ self.CursorTimer.setSingleShot(True)
426
+ self.CursorTimer.timeout.connect(self.forceRestoreArrowCursor)
423
427
 
424
428
  self.img=None
425
429
  self.imgshow=None
@@ -547,8 +551,8 @@ class Vis_Tab(gPaIRS_Tab):
547
551
  self.setTABlayout=self.setVISlayout
548
552
 
549
553
  self.FlagReset=True
550
- self.FlagResetLevels=True
551
- self.FlagResetSizes =True
554
+ self.FlagResetLevels=False
555
+ self.FlagResetSizes =False
552
556
 
553
557
  self.image_file=''
554
558
  self.image_raw=None
@@ -634,7 +638,7 @@ class Vis_Tab(gPaIRS_Tab):
634
638
  FlagNew=(not self.VISpar.type and FlagNewImage) or (self.VISpar.type==1 and FlagNewResult)
635
639
  FlagDiff=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['img','cam','frame']) or FlagNew
636
640
 
637
- if (VISpar.FlagAutoLevels and (FlagNewImage or FlagNewResult)):
641
+ if (self.VISpar.FlagAutoLevels and (FlagNewImage or FlagNewResult)):
638
642
  self.resetAllLevels()
639
643
  if FlagDiff or self.FlagResetLevels:
640
644
  self.FlagResetLevels=False
@@ -643,7 +647,7 @@ class Vis_Tab(gPaIRS_Tab):
643
647
  self.FlagResetLevels=False
644
648
  self.resetLevels()
645
649
 
646
- if (VISpar.FlagAutoSizes and (FlagNewImage or FlagNewResult)):
650
+ if (self.VISpar.FlagAutoSizes and (FlagNewImage or FlagNewResult)):
647
651
  self.resetAllXYLims()
648
652
  if FlagDiff or self.FlagResetSizes:
649
653
  self.FlagResetSizes=False
@@ -651,8 +655,9 @@ class Vis_Tab(gPaIRS_Tab):
651
655
  elif self.FlagResetSizes:
652
656
  self.FlagResetSizes=False
653
657
  self.resetXYLims()
654
-
658
+
655
659
  self.adjustFieldRep()
660
+
656
661
 
657
662
  def adjustImport(self):
658
663
  self.VISpar.image_file=self.VISpar.image_file_Min=self.VISpar.image_file_Disp=''
@@ -676,7 +681,7 @@ class Vis_Tab(gPaIRS_Tab):
676
681
  if self.VISpar.img>0:
677
682
  self.VISpar.image_file=self.VISpar.path+self.VISpar.imList[self.VISpar.cam-1][self.VISpar.frame-1][self.VISpar.img-1] if len(self.VISpar.imList[self.VISpar.cam-1][self.VISpar.frame-1]) else ''
678
683
  elif self.VISpar.img==0:
679
- self.VISpar.image_file=self.VISpar.image_file_Current if self.VISpar.flagRun==-2 else self.VISpar.image_file_Disp if self.VISpar.variableKey==self.namesPIV.dispMap else self.VISpar.image_file_Min
684
+ self.VISpar.image_file=self.VISpar.image_file_Current if self.VISpar.flagRun==-2 and self.VISpar.variableKey!=self.namesPIV.dispMap else self.VISpar.image_file_Disp if self.VISpar.variableKey==self.namesPIV.dispMap else self.VISpar.image_file_Min
680
685
  else:
681
686
  self.VISpar.image_file=self.image_file_Load
682
687
 
@@ -699,7 +704,13 @@ class Vis_Tab(gPaIRS_Tab):
699
704
  else:
700
705
  self.VISpar.result_file=self.VISpar.resF(self.VISpar.img)
701
706
  elif self.VISpar.img==0:
702
- self.VISpar.result_file=self.VISpar.result_file_Mean
707
+ self.VISpar.result_file=self.VISpar.result_file_Mean
708
+ if not self.VISpar.FlagView:
709
+ ITE=self.gui.ui.Explorer.ITEfromInd(self.VISpar.ind)
710
+ id=ITE.procdata.name_proc
711
+ self.VISpar.FlagResult=fileIdenitifierCheck(id,self.VISpar.result_file)
712
+ if not self.VISpar.FlagResult: self.VISpar.result_file=''
713
+
703
714
 
704
715
  FlagNewImage, FlagNewResult, _=self.importFiles()
705
716
  return FlagNewImage, FlagNewResult
@@ -717,7 +728,7 @@ class Vis_Tab(gPaIRS_Tab):
717
728
  self.image_file=self.VISpar.image_file
718
729
  if self.VISpar.img==0:
719
730
  if self.VISpar.flagRun==-2:
720
- self.image_raw=self.image_Current_raw[self.VISpar.frame] if self.image_Current_raw else None
731
+ self.image_raw=self.image_Disp_raw if self.VISpar.variableKey==self.namesPIV.dispMap else self.image_Current_raw[self.VISpar.frame] if self.image_Current_raw else None
721
732
  else:
722
733
  self.image_raw=self.image_Disp_raw if self.VISpar.variableKey==self.namesPIV.dispMap else self.image_Min_raw
723
734
  else:
@@ -871,7 +882,10 @@ class Vis_Tab(gPaIRS_Tab):
871
882
  self.ui.image_levels.setCurrentIndex(i)
872
883
  self.ui.label_title.setText(f"Settings ({i+1}/{c+1})")
873
884
 
874
- Lim=self.VISpar.vLim[self.VISpar.variableKey]
885
+ if self.VISpar.variableKey in self.VISpar.vLim:
886
+ Lim=self.VISpar.vLim[self.VISpar.variableKey]
887
+ else:
888
+ Lim=1.0
875
889
  step=Lim/nStepsSlider
876
890
  FlagLim= self.VISpar.type or FlagDispMap
877
891
  self.ui.spin_min.setMinimum(-Lim if FlagLim else 0)
@@ -929,8 +943,10 @@ class Vis_Tab(gPaIRS_Tab):
929
943
  self.ui.name_var.setToolTip(f'{dataType} file: {dataName}')
930
944
  self.ui.name_var.setStatusTip(self.ui.name_var.toolTip())
931
945
 
932
- self.VISpar.colorMap=self.VISpar.vcolorMap[self.VISpar.variableKey]
933
- self.VISpar.vectorColor=self.VISpar.vvectorColor[self.VISpar.variableKey]
946
+ if self.VISpar.variableKey in self.VISpar.vcolorMap:
947
+ self.VISpar.colorMap=self.VISpar.vcolorMap[self.VISpar.variableKey]
948
+ if self.VISpar.variableKey in self.VISpar.vvectorColor:
949
+ self.VISpar.vectorColor=self.VISpar.vvectorColor[self.VISpar.variableKey]
934
950
 
935
951
  self.ui.button_cmap.setIcon(QIcon(icons_path+'colormaps/'+self.VISpar.colorMap+'.png'))
936
952
  self.ui.button_cvec.setIcon(QIcon(icons_path+'colormaps/'+self.VISpar.vectorColor+'Vector.png'))
@@ -950,17 +966,19 @@ class Vis_Tab(gPaIRS_Tab):
950
966
  return
951
967
 
952
968
  def setLevels(self):
953
- self.VISpar.min=self.VISpar.vmin[self.VISpar.variableKey]
954
- self.VISpar.max=self.VISpar.vmax[self.VISpar.variableKey]
955
- self.VISpar.mean=self.VISpar.vmean[self.VISpar.variableKey]
956
- self.VISpar.range=self.VISpar.vrange[self.VISpar.variableKey]
969
+ if self.VISpar.variableKey in self.VISpar.vmin:
970
+ self.VISpar.min=self.VISpar.vmin[self.VISpar.variableKey]
971
+ self.VISpar.max=self.VISpar.vmax[self.VISpar.variableKey]
972
+ self.VISpar.mean=self.VISpar.vmean[self.VISpar.variableKey]
973
+ self.VISpar.range=self.VISpar.vrange[self.VISpar.variableKey]
957
974
 
958
975
  def resetLevels(self):
959
- self.VISpar.vmin[self.VISpar.variableKey]=self.VISpar.vmin_default[self.VISpar.variableKey]
960
- self.VISpar.vmax[self.VISpar.variableKey]=self.VISpar.vmax_default[self.VISpar.variableKey]
961
- self.VISpar.vmean[self.VISpar.variableKey]=self.VISpar.vmean_default[self.VISpar.variableKey]
962
- self.VISpar.vrange[self.VISpar.variableKey]=self.VISpar.vrange_default[self.VISpar.variableKey]
963
- #self.setLevels()
976
+ if self.VISpar.variableKey in self.VISpar.vmin_default:
977
+ self.VISpar.vmin[self.VISpar.variableKey]=self.VISpar.vmin_default[self.VISpar.variableKey]
978
+ self.VISpar.vmax[self.VISpar.variableKey]=self.VISpar.vmax_default[self.VISpar.variableKey]
979
+ self.VISpar.vmean[self.VISpar.variableKey]=self.VISpar.vmean_default[self.VISpar.variableKey]
980
+ self.VISpar.vrange[self.VISpar.variableKey]=self.VISpar.vrange_default[self.VISpar.variableKey]
981
+ #self.setLevels()
964
982
 
965
983
  def resetAllLevels(self, ind=None):
966
984
  if ind is None: VIS:VISpar=self.VISpar
@@ -1007,6 +1025,7 @@ class Vis_Tab(gPaIRS_Tab):
1007
1025
  def getImageInfo(self,image=None,ind=None):
1008
1026
  if image is None: I=self.image
1009
1027
  else: I=image
1028
+ if I is None: return
1010
1029
  if ind is None: VIS:VISpar=self.VISpar
1011
1030
  else: VIS:VISpar=self.TABpar_at(ind)
1012
1031
  variableKey=self.VISpar.variableKey
@@ -1052,7 +1071,8 @@ class Vis_Tab(gPaIRS_Tab):
1052
1071
  res[n]=tres[0][:,:,j]
1053
1072
  if self.namesPIV.u in res and self.namesPIV.v in res:
1054
1073
  res=self.calcMagnitude(res)
1055
- res=self.calcZVorticity(res)
1074
+ FlagUnit=self.VISpar.Out.xres!=1.0 or self.VISpar.Out.pixAR!=1.0
1075
+ res=self.calcZVorticity(res,FlagUnit)
1056
1076
  for f in list(res):
1057
1077
  if not f in self.namesPIV.allFields: del res[f]
1058
1078
  except Exception as inst:
@@ -1068,9 +1088,10 @@ class Vis_Tab(gPaIRS_Tab):
1068
1088
  res[self.namesPIV.Mod]=np.sqrt(res[self.namesPIV.u]**2+res[self.namesPIV.v]**2)
1069
1089
  return res
1070
1090
 
1071
- def calcZVorticity(self,res):
1091
+ def calcZVorticity(self,res,FlagUnit=False):
1072
1092
  if self.namesPIV.x in res and self.namesPIV.y in res and self.namesPIV.u in res and self.namesPIV.v in res:
1073
- xres,yres=self.getXYRes(type=1)
1093
+ if FlagUnit: xres=yres=1/1000
1094
+ else: xres=yres=1.0
1074
1095
  try:
1075
1096
  du_dy, _=np.gradient(res[self.namesPIV.u],res[self.namesPIV.y][:,0]*yres,res[self.namesPIV.x][0,:]*xres) # Derivate di u rispetto a y e x
1076
1097
  _, dv_dx=np.gradient(res[self.namesPIV.v],res[self.namesPIV.y][:,0]*yres,res[self.namesPIV.x][0,:]*xres) # Derivate di v rispetto a y e x
@@ -1082,6 +1103,7 @@ class Vis_Tab(gPaIRS_Tab):
1082
1103
  def getResultInfo(self,result=None,ind=None):
1083
1104
  if result is None: res=self.result
1084
1105
  else: res=result
1106
+ if res is None: return
1085
1107
  if ind is None: VIS:VISpar=self.VISpar
1086
1108
  else: VIS:VISpar=self.TABpar_at(ind)
1087
1109
  for i in list(VIS.vmin_default):
@@ -1141,7 +1163,7 @@ class Vis_Tab(gPaIRS_Tab):
1141
1163
 
1142
1164
  def button_ShowIW_action(self):
1143
1165
  self.VISpar.FlagShowIW=self.ui.button_ShowIW.isChecked()
1144
- self.resetXYLims()
1166
+ #if self.VISpar.FlagShowIW: self.resetXYLims()
1145
1167
 
1146
1168
  def button_SubMIN_action(self):
1147
1169
  self.VISpar.FlagSubMIN=self.ui.button_SubMIN.isChecked()
@@ -1170,11 +1192,21 @@ class Vis_Tab(gPaIRS_Tab):
1170
1192
  self.setLevels()
1171
1193
 
1172
1194
  def button_automatic_levels_action(self):
1173
- VISpar.FlagAutoLevels=self.ui.button_automatic_levels.isChecked()
1195
+ self.VISpar.FlagAutoLevels=self.ui.button_automatic_levels.isChecked()
1174
1196
  return True
1175
1197
 
1176
1198
  def button_automatic_sizes_action(self):
1177
- VISpar.FlagAutoSizes=self.ui.button_automatic_sizes.isChecked()
1199
+ self.VISpar.FlagAutoSizes=self.ui.button_automatic_sizes.isChecked()
1200
+ if self.VISpar.FlagAutoSizes is False and self.VISpar.Process==ProcessTypes.piv:
1201
+ type2=0 if self.VISpar.type==1 else 1
1202
+ if self.VISpar.unit[self.VISpar.type]!=self.VISpar.unit[type2]:
1203
+ xres,yres=self.getXYRes(type=self.VISpar.unit[self.VISpar.type])
1204
+ else: xres=yres=1.0
1205
+ if (type2==0 and self.VISpar.unit[type2]) or (type2==1 and not self.VISpar.unit[type2]):
1206
+ xres2,yres2=self.getXYRes(type=type2)
1207
+ else: xres2=yres2=1.0
1208
+ self.VISpar.size[type2][0:2]=[s*xres/xres2 for s in [self.VISpar.xmin, self.VISpar.xmax]]
1209
+ self.VISpar.size[type2][2:4]=[s*yres/yres2 for s in [self.VISpar.ymin, self.VISpar.ymax]]
1178
1210
  return True
1179
1211
 
1180
1212
  def button_restore_action(self):
@@ -1299,6 +1331,33 @@ class Vis_Tab(gPaIRS_Tab):
1299
1331
  self.VISpar.size[self.VISpar.type][3]+=dy
1300
1332
 
1301
1333
  def button_FocusIW_action(self):
1334
+ """
1335
+ Show a popup menu with options 'H x W' and return the selected index (int) or None.
1336
+ Labels are formatted as f"{Vect[2][i]} x {Vect[0][i]}".
1337
+ """
1338
+ FlagDisp=self.VISpar.variableKey is self.namesPIV.dispMap
1339
+ if FlagDisp: it=-1
1340
+ else:
1341
+ # Ensure consistent length between lists 0 (width values) and 2 (height values)
1342
+ ve=self.VISpar.Pro.Vect if isinstance(self.VISpar.Pro.Vect[0],list) else [[v] for v in self.VISpar.Pro.Vect]
1343
+ Vect = [[val for val in v] for v in ve]
1344
+ n = min(len(Vect[0]), len(Vect[2]))
1345
+ if n == 0:
1346
+ return None
1347
+
1348
+ # Create a context menu and populate it with the available sizes
1349
+ menu = QMenu(self)
1350
+ for i in range(n):
1351
+ label = f"{Vect[2][i]} x {Vect[0][i]}"
1352
+ act = menu.addAction(label)
1353
+ act.setData(i)
1354
+
1355
+ # Display the menu at the current cursor position and wait for user selection
1356
+ chosen = menu.exec(QCursor.pos())
1357
+ it = None if chosen is None else chosen.data()
1358
+ if it is not None: self.FocusIW_it(it)
1359
+
1360
+ def FocusIW_it(self,it=-1):
1302
1361
  ve=self.VISpar.Pro.Vect if isinstance(self.VISpar.Pro.Vect[0],list) else [[v] for v in self.VISpar.Pro.Vect]
1303
1362
  Vect = [[val for val in v] for v in ve]
1304
1363
  if self.VISpar.unit[self.VISpar.type] and self.VISpar.type!=0:
@@ -1306,20 +1365,20 @@ class Vis_Tab(gPaIRS_Tab):
1306
1365
  for k in range(2): Vect[k]=[val/self.VISpar.Out.xres for val in Vect[k]]
1307
1366
  for k in range(2,4): Vect[k]=[val/yres for val in Vect[k]]
1308
1367
  else: yres=1.0
1309
- W=Vect[2][-1]
1368
+ W=Vect[2][it]
1310
1369
  FlagDisp=self.VISpar.variableKey is self.namesPIV.dispMap
1311
1370
  if FlagDisp:
1312
1371
  H=self.gui.w_Process_Disp.PROpar.SemiWidth_Epipolar*2+1
1313
1372
  H/=yres
1314
1373
  FlagBordo=False
1315
1374
  else:
1316
- H=Vect[0][-1]
1375
+ H=Vect[0][it]
1317
1376
  FlagBordo=self.VISpar.Pro.FlagBordo
1318
1377
  if abs(self.VISpar.size[self.VISpar.type][1]-self.VISpar.size[self.VISpar.type][0]-W)<1 and abs(self.VISpar.size[self.VISpar.type][3]-self.VISpar.size[self.VISpar.type][2]-H)<1:
1319
- dW=W if FlagDisp else Vect[3][-1]
1378
+ dW=W if FlagDisp else Vect[3][it]
1320
1379
  boundDist=W/2 if not FlagBordo else dW
1321
1380
  x0=int((self.VISpar.size[self.VISpar.type][0]-boundDist+W/2)/dW)*dW+boundDist-W/2 if self.VISpar.size[self.VISpar.type][0]>boundDist else boundDist-W/2
1322
- dH=H if FlagDisp else Vect[1][-1]
1381
+ dH=H if FlagDisp else Vect[1][it]
1323
1382
  boundDist=H/2 if not FlagBordo else dH
1324
1383
  y0=int((self.VISpar.size[self.VISpar.type][2]-boundDist+H/2)/dH)*dH+boundDist-H/2 if self.VISpar.size[self.VISpar.type][2]>boundDist else boundDist-H/2
1325
1384
  self.VISpar.size[self.VISpar.type][0]=x0
@@ -1350,10 +1409,10 @@ class Vis_Tab(gPaIRS_Tab):
1350
1409
  self.ui.button_Contourf.setChecked(self.VISpar.FlagContourf)
1351
1410
 
1352
1411
  def button_automatic_levels_set(self):
1353
- self.ui.button_automatic_levels.setChecked(VISpar.FlagAutoLevels)
1412
+ self.ui.button_automatic_levels.setChecked(self.VISpar.FlagAutoLevels)
1354
1413
 
1355
1414
  def button_automatic_sizes_set(self):
1356
- self.ui.button_automatic_sizes.setChecked(VISpar.FlagAutoSizes)
1415
+ self.ui.button_automatic_sizes.setChecked(self.VISpar.FlagAutoSizes)
1357
1416
 
1358
1417
  def button_invert_y_set(self):
1359
1418
  self.ui.button_invert_y.setChecked(self.VISpar.FlagYInvert[self.VISpar.type])
@@ -1384,14 +1443,18 @@ class Vis_Tab(gPaIRS_Tab):
1384
1443
  self.VISpar.size[self.VISpar.type][:2]=[xmin/self.xres,xmax/self.xres]
1385
1444
  self.VISpar.size[self.VISpar.type][2:4]=[ymin/self.yres,ymax/self.yres]
1386
1445
 
1446
+ def forceRestoreArrowCursor(self):
1447
+ if self.CursorTimer.isActive():
1448
+ self.CursorTimer.stop()
1449
+ while QApplication.overrideCursor() is not None:
1450
+ QApplication.restoreOverrideCursor()
1451
+ self.FlagNormalCursor = True
1452
+
1387
1453
  def brushCursor(self):
1388
- if self.FlagNormalCursor:
1389
- self.FlagNormalCursor=False
1390
- QApplication.setOverrideCursor(self.brush_cursor)
1391
- def restoreCursor():
1392
- QApplication.restoreOverrideCursor()
1393
- self.FlagNormalCursor=True
1394
- QTimer.singleShot(250,lambda: restoreCursor())
1454
+ self.forceRestoreArrowCursor()
1455
+ self.FlagNormalCursor=False
1456
+ QApplication.setOverrideCursor(self.brush_cursor)
1457
+ self.CursorTimer.start(250)
1395
1458
 
1396
1459
  def setMapVar(self):
1397
1460
  pri.PlotTime.magenta(f'{"/"*25} Plotting image - start')
@@ -1417,12 +1480,13 @@ class Vis_Tab(gPaIRS_Tab):
1417
1480
  if self.orect: self.cleanRect()
1418
1481
  self.cleanCommonRegion()
1419
1482
  fields=['result_file','variable','unit','min','max','nclev','FlagContourf','colorMap']
1483
+ if self.VISpar.variableKey not in self.result: raise('Variable not found in result structure!')
1420
1484
  V=self.result[self.VISpar.variableKey]
1421
1485
  if not self.VISpar.FlagContourf:
1422
1486
  self.img,Ximg,Yimg,FlagInterp,size=self.calcMap(V,size_pixels=[np.size(V,0), np.size(V,1)])
1423
1487
  FlagDraw=self.showImg(fields,size)
1424
1488
  else:
1425
- self.img,Ximg,Yimg,FlagInterp,size=self.calcMap(self.result[self.VISpar.variableKey])
1489
+ self.img,Ximg,Yimg,FlagInterp,size=self.calcMap(V)
1426
1490
  if FlagInterp:
1427
1491
  FlagDraw=self.showImg(fields,size)
1428
1492
  else:
@@ -1436,6 +1500,7 @@ class Vis_Tab(gPaIRS_Tab):
1436
1500
  FlagVecField=self.VISpar.isDifferentFrom(self.VISpar_old,fields=fields)
1437
1501
  if FlagVecField and self.result:
1438
1502
  self.showVecField()
1503
+ elif self.result is None: self.cleanVecField()
1439
1504
  FlagDraw=FlagDraw or FlagVecField
1440
1505
 
1441
1506
  if FlagDraw:
@@ -1476,7 +1541,7 @@ class Vis_Tab(gPaIRS_Tab):
1476
1541
  FlagXLim=True
1477
1542
  else:
1478
1543
  self.imgshow.set_data(img)
1479
- extent=self.imgExtent()
1544
+ extent=self.imgExtent(size)
1480
1545
  if extent!=self.imgshow.get_extent():
1481
1546
  self.imgshow.set_extent(extent)
1482
1547
  FlagExtent=True
@@ -1516,7 +1581,7 @@ class Vis_Tab(gPaIRS_Tab):
1516
1581
  return cmap, levs
1517
1582
 
1518
1583
  def getXYRes(self,type=None):
1519
- if not type: type=self.VISpar.type
1584
+ if type is None: type=self.VISpar.type
1520
1585
  xres=yres=1.0
1521
1586
  if self.VISpar.Process==ProcessTypes.piv and not self.VISpar.Out.FlagNone:
1522
1587
  if type==0: #mm/pixels
@@ -1564,6 +1629,7 @@ class Vis_Tab(gPaIRS_Tab):
1564
1629
  else: xres=yres=1.0
1565
1630
  X=result[self.namesPIV.x]*xres
1566
1631
  Y=result[self.namesPIV.y]*yres
1632
+ if self.VISpar.variableKey not in self.result: raise('Variable not found in result structure!')
1567
1633
  V=result[self.VISpar.variableKey]
1568
1634
  self.map=[X,Y,V]
1569
1635
 
@@ -1707,6 +1773,8 @@ class Vis_Tab(gPaIRS_Tab):
1707
1773
  size_pixels=np.shape(U)
1708
1774
  Up,_,_,_,_=self.calcMap(U,size_pixels=size_pixels)
1709
1775
  Vp,Xp,Yp,_,_=self.calcMap(V,size_pixels=size_pixels)
1776
+ Xp=Xp*xres
1777
+ Yp=Yp*yres
1710
1778
  self.stream=self.ui.plot.axes.streamplot(Xp,Yp,Up,Vp,color=VIS_VectorColors[self.VISpar.vectorColor],density=self.VISpar.streamdens,zorder=10)
1711
1779
 
1712
1780
  def cleanAxes(self,FlagAxis=True):
@@ -1836,21 +1904,22 @@ class Vis_Tab(gPaIRS_Tab):
1836
1904
  else:
1837
1905
  yin0=0
1838
1906
  xin0=xmax
1839
- xlim=self.ui.plot.axes.get_xlim()
1840
- xlim_min=min([xlim[0],xlim_min])
1841
- xlim_max=max([xlim[1],xlim_max])
1842
- self.ui.plot.axes.set_xlim(xlim_min,xlim_max)
1843
- if self.VISpar.FlagYInvert[self.VISpar.type]:
1844
- ylim=self.ui.plot.axes.get_ylim()
1845
- ylim_max=min([ylim[1],ylim_min])
1846
- ylim_min=max([ylim[0],ylim_max])
1847
- else:
1848
- ylim=self.ui.plot.axes.get_ylim()
1849
- ylim_min=min([ylim[0],ylim_min])
1850
- ylim_max=max([ylim[1],ylim_max])
1851
- self.ui.plot.axes.set_ylim(ylim_min,ylim_max)
1852
- self.VISpar.xmin,self.VISpar.xmax=list(self.ui.plot.axes.get_xlim())
1853
- self.VISpar.ymin,self.VISpar.ymax=list(self.ui.plot.axes.get_ylim())
1907
+ if self.VISpar.FlagShowIW and self.VISpar.isDifferentFrom(self.VISpar_old,fields=['FlagShowIW']):
1908
+ xlim=self.ui.plot.axes.get_xlim()
1909
+ xlim_min=min([xlim[0],xlim_min])
1910
+ xlim_max=max([xlim[1],xlim_max])
1911
+ self.ui.plot.axes.set_xlim(xlim_min,xlim_max)
1912
+ if self.VISpar.FlagYInvert[self.VISpar.type]:
1913
+ ylim=self.ui.plot.axes.get_ylim()
1914
+ ylim_max=min([ylim[1],ylim_min])
1915
+ ylim_min=max([ylim[0],ylim_max])
1916
+ else:
1917
+ ylim=self.ui.plot.axes.get_ylim()
1918
+ ylim_min=min([ylim[0],ylim_min])
1919
+ ylim_max=max([ylim[1],ylim_max])
1920
+ self.ui.plot.axes.set_ylim(ylim_min,ylim_max)
1921
+ self.VISpar.xmin,self.VISpar.xmax=list(self.ui.plot.axes.get_xlim())
1922
+ self.VISpar.ymin,self.VISpar.ymax=list(self.ui.plot.axes.get_ylim())
1854
1923
 
1855
1924
  def cleanCommonRegion(self):
1856
1925
  if self.CR:
PaIRS_UniNa/Whatsnew.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from .PaIRS_pypacks import*
2
2
  from .ui_Whatsnew import Ui_Whatsnew
3
- from .__init__ import __version__
3
+ from .__init__ import __version__,__subversion__
4
4
  import unicodedata
5
5
 
6
6
  #from TabTools import setupWid,setFontPixelSize,setFontSizeText
@@ -50,8 +50,10 @@ class Whatsnew(QMainWindow):
50
50
  self.ui.button_Ok.clicked.connect(self.close)
51
51
 
52
52
  def whatsNew(self):
53
+ FlagCheckWhatWasNew=False
53
54
  if os.path.exists(fileWhatsNew[0]):
54
55
  filename=fileWhatsNew[0]
56
+ FlagCheckWhatWasNew=True
55
57
  elif os.path.exists(fileWhatsNew[1]):
56
58
  filename=fileWhatsNew[1]
57
59
  else:
@@ -72,6 +74,15 @@ def whatsNew(self):
72
74
  news=content.replace('\r','').replace('\n','').replace('$',warn).replace('*',star)
73
75
  news=news.replace('<br/><br/>','',1)
74
76
  """
77
+ if FlagCheckWhatWasNew and os.path.exists(fileWhatsNew[1]):
78
+ file_old = open(fileWhatsNew[1], "rb")
79
+ content_old = file_old.read().decode("utf-8")
80
+ file_old.close()
81
+ if content_old==content:
82
+ os.remove(fileWhatsNew[1])
83
+ os.rename(fileWhatsNew[0],fileWhatsNew[1])
84
+ return
85
+
75
86
  splitted_news=content.splitlines()
76
87
  for k, text in enumerate(splitted_news):
77
88
  if not text: continue
@@ -90,8 +101,9 @@ def whatsNew(self):
90
101
  splitted_news[k]= f'<br/><span style="font-weight: 600; font-size: {fontPixelSize}px;">{text[1:]}</span><br/>'
91
102
  news="".join(splitted_news)
92
103
 
93
- Message=f'<span style=" font-size: {fontPixelSize+dfontPixelSize}px; font-weight: 600;">'+f"What's new in PaIRS-UniNa {__version__}"+'</span><br/><br/>'+news+'<br/>Go to the menu "? -> Changes" for further information.'
94
- self.whatsnew=Whatsnew(self,Message,f'Updates of version {__version__}',dfontPixelSize)
104
+ subversion_string=f'(.{__subversion__})' if int(__subversion__) else ''
105
+ Message=f'<span style=" font-size: {fontPixelSize+dfontPixelSize}px; font-weight: 600;">'+f"What's new in PaIRS-UniNa {__version__}{subversion_string}"+'</span><br/><br/>'+news+'<br/>Go to the menu "? -> Changes" for further information.'
106
+ self.whatsnew=Whatsnew(self,Message,f'Updates of version {__version__}{subversion_string}',dfontPixelSize)
95
107
  #warningDialog(self,Message,pixmap=''+ icons_path +'news.png',title=f'Updates of version {__version__}',flagRichText=True)
96
108
  except Exception as inst:
97
109
  pri.Error.red(f"There was a problem while launching the What's new dialog box:\n{inst}")
Binary file
PaIRS_UniNa/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
- __version__="0.2.5"
1
+ __version__="0.2.9"
2
2
  __subversion__="0"
3
- __year__='2024'
4
- __date__='2025.07.18'
3
+ __year__='2025'
4
+ __date__='2025.12.12'
5
5
  __mail__='etfd@unina.it'
6
- __website__='https://pairs.unina.it'
6
+ __website__='https://pairs.unina.it'