PaIRS-UniNa 0.2.0__cp310-cp310-win_amd64.whl → 0.2.8__cp310-cp310-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 (88) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +39 -23
  2. PaIRS_UniNa/Changes.txt +127 -8
  3. PaIRS_UniNa/Custom_Top.py +12 -9
  4. PaIRS_UniNa/Explorer.py +534 -165
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +261 -100
  7. PaIRS_UniNa/Input_Tab_CalVi.py +24 -25
  8. PaIRS_UniNa/Input_Tab_tools.py +967 -405
  9. PaIRS_UniNa/Output_Tab.py +324 -130
  10. PaIRS_UniNa/PaIRS_PIV.py +58 -1
  11. PaIRS_UniNa/PaIRS_pypacks.py +1415 -1039
  12. PaIRS_UniNa/Process_Tab.py +15 -19
  13. PaIRS_UniNa/Process_Tab_Disp.py +12 -5
  14. PaIRS_UniNa/Saving_tools.py +27 -13
  15. PaIRS_UniNa/TabTools.py +176 -59
  16. PaIRS_UniNa/Vis_Tab.py +664 -256
  17. PaIRS_UniNa/Vis_Tab_CalVi.py +114 -45
  18. PaIRS_UniNa/Whatsnew.py +58 -9
  19. PaIRS_UniNa/_PaIRS_PIV.pyd +0 -0
  20. PaIRS_UniNa/__init__.py +4 -3
  21. PaIRS_UniNa/addwidgets_ps.py +150 -63
  22. PaIRS_UniNa/calib.py +6 -3
  23. PaIRS_UniNa/calibView.py +19 -6
  24. PaIRS_UniNa/gPaIRS.py +1397 -543
  25. PaIRS_UniNa/icons/align_all.png +0 -0
  26. PaIRS_UniNa/icons/announcement.png +0 -0
  27. PaIRS_UniNa/icons/bugfix.png +0 -0
  28. PaIRS_UniNa/icons/change_folder.png +0 -0
  29. PaIRS_UniNa/icons/change_folder_off.png +0 -0
  30. PaIRS_UniNa/icons/close_all.png +0 -0
  31. PaIRS_UniNa/icons/copy_process_off.png +0 -0
  32. PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
  33. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  34. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  35. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  36. PaIRS_UniNa/icons/linked.png +0 -0
  37. PaIRS_UniNa/icons/logo_opaco.png +0 -0
  38. PaIRS_UniNa/icons/open_image.png +0 -0
  39. PaIRS_UniNa/icons/open_new_window.png +0 -0
  40. PaIRS_UniNa/icons/open_result.png +0 -0
  41. PaIRS_UniNa/icons/process_loop.png +0 -0
  42. PaIRS_UniNa/icons/pylog.png +0 -0
  43. PaIRS_UniNa/icons/python_warning.png +0 -0
  44. PaIRS_UniNa/icons/queue.png +0 -0
  45. PaIRS_UniNa/icons/restore_undo.png +0 -0
  46. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  47. PaIRS_UniNa/icons/scale_all.png +0 -0
  48. PaIRS_UniNa/icons/scale_down.png +0 -0
  49. PaIRS_UniNa/icons/scale_up.png +0 -0
  50. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  51. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  52. PaIRS_UniNa/icons/show_all.png +0 -0
  53. PaIRS_UniNa/icons/star.png +0 -0
  54. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  55. PaIRS_UniNa/icons/subMIN_on.png +0 -0
  56. PaIRS_UniNa/icons/unedited.png +0 -0
  57. PaIRS_UniNa/icons/uninitialized.png +0 -0
  58. PaIRS_UniNa/icons/window.png +0 -0
  59. PaIRS_UniNa/listLib.py +3 -2
  60. PaIRS_UniNa/parForMulti.py +7 -5
  61. PaIRS_UniNa/parForWorkers.py +174 -140
  62. PaIRS_UniNa/pivParFor.py +9 -11
  63. PaIRS_UniNa/preProcParFor.py +4 -4
  64. PaIRS_UniNa/procTools.py +120 -44
  65. PaIRS_UniNa/rqrdpckgs.txt +9 -0
  66. PaIRS_UniNa/stereoPivParFor.py +16 -22
  67. PaIRS_UniNa/tabSplitter.py +17 -7
  68. PaIRS_UniNa/ui_Input_Tab.py +56 -57
  69. PaIRS_UniNa/ui_Input_Tab_CalVi.py +71 -64
  70. PaIRS_UniNa/ui_Log_Tab.py +8 -6
  71. PaIRS_UniNa/ui_Output_Tab.py +180 -4
  72. PaIRS_UniNa/ui_Process_Tab.py +19 -19
  73. PaIRS_UniNa/ui_Process_Tab_Disp.py +181 -10
  74. PaIRS_UniNa/ui_Vis_Tab.py +332 -196
  75. PaIRS_UniNa/ui_Whatsnew.py +13 -13
  76. PaIRS_UniNa/ui_gPairs.py +140 -71
  77. PaIRS_UniNa/ui_infoPaIRS.py +156 -31
  78. PaIRS_UniNa/whatsnew.txt +6 -4
  79. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/METADATA +62 -26
  80. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/RECORD +82 -54
  81. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/WHEEL +1 -1
  82. PaIRS_UniNa/icons/order.png +0 -0
  83. PaIRS_UniNa/icons/order_reverse.png +0 -0
  84. PaIRS_UniNa/icons/run_piv.png +0 -0
  85. PaIRS_UniNa/stereo.py +0 -685
  86. PaIRS_UniNa/ui_infoCalVi.py +0 -428
  87. PaIRS_UniNa-0.2.0.dist-info/LICENSE +0 -19
  88. {PaIRS_UniNa-0.2.0.dist-info → pairs_unina-0.2.8.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/procTools.py CHANGED
@@ -51,27 +51,25 @@ for p in processData:
51
51
 
52
52
  stepData= {
53
53
  StepTypes.cal: {'name': 'Camera calibration', 'caption': 'Select an appropriate camera model and estimate the parameters of the mapping functions based on calibration target images',
54
- 'class': 1, 'icon': 'cal_step.png',
54
+ 'class': 1, 'icon': 'cal_step.png', 'parents': [],
55
55
  'tabs': ['Calibration','Input_CalVi','Process_CalVi','Vis_CalVi'], },
56
56
  StepTypes.min: {'name': 'Image pre-processing', 'caption': 'Select a set of particle images and compute the historical minimum background for subsets corresponding to the same laser light source',
57
- 'class': 1, 'icon': 'min_step.png',
57
+ 'class': 1, 'icon': 'min_step.png', 'parents': [],
58
58
  'tabs': ['Input','Output','Process_Min','Log','Vis'], },
59
59
  StepTypes.piv: {'name': 'PIV analysis', 'caption': 'Select a set of particle images, craft a custom iterative multi-grid method and compute the two-dimensional two-component displacement field',
60
- 'class': 1, 'icon': 'piv_step.png',
60
+ 'class': 1, 'icon': 'piv_step.png', 'parents': [],
61
61
  'tabs': ['Input','Output','Process','Log','Vis'], },
62
62
  StepTypes.disp: {'name': 'Disparity correction', 'caption': 'Select a a set of particle images and compute the laser sheet position and orientation to adjust the camera disparities in the stereo-setup',
63
- 'class': 1, 'icon': 'disp_step.png',
63
+ 'class': 1, 'icon': 'disp_step.png', 'parents': [StepTypes.cal],
64
64
  'tabs': ['Input','Output','Process_Disp','Log','Vis'], },
65
65
  StepTypes.spiv: {'name': 'Stereoscopic PIV analysis', 'caption': 'Select a set of particle images, craft a custom iterative multi-grid method and compute the two-dimensional three-component displacement field',
66
- 'class': 1, 'icon': 'piv_step.png',
66
+ 'class': 1, 'icon': 'piv_step.png', 'parents': [StepTypes.cal,StepTypes.disp],
67
67
  'tabs': ['Input','Output','Process','Log','Vis'], },
68
68
  }
69
69
  for p in stepData:
70
70
  stepData[p]['type']=p
71
71
 
72
72
  class dataTreePar(TABpar):
73
- nTypeProc=4
74
-
75
73
  def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
76
74
  self.setup(Process,Step)
77
75
  super().__init__('dataTreePar','ITEpar')
@@ -123,8 +121,8 @@ class dataTreePar(TABpar):
123
121
 
124
122
  self.dispFrames=0
125
123
 
126
- self.numUsedThreadsPIV=1
127
- self.NumThreads=-1 # used by PIV_ParFor_Workerfor setting the correct number of threads
124
+ self.numUsedProcs=1
125
+ self.numPivOmpCores=-1 # used by PIV_ParFor_Workerfor setting the correct number of threads
128
126
 
129
127
  self.OUT_dict={}
130
128
  self.PRO_dict={}
@@ -148,7 +146,7 @@ class dataTreePar(TABpar):
148
146
 
149
147
  #if Step==StepTypes.spiv:
150
148
  self.FlagDISP=False
151
- self.dispFile=''
149
+ #self.dispFile=''
152
150
 
153
151
  fields=[f for f,_ in self.__dict__.items()]
154
152
  self.numCallBackTotOk=0 #numero di callback ricevute= quelle con problema + finalized
@@ -170,14 +168,20 @@ class dataTreePar(TABpar):
170
168
  self.assignDataName()
171
169
  return
172
170
 
173
- def resF(self,i):
171
+ def resF(self,i,string=''):
174
172
  if self.ndig<-1: return ''
175
- if type(i)==str:
176
- return f"{self.outPathRoot}_{i}{self.outExt}"
177
- elif type(i)==int:
178
- return f"{self.outPathRoot}_{i:0{self.ndig:d}d}{self.outExt}"
173
+ if string=='dispMap':
174
+ fold=os.path.dirname(self.outPathRoot)
175
+ rad=os.path.splitext(os.path.basename(self.outPathRoot))[0]
176
+ if rad[-1]!='_': rad+='_'
177
+ return myStandardRoot(os.path.join(fold, f'dispMap_rot_{rad}{i}.png'))
179
178
  else:
180
- return ''
179
+ if type(i)==str:
180
+ return f"{self.outPathRoot}_{i}{self.outExt}"
181
+ elif type(i)==int:
182
+ return f"{self.outPathRoot}_{i:0{self.ndig:d}d}{self.outExt}"
183
+ else:
184
+ return ''
181
185
 
182
186
  def setProc(self,INP:INPpar=INPpar(),OUT:OUTpar=OUTpar(),PRO:PROpar=PROpar(),PRO_Min:PROpar_Min=PROpar_Min(),PRO_Disp:PROpar_Disp=PROpar_Disp()):
183
187
  if INP is None: return
@@ -199,7 +203,9 @@ class dataTreePar(TABpar):
199
203
  self.ncam=len(INP.imList)
200
204
  self.FlagTR=INP.FlagTR
201
205
  self.LaserType=INP.LaserType
202
-
206
+ self.FlagMIN=INP.FlagMIN
207
+ self.Imin=INP.imListMin
208
+
203
209
  if self.Step==StepTypes.min:
204
210
  self.compMin.outName = self.outPathRoot+'_data'+outExt.min
205
211
  self.compMin.name_proc = self.name_proc
@@ -217,16 +223,16 @@ class dataTreePar(TABpar):
217
223
  self.nimg=INP.nimg
218
224
  self.ndig=len(str(self.nimg))
219
225
  self.outExt=list(outType_dict)[OUT.outType]
220
- self.numUsedThreadsPIV=self.numUsedThreadsPIV #TODEL
226
+ self.numUsedProcs=self.numUsedProcs #TODEL
221
227
  if self.Step in (StepTypes.disp,StepTypes.spiv):
222
228
  self.calList=INP.calList
223
229
  self.calEx =INP.calEx
224
230
  if self.Step==StepTypes.disp:
225
231
  self.Nit = PRO_Disp.Nit
226
232
  self.dispFrames = PRO_Disp.frames
227
- if self.Step==StepTypes.spiv:
228
- self.FlagDISP=INP.FlagDISP
229
- self.dispFile=INP.dispFile
233
+ #if self.Step==StepTypes.spiv:
234
+ #self.FlagDISP=INP.FlagDISP
235
+ #self.dispFile=INP.dispFile
230
236
 
231
237
  self.nsteps=self.Nit if self.Step==StepTypes.disp else self.nimg
232
238
  self.list_pim=[0]*self.nsteps
@@ -259,6 +265,9 @@ class dataTreePar(TABpar):
259
265
 
260
266
  def procOutName(self):
261
267
  return procOutName(self)
268
+
269
+ def stepOutName(self):
270
+ return stepOutName(self)
262
271
 
263
272
  def resetTimeStat(self):
264
273
  ''' reset all the TimeStat parameters should be called before starting a new process maybe it is useless ask GP'''
@@ -319,7 +328,7 @@ class dataTreePar(TABpar):
319
328
 
320
329
  def setCompleteLog(self):
321
330
  warn1=self.headerSection('WARNINGS',self.warnings[1],'!')
322
- if self.flagRun:
331
+ if self.flagRun not in (0,-10):
323
332
  warn0=''
324
333
  self.createLogProc()
325
334
  LogProc = self.headerSection('OUTPUT',self.procLog[0])
@@ -329,7 +338,10 @@ class dataTreePar(TABpar):
329
338
  if self.warnings[0]: warn0='*Further information:\n'+self.warnings[0]+'\n'
330
339
  self.Log=self.createLogHeader()+procLog+warn0+warn1
331
340
  else:
332
- self.Log=self.createLogHeader()+warn1
341
+ if self.flagRun:
342
+ self.Log=self.createLogHeader()
343
+ else:
344
+ self.Log=self.createLogHeader()+warn1
333
345
 
334
346
  def createWarningLog(self,warning):
335
347
  warn1=self.headerSection('WARNINGS',warning,'!')
@@ -343,9 +355,54 @@ class dataTreePar(TABpar):
343
355
  if len(args)>1: n=args[1]
344
356
  ln=len(nameSection)
345
357
  ns=int((n-ln)/2)
346
- Log=f'{f"{c}"*n}\n{" "*ns}{nameSection}{" "*ns}\n{f"{c}"*n}\n'+Log+'\n'
358
+ header=f'{f"{c}"*n}\n{" "*ns}{nameSection}{" "*ns}\n{f"{c}"*n}\n'
359
+ if Log!=' ': Log=header+Log+'\n'
360
+ else: Log=header
347
361
  return Log
348
362
 
363
+ def eyeHeaderSection(self, text:str, width:int=54, height:int=11, border:str='o', pad:int=0)->str:
364
+ """
365
+ Draw an eye-shaped frame with the given text centered on the middle row.
366
+ Works in monospace consoles or QTextEdit. Uses a smooth parametric eye curve.
367
+ """
368
+ width=max(width, len(text)+2*pad+2)
369
+ height=max(5, height|(1)) # make it odd
370
+ mid=height//2
371
+ # eye boundary: y = a*(1 - |x|^p)^b, mirrored top/bottom
372
+ import math
373
+ p,b=1.6,1.0 # shape controls (p: pointiness, b: roundness)
374
+ ax=width/2-1
375
+ ay=mid-1 # vertical semi-size (controls thickness of eye)
376
+ eps=0.6 # border thickness in "cells"
377
+
378
+ rows=[]
379
+ for r in range(height):
380
+ y=(r-mid)/ay # -1..1
381
+ line=[]
382
+ for c in range(width):
383
+ x=(c- (width-1)/2)/ax # -1..1
384
+ # target boundary (top curve positive y, bottom negative)
385
+ yb = (1 - abs(x)**p)
386
+ yb = (yb if yb>0 else 0)**b # clamp
387
+ # distance to boundary (abs because top/bottom)
388
+ d=abs(abs(y)-yb)
389
+ ch=' '
390
+ if yb<=0 and abs(y)<eps/ay: # very ends -> leave blank
391
+ ch=' '
392
+ elif d*ay<=eps and yb>0: # on border
393
+ ch=border
394
+ line.append(ch)
395
+ rows.append(''.join(line))
396
+
397
+ # write text on middle row
398
+ body=list(rows[mid])
399
+ s=f' {text} '
400
+ start=(width-len(s))//2
401
+ body[start:start+len(s)]=list(s)
402
+ rows[mid]=''.join(body)
403
+
404
+ return '\n'.join(rows)
405
+
349
406
  def createLogProc(self):
350
407
  splitAs='\n '#used to join the strings together tab or spaces may be use to indent the error
351
408
  numImgTot=len(self.list_pim) if self.Step!=StepTypes.min else (2*len(self.list_pim))
@@ -358,7 +415,7 @@ class dataTreePar(TABpar):
358
415
  continue
359
416
  if self.Step==StepTypes.min: #minimum
360
417
  cont+=2
361
- flag=(p&FLAG_FINALIZED[0]) and (p&FLAG_FINALIZED[1])
418
+ #flag=(p&FLAG_FINALIZED[0]) and (p&FLAG_FINALIZED[1])
362
419
  if (p&FLAG_FINALIZED[0]):
363
420
  if (p&FLAG_FINALIZED[1]):
364
421
  LogProc+=(self.list_print[i])
@@ -372,6 +429,7 @@ class dataTreePar(TABpar):
372
429
  else:# la b nonè stata proprio letta
373
430
  cont-=1
374
431
  #pri.Process.magenta(f'LogProc wrong {i} {p} {splitAs.join(sAppo[1:-1])} {hex(p)} ')
432
+ LogProc+='\n'
375
433
  else:
376
434
  sAppo=self.list_print[i].split('\n')
377
435
  if (p&FLAG_FINALIZED[1]):
@@ -394,16 +452,23 @@ class dataTreePar(TABpar):
394
452
 
395
453
  if not LogProc: LogProc=self.nullLogProc()
396
454
 
397
- self.FlagErr=bool(LogErr)
455
+ self.FlagErr=bool(LogErr) or 'CRITICAL ERROR' in self.warnings[0]
398
456
  if self.Step in (StepTypes.piv,StepTypes.spiv):
399
457
  errStr=f' ({contErr}/{numImgTot} images)'
400
458
  else:
401
459
  errStr=''
460
+ if 'CRITICAL ERROR' in self.warnings[0]:
461
+ errStr2='!!! Critical errors occured! Please, see further information reported below.\n\n'
462
+ else:
463
+ errStr2=''
402
464
  if self.FlagErr:
403
- LogErr=f'There were errors in the current process{errStr}:\n\n'+LogErr
465
+ LogErr=f'There were errors in the current process{errStr}:\n\n{errStr2}'+LogErr
404
466
  else:
405
467
  LogErr=f'There were no errors in the current process!\n\n'
406
- pProc=cont*100/numImgTot
468
+ if numImgTot:
469
+ pProc=cont*100/numImgTot
470
+ else:
471
+ pProc=100
407
472
  pLeft=100-pProc
408
473
  if cont:
409
474
  pErr=contErr*100/cont
@@ -412,6 +477,7 @@ class dataTreePar(TABpar):
412
477
  pCorr=100-pErr
413
478
  item='pair' if self.Step!=StepTypes.disp else 'iteration'
414
479
  sp=' '*6 if self.Step!=StepTypes.disp else ' '
480
+ Log_PIVCores='' if self.Step==StepTypes.min else f' PIV cores: {self.numPivOmpCores}\n'
415
481
  LogStat=\
416
482
  f'Percentage of {item}s\n'+\
417
483
  f' processed: {pProc:.2f}%\n'+\
@@ -423,8 +489,9 @@ class dataTreePar(TABpar):
423
489
  f' {sp} per {item}: {self.deltaTime2String(self.timePerImage,True)}\n'+\
424
490
  f' to the end: {self.deltaTime2String(self.eta,True)}\n\n'+\
425
491
  f'Multi processing\n'+\
426
- f' PIV Cores: {self.NumThreads}\n'+\
427
- f' processing units: {floor(self.numUsedThreadsPIV/self.NumThreads)}\n'
492
+ Log_PIVCores+\
493
+ f' processing units: {floor(self.numUsedProcs)}\n'
494
+ #5f' processing units: {floor(self.numUsedProcs/self.numPivOmpCores)}\n'
428
495
  self.procLog=[LogProc,LogStat,LogErr]
429
496
  return
430
497
 
@@ -435,22 +502,25 @@ class dataTreePar(TABpar):
435
502
  if self.procLog[0]!=self.nullLogProc():
436
503
  self.Log=self.createLogHeader()+self.procLog[0]
437
504
  else:
438
- self.Log=self.createLogHeader()
505
+ self.Log=self.createLogHeader()
439
506
  return
440
507
 
441
- def writeCfgProcPiv(self,filename=''):
508
+ def writeCfgProcPiv(self,filename='',FlagWarningDialog=False):
442
509
  flagSpiv=self.Step==StepTypes.spiv
443
510
  if filename=='':
444
511
  outPathRoot=self.outPathRoot
445
512
  foldOut=os.path.dirname(outPathRoot)
446
513
  if not os.path.exists(foldOut):
447
- os.mkdir(foldOut)
514
+ try:
515
+ os.mkdir(foldOut)
516
+ except Exception as inst:
517
+ pri.Error.red(f'It was not possible to make the directory {foldOut}:\n{traceback.format_exc()}\n\n{inst}')
448
518
  filename=f"{outPathRoot}.cfg"
449
519
  try:
450
520
  writeCfgProcPiv(self,filename,flagSpiv)
451
521
  except Exception as inst:
452
522
  warningMessage=f'Error while writing PIV configuration file to location "{filename}":\n{inst}'
453
- warningDialog(self,warningMessage)
523
+ if FlagWarningDialog: warningDialog(None,warningMessage)
454
524
  pri.Error.red(f'{warningMessage}\n{traceback.format_exc()}\n')
455
525
 
456
526
  class MediaPIV():
@@ -515,9 +585,9 @@ class MediaPIV():
515
585
  self.vp=self.vp+var[self.indu+1]*var[self.indu+1] #piv.vp
516
586
  self.uvp=self.uvp+var[self.indu]*var[self.indu+1] #piv.uvp
517
587
  if self.stepType==StepTypes.spiv:
518
- self.wp=self.vp+var[self.indu+1]*var[self.indu+1] #piv.wp
519
- self.uwp=self.uvp+var[self.indu]*var[self.indu+1] #piv.uwp
520
- self.vwp=self.vp+var[self.indu+1]*var[self.indu+1] #piv.vwp
588
+ self.wp=self.wp+var[self.indu+2]*var[self.indu+2] #piv.wp
589
+ self.uwp=self.uwp+var[self.indu]*var[self.indu+2] #piv.uwp
590
+ self.vwp=self.vwp+var[self.indu+1]*var[self.indu+2] #piv.vwp
521
591
 
522
592
 
523
593
  if self.x.size<=1:
@@ -581,7 +651,6 @@ class MediaPIV():
581
651
  self.sn=self.sn*self.cont
582
652
  self.Info=self.Info*self.cont#percentuale di vettori buoni 1=100% 0 nememno un vettore buono
583
653
 
584
-
585
654
  class CompMin():
586
655
  ''' helper class to compute minimum '''
587
656
  def __init__(self,ncam=1,nframe=2):
@@ -1017,7 +1086,7 @@ def data2PIV(data:dataTreePar,flagSpiv=False):
1017
1086
  PIV=PaIRS_lib.PIV()
1018
1087
 
1019
1088
  PIV.DefaultValues()
1020
- PIV.Inp.FlagNumThreads=data.NumThreads
1089
+ PIV.Inp.FlagNumThreads=data.numPivOmpCores
1021
1090
  #OUT=data.OUT
1022
1091
  #PRO=data.PRO
1023
1092
 
@@ -1142,7 +1211,7 @@ def data2StereoPIV(data:dataTreePar):
1142
1211
  # STEREO CFG file
1143
1212
  # A €£ indicate that the feature is not enabled in the python wrapper
1144
1213
  spiv.nomecal='' # Root of calibration constants
1145
- spiv.NomeCostPiano=data.dispFile[:-4] # Root of disparity plane constants
1214
+ #spiv.NomeCostPiano=data.dispFile[:-4] # Root of disparity plane constants
1146
1215
 
1147
1216
  spiv.percorsocal='' # Path of calibration constants
1148
1217
  spiv.FlagParallel=0 # Type of parallel process 0 horizontal 1 vertical (faster but with less information and mor RAM occupied)
@@ -1206,7 +1275,11 @@ def data2StereoPIV(data:dataTreePar):
1206
1275
  cost.append(costDum)
1207
1276
  StereoPIV.setCalConst( flagCal, numCostCalib,cost)
1208
1277
 
1209
- flagReadPlaneConst=1# if true internal reading
1278
+ StereoPIV.vect.PianoLaser[0]=np.float32(data.OUT_dict['zconst'])
1279
+ StereoPIV.vect.PianoLaser[1]=np.float32(data.OUT_dict['xterm'])
1280
+ StereoPIV.vect.PianoLaser[2]=np.float32(data.OUT_dict['yterm'])
1281
+ """
1282
+ flagReadPlaneConst=0# if true internal reading
1210
1283
  if flagReadPlaneConst:
1211
1284
  if StereoPIV.readPlaneConst()==0:
1212
1285
  pri.Callback.green('Laser plane constants correclty read!')
@@ -1218,7 +1291,7 @@ def data2StereoPIV(data:dataTreePar):
1218
1291
  StereoPIV.vect.PianoLaser[1]=data.laserConst[1]
1219
1292
  StereoPIV.vect.PianoLaser[2]=data.laserConst[2]
1220
1293
  #piv *******************************************************************************
1221
-
1294
+ """
1222
1295
  #StereoPIV.readCfgProc(spiv.nomecfgPiv)
1223
1296
  return StereoPIV
1224
1297
 
@@ -1265,12 +1338,15 @@ def data2Disp(data:dataTreePar):
1265
1338
  """
1266
1339
 
1267
1340
  dAC.HCella=PRO_Disp.Vect[0] # Correlation window Height
1268
- dAC.WCella=PRO_Disp.Vect[1] # Correlation window Width
1269
- dAC.HGrid=PRO_Disp.Vect[2] # Grid distance vertical
1341
+ dAC.WCella=PRO_Disp.Vect[2] # Correlation window Width
1342
+ dAC.HGrid=PRO_Disp.Vect[1] # Grid distance vertical
1270
1343
  dAC.WGrid=PRO_Disp.Vect[3] # Grid distance horizontal
1271
1344
  dAC.N_NormEpi=PRO_Disp.SemiWidth_Epipolar # Semiwidth in the direction normal to the epipolar line
1272
1345
  dAC.RaggioFiltro=PRO_Disp.Filter_SemiWidth # Semiwidth of the filter for the detection of the maximum in the displacement map
1273
1346
  dAC.SogliaCor = PRO_Disp.Threshold # Threshold for the determination of point used in the baricentric search of the maximum in the disp map
1347
+ dAC.nIterMaxValid = PRO_Disp.Nit_OutDet
1348
+ dAC.numStd = PRO_Disp.Std_Threshold
1349
+
1274
1350
  #%% Volume ********************************
1275
1351
  dP.xinfZC = OUT.x_min # Coordinata x inferiore
1276
1352
  dP.yinfZC = OUT.y_min # Coordinata y inferiore
@@ -0,0 +1,9 @@
1
+ scipy 1.14.0 1.16.1 0
2
+ matplotlib 3.9.0 3.10.6 0
3
+ pillow 10.4.0 11.3.0 0
4
+ numpy 2.0.0 2.3.2 0
5
+ pyside6 6.7.0 6.9.2 0
6
+ unidecode 1.3.0 1.4.0 0
7
+ psutil 6.0.0 7.0.0 0
8
+ debugpy 1.6.6 1.8.16 0
9
+ certifi 2025.7.14 2025.8.3 0
@@ -24,17 +24,14 @@ def initStereoPIV(eventFerma,iImg,procId,data:dataTreePar,*args,**kwargs):
24
24
  #for v in data.PRO.Vect: vect.append(v.astype(np.intc))
25
25
 
26
26
  #StereoPIV.SetVect([v.astype(np.intc) for v in data.PRO.Vect])
27
- data.compMin.Imin=[np.zeros(1),np.zeros(1)]
28
27
  if data.FlagMIN:
29
- filename=data.filename_proc[StepTypes.min]
30
- if filename:
31
- try:
32
- with open(filename, 'rb') as file:
33
- data_min:dataTreePar = pickle.load(file)
34
- data.copyfromfields(data_min,['compMin'])
35
- except Exception as inst:
36
- raise (inst)
37
- #data.FlagMIN=False
28
+ data.compMin.Imin=[[np.zeros(1) for _ in range(data.nframe)] for _ in range(data.ncam)]
29
+ for c,Iminc in enumerate(data.Imin):
30
+ for k,filename in enumerate(Iminc):
31
+ try:
32
+ data.compMin.Imin[c][k]=np.ascontiguousarray(Image.open(filename))
33
+ except Exception as inst:
34
+ raise (inst)
38
35
 
39
36
 
40
37
  #fatto in modo esplicito da vedere
@@ -49,7 +46,7 @@ def exitNoLog(flagOut,varOut):
49
46
  ''' exit without printing the log '''
50
47
  varOut[0]=-1
51
48
  return (flagOut,varOut)
52
- def procStereoPIV(i,procId ,StereoPIV,data:dataTreePar,numUsedThreadsPIV,*args,**kwargs):
49
+ def procStereoPIV(i,procId ,StereoPIV,data:dataTreePar,numUsedProcs,*args,**kwargs):
53
50
  ''' main proc function called for all the images one time per processor
54
51
  k=0 always
55
52
  In output flagOut and varOut[0] can be:
@@ -70,7 +67,7 @@ def procStereoPIV(i,procId ,StereoPIV,data:dataTreePar,numUsedThreadsPIV,*args,*
70
67
  where FLAG_FINALIZED_OR_ERR = [ p|e for (p,e) in zip(FLAG_FINALIZED,FLAG_READ_ERR)]
71
68
  numProcOrErrTot=sum(1 if (f&FLAG_FINALIZED_OR_ERR[0])or(not f&FLAG_PROC[0]) else 0 for f in flagOut)
72
69
  to delete images
73
- pa='C:\desk\dl\apairs\jetcross\'
70
+ pa='C:\\desk\\dl\\apairs\\jetcross\\'
74
71
  no='zR2jet0_0004a'
75
72
  I =imread([pa no '.png']);
76
73
  I=I*0+1;
@@ -107,15 +104,12 @@ def procStereoPIV(i,procId ,StereoPIV,data:dataTreePar,numUsedThreadsPIV,*args,*
107
104
  else:
108
105
  nameImg=data.inpPath+data.list_Image_Files[j+k].replace('_cam0','_cam1')
109
106
  imgs[c][k]=np.ascontiguousarray(Image.open(nameImg),dtype= np.uint16)
110
- """
111
- if data.FlagMIN
112
- if data.FlagTR and i%2:
113
- I1[k]=I1[k]-data.compMin.Imin[[1,0][k]]
114
- else:
115
- I1[k]=I1[k]-data.compMin.Imin[k]
116
- #todo mettere la seconda img
117
- #todo al contrario della PIV le img sono uint16 capire se sia il caso di cambiare anche li
118
- """
107
+ if data.FlagMIN:
108
+ if data.FlagTR and i%2:
109
+ imgs[c][k]=imgs[c][k]-data.compMin.Imin[c][[1,0][k]]
110
+ else:
111
+ imgs[c][k]=imgs[c][k]-data.compMin.Imin[c][k]
112
+ imgs[c][k]=np.ascontiguousarray(imgs[c][k],dtype= np.uint16)
119
113
  #iProc=transfIm(data.OUT,flagTransf=0,Images=I1)
120
114
  except Exception as inst:
121
115
  flagOut|=FLAG_READ_ERR[kConst]
@@ -180,7 +174,7 @@ def procStereoPIV(i,procId ,StereoPIV,data:dataTreePar,numUsedThreadsPIV,*args,*
180
174
 
181
175
  # to del ma il resto dove va
182
176
  #varOut=[i,stampa,[]] if flagOut&FLAG_FINALIZING_PROC_OK[0] else [-1,stampa,[]]
183
- if (not procId%numUsedThreadsPIV) and flagOut&FLAG_FINALIZED[0]: # copiare l'img nella coda è un operazione onerosa. TA ha deciso che si copia solo quando serve
177
+ if (not procId%numUsedProcs) and flagOut&FLAG_FINALIZED[0]: # copiare l'img nella coda è un operazione onerosa. TA ha deciso che si copia solo quando serve
184
178
  #prLock(f'procMIN Main proc i={i}')
185
179
  varOut[2]=campoVel#VarOut=[i,stampa,Var]
186
180
 
@@ -165,12 +165,12 @@ class PaIRS_QSplitter(QSplitter):
165
165
  self.splitterSizes[-1]+=pa.width()-width
166
166
  width=pa.width()+self.handleWidth()
167
167
  self.setFixedWidth(width)
168
- self.setSizes(self.splitterSizes)
168
+ self.setSizes(self.splitterSizes)
169
169
  if FlagReleased:
170
170
  for i in range(self.count()-1):
171
171
  w=self.widget(i)
172
172
  w.setFixedWidth(self.splitterSizes[i])
173
- w.widget.setFixedWidth(self.splitterSizes[i])
173
+ w.widget.setFixedWidth(self.splitterSizes[i])
174
174
  return self.splitterSizes
175
175
 
176
176
  def resizeEvent(self,event):
@@ -236,6 +236,7 @@ class PaIRS_QScrollArea(QScrollArea):
236
236
  #if i in (0,3): frame.hide()
237
237
  frame_layout.addWidget(w)
238
238
  setattr(frame,'widget',w)
239
+ frame.setVisible(False)
239
240
  self.frames.append(frame)
240
241
  if hasattr(w,'ui') and hasattr(w.ui,'scrollArea'):
241
242
  w.ui.scrollArea.setObjectName('scroll_area_'+w.TABname)
@@ -296,9 +297,9 @@ class SPLpar(TABpar):
296
297
  self.Step=Step
297
298
  self.sizes=[s for s in SPLpar.sizes_default]
298
299
  self.FlagVisible=[f for f in SPLpar.FlagVisible_default]
299
- self.horizontalBarValues=SPLpar.horizontalBarValues_default
300
- self.verticalBarValues=SPLpar.verticalBarValues_default
301
- self.FlagCollapsibleBoxes=SPLpar.FlagCollapsibleBoxes_default
300
+ self.horizontalBarValues=copy.deepcopy(SPLpar.horizontalBarValues_default)
301
+ self.verticalBarValues=copy.deepcopy(SPLpar.verticalBarValues_default)
302
+ self.FlagCollapsibleBoxes=copy.deepcopy(SPLpar.FlagCollapsibleBoxes_default)
302
303
 
303
304
  class TabAreaWidget(gPaIRS_Tab):
304
305
  margin=10
@@ -404,6 +405,7 @@ class TabAreaWidget(gPaIRS_Tab):
404
405
  self.collapBoxes+=w.findChildren(CollapsibleBox)
405
406
  for s in self.scrollAreas:
406
407
  s:QScrollArea
408
+ if s.objectName()=='': continue
407
409
  self.SPLpar.horizontalBarValues[s.objectName()]=s.horizontalScrollBar().value()
408
410
  self.SPLpar.verticalBarValues[s.objectName()]=s.verticalScrollBar().value()
409
411
  s.horizontalScrollBar().valueChanged.connect(lambda v, scrllr=s: self.updateScrollBarValue(scrllr,True))
@@ -425,6 +427,7 @@ class TabAreaWidget(gPaIRS_Tab):
425
427
  #self.adjustTABparInd()
426
428
 
427
429
  def updateFlagCollapsibleBox(self,collapBox:CollapsibleBox):
430
+ if self.FlagSettingPar: return
428
431
  self.SPLpar.FlagCollapsibleBoxes[collapBox.objectName()]=collapBox.toggle_button.isChecked()
429
432
  TABpar_ind:SPLpar=self.TABpar_at(self.TABpar.ind)
430
433
  if TABpar_ind: TABpar_ind.FlagCollapsibleBoxes[collapBox.objectName()]=collapBox.toggle_button.isChecked()
@@ -438,7 +441,7 @@ class TabAreaWidget(gPaIRS_Tab):
438
441
  cB.on_click()
439
442
 
440
443
  def updateScrollBarValue(self,scrollArea:QScrollArea=None,flagHorizontal:bool=True):
441
- if self.FlagAnimationRunning: return
444
+ if self.FlagAnimationRunning or self.FlagSettingPar: return
442
445
  TABpar_ind:SPLpar=self.TABpar_at(self.TABpar.ind)
443
446
 
444
447
  if flagHorizontal:
@@ -490,6 +493,7 @@ class TabAreaWidget(gPaIRS_Tab):
490
493
  b.setIconSize(QSize(self.iconSize,self.iconSize))
491
494
 
492
495
  self.buttonBar_layout.addWidget(b)
496
+ b.setVisible(False)
493
497
  self.buttons.append(b)
494
498
  w.buttonTab=b
495
499
 
@@ -572,11 +576,17 @@ class TabAreaWidget(gPaIRS_Tab):
572
576
 
573
577
  #if self.SPLpar_old.barValue!=self.SPLpar.barValue:
574
578
  #self.scrollArea.horizontalScrollBar().setValue(self.SPLpar.barValue)
579
+ self.scrollArea.horizontalScrollBar().setMaximum(self.scrollArea.splitter.width()-self.scrollArea.width())
575
580
  self.setScrollBarValues()
576
581
  self.setFlagCollapsibleBox()
577
582
 
578
583
  #self.setUpdatesEnabled(True)
579
- #self.repaint()
584
+ #self.parent().hide()
585
+ #self.hide()
586
+ self.parent().updateGeometry()
587
+ self.updateGeometry()
588
+ #self.show()
589
+ #self.parent().show()
580
590
  return
581
591
 
582
592
  def splitterResize(self,FlagVisible=None,FlagReleased=True):