PEARL Procedures  rev-distro-2.0.3-2-g58135e4-dirty
Igor procedures for the analysis of PEARL data
pearl-area-display.ipf
Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.2
3 #pragma ModuleName = PearlAreaDisplay
4 #pragma version = 1.04
5 #include "pearl-compat"
6 
20 // 3D data is handled by 3 windows. they don't have to be visible all at the same time.
49 
55 
57 static function /s graphname_from_dfref(df, prefix)
58  dfref df
59  string prefix
60 
61  string name
62 
63  name = GetDataFolder(1, df)
64  name = ReplaceString("root:", name, "")
65  name = name[0, strlen(name) - 2]
66  name = ReplaceString(" ", name, "")
67  name = PearlCleanupName(prefix + name)
68  if (CheckName(name, 6))
69  name = UniqueName(name, 6, 0)
70  endif
71 
72  return name
73 end
74 
85 function /s ad_display(image)
86  wave image // wave which contains the image data from the detector
87  // returns the name of the graph window
88 
89  dfref savedf = GetDataFolderDFR()
90  dfref imagedf = GetWavesDataFolderDFR(image)
91  setdatafolder imagedf
92 
93  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
94  string graphtitle = dfname + " View"
95  string /g view_graphname = graphname_from_dfref(imagedf, "view_")
96  svar graphname = view_graphname
97  display /k=1/n=$graphname as graphtitle
98  graphname = s_name
99  appendimage /w=$graphname image
100 
101  setdatafolder savedf
102  return graphname
103 end
104 
115 function /s ad_display_histogram(image)
116  wave image
117 
118  dfref savedf = GetDataFolderDFR()
119  dfref imagedf = GetWavesDataFolderDFR(image)
120  string s_imagedf = GetDataFolder(1, imagedf)
121  setdatafolder imagedf
122 
123  make /n=(1)/o hist // histogram
124 
125  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
126  string graphtitle = dfname + " Histogram"
127  string /g hist_graphname = graphname_from_dfref(imagedf, "hist_")
128  svar graphname = hist_graphname
129  display /k=1/n=$graphname as graphtitle
130  graphname = s_name
131  appendtograph /w=$graphname hist
132 
133  ModifyGraph /w=$graphname rgb(hist)=(39168,0,0)
134  ModifyGraph /w=$graphname mode=6
135  ModifyGraph /w=$graphname mirror=1
136  ModifyGraph /w=$graphname minor=1
137  ModifyGraph /w=$graphname axThick=0.5
138  ModifyGraph /w=$graphname lblPosMode=1,lblPos=30,lblMargin=0
139  ModifyGraph /w=$graphname btLen=4
140  ModifyGraph /w=$graphname margin(left)=45,margin(bottom)=35,margin(top)=10,margin(right)=10
141  ModifyGraph /w=$graphname gfSize=10
142  Label /w=$graphname bottom "value"
143  Label /w=$graphname left "# pixels"
144 
145  ad_calc_histogram(image)
146 
147  setdatafolder savedf
148  return graphname
149 end
150 
166 function /s ad_display_profiles(image, [filter])
167  wave image
168  string filter
169  variable show_legend = 0 // currently not supported
170 
171  if (WaveDims(image) != 2)
172  abort "ad_display_profiles: image wave must be two-dimensional."
173  endif
174  if (ParamIsDefault(filter))
175  filter = "ad_box_filter"
176  endif
177 
178  // data folders and references
179  dfref savedf = GetDataFolderDFR()
180  dfref imagedf = GetWavesDataFolderDFR(image)
181  string s_imagedf = GetDataFolder(1, imagedf)
182  setdatafolder imagedf
183  string s_viewdf = PearlCleanupName("view_" + NameOfWave(image))
184  newdatafolder /o/s $s_viewdf
185  dfref viewdf = GetDataFolderDFR()
186  s_viewdf = GetDataFolder(1, viewdf)
187 
188  // data structures
189  string /g sourcepath = GetWavesDataFolder(image, 2)
190  string viewname = "view_image"
191  duplicate /o image, $viewname /wave=view
192  make /n=(3,3)/o xprofiles // NX x 3 wave with 3 one-dimensional profiles along Y dimension
193  make /n=(3,3)/o yprofiles // NY x 3 wave with 3 one-dimensional profiles along X dimension
194  string /g view_filter
195  string /g view_filter_options
196  view_filter = filter
197  view_filter_options = ""
198  variable /g view_filter_smoothing_x = 1
199  variable /g view_filter_smoothing_y = 1
200  variable /g view_cursor_mode = 0
201  string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
202  string graphtitle = dfname + NameOfWave(image) + " Profiles"
203  string /g prof_graphname = graphname_from_dfref(imagedf, "prof_")
204  svar graphname = prof_graphname
205  variable /g graph_avg // average value in ROI (ROI is defined by the crosshairs A and B)
206  variable /g graph_min // minimum value in ROI
207  variable /g graph_max // maximum value in ROI
208  variable /g graph_sum // sum of all values in ROI
209  variable /g graph_sdev // standard deviation of all values in ROI
210 
211  // graph setup
212  display /k=1 /n=$graphname /w=(100,100,500,400) as graphtitle
213  graphname = s_name
214  AppendToGraph /w=$graphname /L=xprofiles xprofiles[*][0],xprofiles[*][1],xprofiles[*][2]
215  AppendToGraph /w=$graphname /VERT/B=yprofiles yprofiles[*][0],yprofiles[*][1],yprofiles[*][2]
216  AppendImage /w=$graphname view
217  string imgname = StringFromList(0, ImageNameList(graphname, ";"))
218  ModifyImage /w=$graphname $imgname ctab= {*,*,BlueGreenOrange,0}
219  ModifyGraph /w=$graphname rgb(xprofiles)=(39168,0,0),rgb(yprofiles)=(39168,0,0)
220  ModifyGraph /w=$graphname rgb(xprofiles#1)=(0,26112,0),rgb(yprofiles#1)=(0,26112,0)
221  ModifyGraph /w=$graphname rgb(xprofiles#2)=(0,9472,39168),rgb(yprofiles#2)=(0,9472,39168)
222  ModifyGraph /w=$graphname mirror(xprofiles)=2,mirror(bottom)=3,mirror(yprofiles)=2,mirror(left)=3
223  ModifyGraph /w=$graphname nticks=3
224  ModifyGraph /w=$graphname minor=1
225  ModifyGraph /w=$graphname axThick=0.5
226  ModifyGraph /w=$graphname lblPosMode=1,lblPos=30,lblMargin=0
227  ModifyGraph /w=$graphname btLen=4
228  ModifyGraph /w=$graphname freePos(xprofiles)=0
229  ModifyGraph /w=$graphname freePos(yprofiles)=0
230  ModifyGraph /w=$graphname axisEnab(xprofiles)={0.64,1}
231  ModifyGraph /w=$graphname axisEnab(bottom)={0,0.6}
232  ModifyGraph /w=$graphname axisEnab(yprofiles)={0.64,1}
233  ModifyGraph /w=$graphname axisEnab(left)={0,0.6}
234  ModifyGraph /w=$graphname zero(left)=8
235  ModifyGraph /w=$graphname margin(left)=40,margin(bottom)=30,margin(top)=20,margin(right)=40
236  ModifyGraph /w=$graphname gfSize=10
237 
238  // axis labels
239  string labels = note(image)
240  string lab
241  lab = StringByKey("AxisLabelX", labels, "=", "\r")
242  if (!strlen(lab))
243  lab = "X"
244  endif
245  Label /w=$graphname bottom lab + " (\\U)"
246  lab = StringByKey("AxisLabelY", labels, "=", "\r")
247  if (!strlen(lab))
248  lab = "Y"
249  endif
250  Label /w=$graphname left lab + " (\\U)"
251  lab = StringByKey("AxisLabelD", labels, "=", "\r")
252  if (!strlen(lab))
253  lab = "value"
254  endif
255  Label /w=$graphname xprofiles lab + " (\\U)"
256  Label /w=$graphname yprofiles lab + " (\\U)"
257 
258  // legend
259  if (show_legend)
260  Legend /w=$graphname/C/N=text0/J/F=2/D=0.5/T={28}/A=RT/X=0.00/Y=0.00 "\\s(xprofiles)\tprofile A"
261  AppendText /w=$graphname "\\s(xprofiles#1)\tprofile B"
262  AppendText /w=$graphname "\\s(xprofiles#2)\tROI average"
263  AppendText /w=$graphname "min\t\\{" + s_viewdf + "graph_min}"
264  AppendText /w=$graphname "max\t\\{" + s_viewdf + "graph_max}"
265  AppendText /w=$graphname "sum\t\\{" + s_viewdf + "graph_sum}"
266  AppendText /w=$graphname "avg\t\\{" + s_viewdf + "graph_avg}"
267  AppendText /w=$graphname "sdev\t\\{" + s_viewdf + "graph_sdev}"
268  else
269  TextBox /w=$graphname /C/N=text0 /F=0 /B=1 /X=1.00 /Y=1.00
270  lab = StringByKey("Dataset", labels, "=", "\r")
271  if (strlen(lab))
272  AppendText /w=$graphname lab
273  endif
274  AppendText /w=$graphname "sum\t\\{" + s_viewdf + "graph_sum}"
275  AppendText /w=$graphname "avg\t\\{" + s_viewdf + "graph_avg}"
276  AppendText /w=$graphname "sdev\t\\{" + s_viewdf + "graph_sdev}"
277  endif
278 
279  // interactive elements
280  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 A $imgname 0,0
281  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 B $imgname DimSize(view, 0)-1, DimSize(view, 1)-1
282  variable pcurs
283  pcurs = floor(DimSize(xprofiles, 0) / 3)
284  Cursor /w=$graphname /A=0 /P /S=1 /H=0 C xprofiles#2 pcurs
285  pcurs = floor(DimSize(xprofiles, 0) * 2 / 3)
286  Cursor /w=$graphname /A=0 /P /S=1 /H=0 D xprofiles#2 pcurs
287  pcurs = floor(DimSize(yprofiles, 0) / 3)
288  Cursor /w=$graphname /A=0 /P /S=1 /H=0 E yprofiles#2 pcurs
289  pcurs = floor(DimSize(yprofiles, 0) * 2 / 3)
290  Cursor /w=$graphname /A=0 /P /S=1 /H=0 F yprofiles#2 pcurs
291  ShowInfo /w=$graphname /CP=0
292 
293  SetWindow $graphname, hook(ad_profiles_hook)=ad_profiles_hook
294  ControlBar /w=$graphname 21
295  Button b_reset_cursors win=$graphname, title="reset cursors",pos={0,0},size={70,20},proc=PearlAreaDisplay#bp_reset_cursors
296  Button b_reset_cursors win=$graphname, fColor=(65535,65535,65535),fSize=10
297 
298  SetVariable sv_smoothing_x win=$graphname, title="X smoothing",pos={130,2},bodyWidth=40
299  SetVariable sv_smoothing_x win=$graphname, value=view_filter_smoothing_x,limits={1,100,1}
300  SetVariable sv_smoothing_x win=$graphname, proc=PearlAreaDisplay#svp_smoothing
301  SetVariable sv_smooting_y win=$graphname, title="Y smoothing",pos={240,2},bodyWidth=40
302  SetVariable sv_smooting_y win=$graphname, value=view_filter_smoothing_y,limits={1,100,1}
303  SetVariable sv_smooting_y win=$graphname, proc=PearlAreaDisplay#svp_smoothing
304 
305  PopupMenu pm_export win=$graphname, mode=0,title="Export"
306  PopupMenu pm_export win=$graphname, value="X profile;Y profile;X profile (collate);Y profile (collate)"
307  PopupMenu pm_export win=$graphname, pos={308,0},bodyWidth=60,proc=PearlAreaDisplay#pmp_export
308  PopupMenu pm_export win=$graphname, help={"Export profile of selected area and display in graph. Collate mode = display all profiles in same graph."}
309 
310  // data processing
311  ad_update_profiles(image)
312 
313  setdatafolder savedf
314  return graphname
315 end
316 
322 function ad_update_profiles(image)
323  wave image
324 
325  // data folders and references
326  dfref viewdf = get_view_folder(image)
327  if (DataFolderRefStatus(viewdf) == 0)
328  return -1 // data folder not found
329  endif
330  dfref savedf = GetDataFolderDFR()
331  setdatafolder viewdf
332 
333  // data structures
334  string viewname = "view_image"
335  duplicate /o image, $viewname /wave=view
336 
337  // data processing
338  svar view_filter
339  svar view_filter_options
340  nvar smoothing_x = view_filter_smoothing_x
341  nvar smoothing_y = view_filter_smoothing_y
342  funcref ad_default_image_filter filterfunc = $view_filter
343  view_filter_options = ReplaceNumberByKey("SmoothingX", view_filter_options, smoothing_x, "=", ";")
344  view_filter_options = ReplaceNumberByKey("SmoothingY", view_filter_options, smoothing_y, "=", ";")
345  filterfunc(view, view_filter_options)
346 
348 
349  setdatafolder savedf
350  return 0
351 end
352 
369 function ad_profiles_cursor_mode(image, mode)
370  wave image
371  variable mode
372 
373  dfref savedf = GetDataFolderDFR()
374  wave view_image = get_view_image(image)
375  dfref viewdf = GetWavesDataFolderDFR(view_image)
376  svar /sdfr=viewdf graphname = prof_graphname
377  nvar /sdfr=viewdf cursor_mode = view_cursor_mode
378  wave /sdfr=viewdf xprofiles, yprofiles
379 
380  variable dx = DimSize(view_image, 0)
381  variable dy = DimSize(view_image, 1)
382  switch(mode)
383  case 1: // background selection
384  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 A view_image 0, 0
385  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
386  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 C view_image round(0.2 * dx) -1, 0
387  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 D view_image round(0.8 * dx) -1, 0
388  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 E view_image round(0.4 * dx) -1, 0
389  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 F view_image round(0.6 * dx) -1, 0
390 
391  ShowInfo /w=$graphname /CP=0
392  cursor_mode = mode
393  break
394  default:
395  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 A view_image 0,0
396  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
397  variable pcurs
398  pcurs = floor(DimSize(xprofiles, 0) / 3)
399  Cursor /w=$graphname /A=0 /P /S=1 /H=0 C xprofiles#2 pcurs
400  pcurs = floor(DimSize(xprofiles, 0) * 2 / 3)
401  Cursor /w=$graphname /A=0 /P /S=1 /H=0 D xprofiles#2 pcurs
402  pcurs = floor(DimSize(yprofiles, 0) / 3)
403  Cursor /w=$graphname /A=0 /P /S=1 /H=0 E yprofiles#2 pcurs
404  pcurs = floor(DimSize(yprofiles, 0) * 2 / 3)
405  Cursor /w=$graphname /A=0 /P /S=1 /H=0 F yprofiles#2 pcurs
406  ShowInfo /w=$graphname /CP=0
407  cursor_mode = 0
408  endswitch
409 
410  setdatafolder savedf
411  return 0
412 end
413 
430 function ad_profiles_set_cursor(image, cursorname, xa, ya, [pscale])
431  wave image
432  string cursorname
433  variable xa, ya
434  variable pscale
435 
436  if (ParamIsDefault(pscale))
437  pscale = 0
438  endif
439 
440  // data folders and references
441  dfref savedf = GetDataFolderDFR()
442  wave view_image = get_view_image(image)
443  dfref viewdf = GetWavesDataFolderDFR(view_image)
444  svar /sdfr=viewdf graphname = prof_graphname
445 
446  variable pa, qa
447  if (pscale)
448  pa = xa
449  qa = ya
450  else
451  pa = round((xa - DimOffset(view_image, 0)) / DimDelta(view_image, 0))
452  qa = round((ya - DimOffset(view_image, 1)) / DimDelta(view_image, 1))
453  endif
454 
455  pa = min(pa, DimSize(view_image, 0) - 1)
456  pa = max(pa, 0)
457  qa = min(qa, DimSize(view_image, 1) - 1)
458  qa = max(qa, 0)
459  Cursor /i /p /w=$graphname $cursorname view_image pa, qa
460 
461  setdatafolder savedf
462  return 0
463 End
464 
475 // the lines can be removed manually using the draw toolbox, or by calling this function with @c clean=1.
482 function ad_profiles_crosshairs(image, [clear])
483  wave image
484  variable clear
485 
486  if (ParamIsDefault(clear))
487  clear = 0
488  endif
489 
490  // data folders and references
491  wave view_image = get_view_image(image)
492  dfref viewdf = GetWavesDataFolderDFR(view_image)
493  svar /sdfr=viewdf graphname = prof_graphname
494 
495  string cursors = "A;B"
496  string colors = "39168,0,0;0,26112,0"
497  string color
498  variable ncursors
499  variable icursor
500  string cursorname
501  string groupname = "crosshairs"
502  variable xx, yy
503  struct RGBColor rgb
504 
505  if (clear == 0)
506  SetDrawEnv /W=$graphname push
507  DrawAction /w=$graphname getgroup=$groupname, delete, begininsert
508  SetDrawEnv /w=$graphname gstart, gname=$groupname
509 
510  SetDrawEnv /W=$graphname dash=4
511  SetDrawEnv /W=$graphname linethick=0.5
512 
513  ncursors = ItemsInList(cursors, ";")
514  for (icursor=0; icursor < ncursors; icursor += 1)
515  cursorname = StringFromList(icursor, cursors, ";")
516  color = StringFromList(icursor, colors, ";")
517  rgb.red = str2num(StringFromList(0, color, ","))
518  rgb.green = str2num(StringFromList(1, color, ","))
519  rgb.blue = str2num(StringFromList(2, color, ","))
520  if (strlen(CsrInfo($cursorname, graphname)) > 0)
521  xx = hcsr($cursorname, graphname)
522  yy = vcsr($cursorname, graphname)
523  SetDrawEnv /W=$graphname linefgc=(rgb.red, rgb.green, rgb.blue)
524  SetDrawEnv /W=$graphname save
525  SetDrawEnv /W=$graphname xcoord=bottom, ycoord=prel
526  DrawLine /W=$graphname xx, 0, xx, 1
527  SetDrawEnv /W=$graphname xcoord=prel, ycoord=left
528  DrawLine /W=$graphname 0, yy, 1, yy
529  endif
530  endfor
531 
532  SetDrawEnv /w=$graphname gstop
533  DrawAction /w=$graphname endinsert
534  SetDrawEnv /W=$graphname pop
535  SetDrawEnv /W=$graphname save
536  else
537  DrawAction /w=$graphname getgroup=$groupname, delete
538  endif
539 
540  return 0
541 end
542 
548 static function /wave get_source_image(view)
549  wave view // image wave displayed in a profiles window
550 
551  dfref viewdf = GetWavesDataFolderDFR(view)
552  svar /z /sdfr=viewdf sourcepath
553  if (svar_exists(sourcepath))
554  wave /z img = $sourcepath
555  else
556  wave /z img = $""
557  endif
558  return img
559 end
560 
562 static function /df make_view_folder(source)
563  wave source // wave which contains the raw data from the detector.
564 
565  // data folders and references
566  dfref savedf = GetDataFolderDFR()
567  dfref imagedf = GetWavesDataFolderDFR(source)
568  string s_imagedf = GetDataFolder(1, imagedf)
569  setdatafolder imagedf
570  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
571  newdatafolder /o/s $s_viewdf
572  dfref viewdf = GetDataFolderDFR()
573 
574  setdatafolder savedf
575  return viewdf
576 end
577 
586 static function /df get_view_folder(source)
587  wave source
588 
589  // data folders and references
590  dfref savedf = GetDataFolderDFR()
591  dfref imagedf = GetWavesDataFolderDFR(source)
592  dfref viewdf
593  setdatafolder imagedf
594  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
595  if (DataFolderExists(s_viewdf))
596  setdatafolder $s_viewdf
597  viewdf = GetDataFolderDFR()
598  endif
599 
600  setdatafolder savedf
601  return viewdf
602 end
603 
609 static function /wave get_view_image(source)
610  wave source
611 
612  dfref viewdf = get_view_folder(source)
613  string viewname = "view_image"
614  wave /sdfr=viewdf view = $viewname
615 
616  return view
617 end
618 
619 static function bp_reset_cursors(ba) : ButtonControl
620  STRUCT WMButtonAction &ba
621 
622  switch( ba.eventCode )
623  case 2: // mouse up
624  string imgname = StringFromList(0, ImageNameList(ba.win, ";"))
625  wave /z image = ImageNameToWaveRef(ba.win, imgname)
626  if (waveexists(image))
627  Cursor /i/p A $imgname 0,0
628  Cursor /i/p B $imgname DimSize(image, 0)-1, DimSize(image, 1)-1
629  endif
630  break
631  case -1: // control being killed
632  break
633  endswitch
634 
635  return 0
636 End
637 
638 static function svp_smoothing(sva) : SetVariableControl
639  STRUCT WMSetVariableAction &sva
640 
641  string imglist
642 
643  switch( sva.eventCode )
644  case 1: // mouse up
645  case 2: // Enter key
646  case 3: // Live update
647  imglist = ImageNameList(sva.win, ";")
648  wave /z img = ImageNameToWaveRef(sva.win, StringFromList(0, imglist))
649  if (WaveExists(img))
650  wave source = get_source_image(img)
651  if (WaveExists(source))
652  ad_update_profiles(source)
653  endif
654  endif
655  break
656  case -1: // control being killed
657  break
658  endswitch
659 
660  return 0
661 end
662 
663 static function pmp_export(pa) : PopupMenuControl
664  STRUCT WMPopupAction &pa
665 
666  switch( pa.eventCode )
667  case 2: // mouse up
668  variable popNum = pa.popNum
669 
670  string imgname = StringFromList(0, ImageNameList(pa.win, ";"))
671  wave /z image = ImageNameToWaveRef(pa.win, imgname)
672  if (waveexists(image) && (popNum >= 1) && (popNum <= 2))
673  ad_export_profile(image, popNum - 1, show=1)
674  elseif (waveexists(image) && (popNum >= 3) && (popNum <= 4))
675  ad_export_profile(image, popNum - 3, show=2)
676  endif
677 
678  break
679  case -1: // control being killed
680  break
681  endswitch
682 
683  return 0
684 End
685 
687 function ad_profiles_hook(s)
688  struct WMWinHookStruct &s
689  variable hookresult = 0
690  string imglist
691  string cmd
692  dfref viewdf
693 
694  switch(s.eventCode)
695  case 2: // delete data folder after window is killed
696  imglist = ImageNameList(s.winName, ";")
697  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
698  if (WaveExists(img))
699  viewdf = GetWavesDataFolderDFR(img)
700  cmd = "killdatafolder /z " + GetDataFolder(1, viewdf)
701  Execute /P/Q/Z cmd
702  endif
703  break
704  case 7: // update profiles when cursor is moved
705  imglist = ImageNameList(s.winName, ";")
706  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
707  if (WaveExists(img))
709  hookresult = 1
710  else
711  hookresult = 0
712  endif
713  break
714  endswitch
715 
716  return hookresult
717 end
718 
727 function ad_calc_cursor_profiles(image)
728  wave image
729 
730  dfref savedf = GetDataFolderDFR()
731  dfref imagedf = GetWavesDataFolderDFR(image)
732  setdatafolder imagedf
733 
734  svar graphname = prof_graphname
735 
736  variable pa, qa // point coordinates cursor A
737  if (strlen(CsrInfo(A, graphname)) > 0)
738  pa = pcsr(A, graphname)
739  qa = qcsr(A, graphname)
740  else
741  pa = 0
742  qa = 0
743  endif
744 
745  variable pb, qb // point coordinates cursor B
746  if (strlen(CsrInfo(B, graphname)) > 0)
747  pb = pcsr(B, graphname)
748  qb = qcsr(B, graphname)
749  else
750  pb = DimSize(image, 0) - 1
751  qb = DimSize(image, 1) - 1
752  endif
753 
754  ad_calc_profiles(image, pa, qa, pb, qb)
755  setdatafolder savedf
756 end
757 
774 function ad_calc_profiles(image, pa, qa, pb, qb)
775  wave image
776  variable pa, qa
777  variable pb, qb
778 
779  dfref savedf = GetDataFolderDFR()
780  dfref imagedf = GetWavesDataFolderDFR(image)
781  setdatafolder imagedf
782 
783  wave xprofiles
784  wave yprofiles
785  nvar graph_avg
786  nvar graph_min
787  nvar graph_max
788  nvar graph_sum
789  nvar graph_sdev
790 
791  // horizontal profiles at crosshairs
792  redimension /n=(dimsize(image,0), 3) xprofiles
793  setscale /p x dimoffset(image,0), dimdelta(image,0), WaveUnits(image,0), xprofiles
794  setscale d 0, 0, waveunits(image,-1), xprofiles
795  xprofiles[][0] = image[p][qa]
796  xprofiles[][1] = image[p][qb]
797 
798  note /k xprofiles
799  note xprofiles, "SourceWave=" + nameofwave(image)
800  note xprofiles, "SourceDimension=0"
801  note xprofiles, "SourceIndex0=" + num2str(qa)
802  note xprofiles, "SourceIndex1=" + num2str(qb)
803 
804  // average horizontal profile between crosshairs
805  variable qq, q0, q1
806  q0 = min(qa, qb)
807  q1 = max(qa, qb)
808  xprofiles[][2] = 0
809  for (qq = q0; qq <= q1; qq += 1)
810  xprofiles[][2] += image[p][qq]
811  endfor
812  xprofiles[][2] /= q1 - q0 + 1
813 
814  // vertical profiles at crosshairs
815  redimension /n=(dimsize(image,1), 3) yprofiles
816  setscale /p x dimoffset(image,1), dimdelta(image,1), WaveUnits(image,1), yprofiles
817  setscale d 0, 0, waveunits(image,-1), yprofiles
818  yprofiles[][0] = image[pa][p]
819  yprofiles[][1] = image[pb][p]
820 
821  note /k yprofiles
822  note yprofiles, "SourceWave=" + nameofwave(image)
823  note yprofiles, "SourceDimension=1"
824  note yprofiles, "SourceIndex0=" + num2str(pa)
825  note yprofiles, "SourceIndex1=" + num2str(pb)
826 
827  // average vertical profile between crosshairs
828  variable pp, p0, p1
829  p0 = min(pa, pb)
830  p1 = max(pa, pb)
831  yprofiles[][2] = 0
832  for (pp = p0; pp <= p1; pp += 1)
833  yprofiles[][2] += image[pp][p]
834  endfor
835  yprofiles[][2] /= p1 - p0 + 1
836 
837  // statistics between crosshairs
838  Duplicate /r=[p0,p1][q0,q1]/o image, roi_image
839  WaveStats /Q roi_image
840  graph_avg = v_avg
841  graph_min = v_min
842  graph_max = v_max
843  graph_sum = v_avg * v_npnts
844  graph_sdev = v_sdev
845 
846  // histogram
847  wave /z hist
848  if (waveexists(hist))
849  Histogram /B=3 roi_image, hist
850  endif
851 
852  setdatafolder savedf
853 end
854 
876 function ad_export_profile(view_image, dim, [trace, show, overwrite])
877  wave view_image
878  variable dim
879  variable trace
880  variable show
881  variable overwrite
882 
883  dfref savedf = GetDataFolderDFR()
884 
885  if (ParamIsDefault(trace))
886  trace = 2
887  endif
888  if (ParamIsDefault(show))
889  show = 0
890  endif
891  if (ParamIsDefault(overwrite))
892  overwrite = 0
893  endif
894 
895  // view folder
896  dfref imagedf = GetWavesDataFolderDFR(view_image)
897  string dim_label
898  switch(dim)
899  case 0:
900  wave /sdfr=imagedf profiles=xprofiles
901  dim_label = "x"
902  break
903  case 1:
904  wave /sdfr=imagedf profiles=yprofiles
905  dim_label = "y"
906  break
907  default:
908  return -1 // invalid argument
909  endswitch
910  string graphname_string = "export_graph_" + dim_label
911  svar /z /sdfr=imagedf linked_graphname = $graphname_string
912 
913  // source folder
914  wave /z source_image = get_source_image(view_image)
915  if (WaveExists(source_image))
916  dfref sourcedf = GetWavesDataFolderDFR(source_image)
917  setdatafolder sourcedf
918  else
919  return -2 // invalid source data folder
920  endif
921 
922  // format dest wave name
923  string profile_note = note(profiles)
924  string name_base
925  string name_dim
926  string name_index
927  string profile_name
928  variable index_width = ceil(log(DimSize(view_image, 1 - dim)))
929  variable index0 = NumberByKey("SourceIndex0", profile_note, "=", "\r")
930  variable index1 = NumberByKey("SourceIndex1", profile_note, "=", "\r")
931  name_dim = "_" + dim_label
932  sprintf name_index, "%0*u_%0*u", index_width, index0, index_width, index1
933  name_base = NameOfWave(source_image)
934  name_base = name_base[0, min(strlen(name_base), 31 - strlen(name_index) - strlen(name_dim) - 1)]
935  profile_name = name_base + name_dim + name_index
936  if ((overwrite == 0) && (CheckName(profile_name, 1)))
937  profile_name = UniqueName(profile_name + "_", 1, 0)
938  endif
939 
940  // create dest wave
941  duplicate /o /r=[][trace] profiles, $profile_name /wave=dest_profile
942  redimension /n=(dimsize(profiles, 0)) dest_profile
943  profile_note = ReplaceStringByKey("SourceWave", profile_note, NameOfWave(source_image), "=", "\r")
944  note /k dest_profile
945  note dest_profile, profile_note
946  print "created", GetWavesDataFolder(dest_profile, 2)
947 
948  if (show)
949  string graphname
950  string graphtitle
951  if (show == 2)
952  // common graph for all profiles of a dimension
953  graphname = "export_profiles_" + dim_label
954  graphtitle = UpperStr(dim_label) + " Profiles"
955  else
956  // one graph per source image
957  if (svar_exists(linked_graphname) && (ItemsInList(WinList(linked_graphname, ";", "WIN:1"), ";") >= 1))
958  graphname = linked_graphname
959  else
960  graphname = GetWavesDataFolder(source_image, 0) + name_dim
961  endif
962  graphtitle = UpperStr(dim_label) + " Profiles: " + GetWavesDataFolder(source_image, 2)
963  endif
964 
965  if ((ItemsInList(WinList(graphname, ";", "WIN:1"), ";") >= 1))
966  appendtograph /w=$graphname dest_profile
967  else
968  setdatafolder imagedf
969  display /k=1 /n=$graphname dest_profile as graphtitle
970  graphname = s_name
971  ModifyGraph /w=$graphname mirror=1,nticks=3,minor=1
972  ModifyGraph /w=$graphname axThick=0.5,btLen=4
973  ModifyGraph /w=$graphname gfSize=10
974  ModifyGraph /w=$graphname grid=2,gridHair=0,gridRGB=(52224,52224,52224)
975  Legend /w=$graphname /C/N=legend0/F=0/B=1/A=LT/X=0.00/Y=0.00
976 
977  if (show != 2)
978  string /g $graphname_string = graphname
979  endif
980  endif
981  endif
982 
983  setdatafolder savedf
984  return 0
985 end
986 
987 static function set_trace_colors(graphname)
988  string graphname
989 
990  ModifyGraph /w=$graphname /z rgb[0]=(0, 0, 0)
991  ModifyGraph /w=$graphname /z rgb[1]=(65535, 16385, 16385)
992  ModifyGraph /w=$graphname /z rgb[2]=(2, 39321, 1)
993  ModifyGraph /w=$graphname /z rgb[3]=(0, 0, 65535)
994  ModifyGraph /w=$graphname /z rgb[4]=(39321, 1, 31457)
995  ModifyGraph /w=$graphname /z rgb[5]=(48059, 48059, 48059)
996  ModifyGraph /w=$graphname /z rgb[6]=(65535, 32768, 32768)
997  ModifyGraph /w=$graphname /z rgb[7]=(0, 65535, 0)
998  ModifyGraph /w=$graphname /z rgb[8]=(16385,65535,65535)
999  ModifyGraph /w=$graphname /z rgb[9]=(65535, 32768, 58981)
1000 end
1001 
1008 function ad_calc_histogram(image)
1009  wave image
1010 
1011  dfref savedf = GetDataFolderDFR()
1012  dfref imagedf = GetWavesDataFolderDFR(image)
1013  setdatafolder imagedf
1014 
1015  wave hist
1016  Histogram /B=3 image, hist
1017 
1018  setdatafolder savedf
1019 end
1020 
1031 function ad_default_image_filter(image, options)
1032  wave image
1033  string options
1034 end
1035 
1045 function ad_box_filter(image, options)
1046  wave image
1047  string options
1048 
1049  variable xsmoothing = NumberByKey("SmoothingX", options, "=", ";")
1050  variable ysmoothing = NumberByKey("SmoothingY", options, "=", ";")
1051 
1052  if ((NumType(xsmoothing) == 0) && (xsmoothing >= 2))
1053  Smooth /B /DIM=0 /E=3 xsmoothing, image
1054  endif
1055  if ((NumType(ysmoothing) == 0) && (ysmoothing >= 2))
1056  Smooth /B /DIM=1 /E=3 ysmoothing, image
1057  endif
1058 end
1059 
1067 function ad_transpose_filter(image, options)
1068  wave image
1069  string options
1070 
1071  MatrixTranspose image
1072 end
1073 
1074 
1075 // ################### 3D DATA ##################
1076 
1083 function /s ad_display_brick(data)
1084  wave data
1085 
1086  if(exists("NewGizmo") != 4)
1087  abort "Gizmo XOP must be installed."
1088  endif
1089  if (WaveDims(data) != 3)
1090  abort "ad_display_brick: data must be three-dimensional."
1091  endif
1092 
1093  dfref savedf = GetDataFolderDFR()
1094  dfref datadf = GetWavesDataFolderDFR(data)
1095  string s_datadf = GetDataFolder(1, datadf)
1096  dfref viewdf = make_view_folder(data)
1097 
1098  setdatafolder viewdf
1099  string dfname = ReplaceString("root:", s_datadf, "")
1100  string graphtitle = dfname + " Gizmo"
1101  string /g gizmo_graphname = graphname_from_dfref(datadf, "giz_")
1102  svar graphname = gizmo_graphname
1103 
1104  if ((strlen(graphname) > 0) && (wintype(graphname) == 13))
1105  setdatafolder savedf
1106  return graphname // gizmo window exists
1107  endif
1108 
1109  variable nx = dimsize(data, 0)
1110  variable ny = dimsize(data, 1)
1111  variable nz = dimsize(data, 2)
1112 
1113  variable pp
1114  string obj
1115  string cmd
1116 
1117  // igor does not allow calling gizmo functions directly
1118  setdatafolder datadf
1119  sprintf cmd, "NewGizmo /k=1 /n=%s /w=(100,100,500,400) /t=\"%s\"", graphname, graphtitle
1120  execute /q cmd
1121  cmd = "AppendToGizmo /D Axes=BoxAxes, name=axes0"
1122  execute /q cmd
1123 
1124  obj = "surface_xmid"
1125  pp = round(nx / 2 - 1)
1126  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
1127  execute /q cmd
1128  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 128}", obj
1129  execute /q cmd
1130  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
1131  execute /q cmd
1132  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
1133  execute /q cmd
1134  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
1135  execute /q cmd
1136  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
1137  execute /q cmd
1138 
1139  obj = "surface_ymid"
1140  pp = round(ny / 2 - 1)
1141  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
1142  execute /q cmd
1143  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 64}", obj
1144  execute /q cmd
1145  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
1146  execute /q cmd
1147  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
1148  execute /q cmd
1149  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
1150  execute /q cmd
1151  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
1152  execute /q cmd
1153 
1154  obj = "surface_zmid"
1155  pp = round(nz / 2 - 1)
1156  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
1157  execute /q cmd
1158  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 32}", obj
1159  execute /q cmd
1160  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
1161  execute /q cmd
1162  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
1163  execute /q cmd
1164  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
1165  execute /q cmd
1166  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
1167  execute /q cmd
1168 
1169  obj = "axes0"
1170  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisScalingMode,1}", obj
1171  execute /q cmd
1172  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisColor,0,0,0,1}", obj
1173  execute /q cmd
1174  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={0,ticks,3}", obj
1175  execute /q cmd
1176  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={1,ticks,3}", obj
1177  execute /q cmd
1178  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={2,ticks,3}", obj
1179  execute /q cmd
1180  sprintf cmd, "ModifyGizmo modifyObject=%s property={Clipped,0}", obj
1181  execute /q cmd
1182  sprintf cmd, "ModifyGizmo modifyObject=%s property={-1,fontScaleFactor,2}", obj
1183  execute /q cmd
1184 
1185  sprintf cmd, "ModifyGizmo showAxisCue=1"
1186  execute /q cmd
1187 
1188  setdatafolder savedf
1189  return graphname
1190 end
1191 
1198 function ad_brick_slicer(data)
1199  wave data
1200 
1201  // data folders and references
1202  dfref savedf = GetDataFolderDFR()
1203  dfref datadf = GetWavesDataFolderDFR(data)
1204  string s_datadf = GetDataFolder(1, datadf)
1205  dfref viewdf = make_view_folder(data)
1206 
1207  setdatafolder viewdf
1208  svar /z ex_panel = slicer_panelname
1209  if (svar_exists(ex_panel))
1210  string panels = WinList("SlicerPanel*", ";", "WIN:64")
1211  if (WhichListItem(ex_panel, panels, ";") >= 0)
1212  dowindow /f $(StringFromList(0, panels, ";"))
1213  return 0
1214  endif
1215  endif
1216 
1217  variable /g x_slice_pos
1218  variable /g y_slice_pos
1219  variable /g z_slice_pos
1220  variable /g slab_thickness
1221  string /g brick_path = getwavesdatafolder(data, 2)
1222  variable /g x_autoinc = 0
1223  variable /g y_autoinc = 0
1224  variable /g z_autoinc = 0
1225 
1226  // axis labels
1227  string labels = note(data)
1228  string xlabel = StringByKey("AxisLabelX", labels, "=", "\r")
1229  if (!strlen(xlabel))
1230  xlabel = "X"
1231  endif
1232  string ylabel = StringByKey("AxisLabelY", labels, "=", "\r")
1233  if (!strlen(ylabel))
1234  ylabel = "Y"
1235  endif
1236  string zlabel = StringByKey("AxisLabelZ", labels, "=", "\r")
1237  if (!strlen(zlabel))
1238  zlabel = "Z"
1239  endif
1240  string dlabel = StringByKey("Dataset", labels, "=", "\r")
1241  if (!strlen(dlabel))
1242  dlabel = NameOfWave(data)
1243  endif
1244 
1245  // this section copied from slicer panel
1246  NewPanel /k=1 /W=(500,600,890,940) /N=SlicerPanel as "Brick Slicer"
1247  string /g slicer_panelname = S_name
1248  string panel = s_name
1249 
1250  GroupBox g_xslice win=$panel,pos={8,8},size={376,96},title=xlabel
1251  Slider sl_xslice_position win=$panel,pos={16,32},size={240,56},proc=PearlAreaDisplay#slp_slice_position
1252  Slider sl_xslice_position win=$panel,limits={0,100,1},variable=x_slice_pos,vert= 0
1253  SetVariable sv_xslice_position win=$panel,pos={20,80},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="X"
1254  SetVariable sv_xslice_position win=$panel,limits={0,100,1},value=x_slice_pos
1255  Button b_xslice_center win=$panel,pos={122,80},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
1256  Button b_xslice_center win=$panel,help={"reset to center position"}
1257  Button b_xslice_extract win=$panel,pos={288,80},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
1258  Button b_xslice_extract win=$panel,help={"extract this slice to a separate wave"}
1259  //CheckBox cb_xslab_active win=$panel,pos={288,80},size={80,16},title="Display X Slab"
1260  //CheckBox cb_xslab_active win=$panel,value= 0
1261  TitleBox tb_xslice_animation win=$panel,pos={288,32},size={356,16},title="animation",frame=0
1262  TitleBox tb_xslice_animation win=$panel,anchor= MC
1263  Button b_xslice_back win=$panel,pos={288,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
1264  Button b_xslice_back win=$panel,help={"animate backwards"}
1265  Button b_xslice_forward win=$panel,pos={312,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
1266  Button b_xslice_forward win=$panel,help={"animate forward"}
1267  Button b_xslice_stop win=$panel,pos={336,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
1268  Button b_xslice_stop win=$panel,help={"stop animation"}
1269 
1270  GroupBox g_yslice win=$panel,pos={8,108},size={376,96},title=ylabel
1271  Slider sl_yslice_position win=$panel,pos={16,132},size={240,56},proc=PearlAreaDisplay#slp_slice_position
1272  Slider sl_yslice_position win=$panel,limits={0,100,1},variable=y_slice_pos,vert= 0
1273  SetVariable sv_yslice_position win=$panel,pos={20,180},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Y"
1274  SetVariable sv_yslice_position win=$panel,limits={0,100,1},value=y_slice_pos
1275  Button b_yslice_center win=$panel,pos={122,180},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
1276  Button b_yslice_center win=$panel,help={"reset to center position"}
1277  Button b_yslice_extract win=$panel,pos={288,180},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
1278  Button b_yslice_extract win=$panel,help={"extract this slice to a separate wave"}
1279  //CheckBox cb_yslab_active win=$panel,pos={288,180},size={80,16},title="Display Y Slab"
1280  //CheckBox cb_yslab_active win=$panel,value= 0
1281  TitleBox tb_yslice_animation win=$panel,pos={288,132},size={356,16},title="animation",frame=0
1282  TitleBox tb_yslice_animation win=$panel,anchor= MC
1283  Button b_yslice_back win=$panel,pos={288,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
1284  Button b_yslice_back win=$panel,help={"animate backwards"}
1285  Button b_yslice_forward win=$panel,pos={312,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
1286  Button b_yslice_forward win=$panel,help={"animate forward"}
1287  Button b_yslice_stop win=$panel,pos={336,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
1288  Button b_yslice_stop win=$panel,help={"stop animation"}
1289 
1290  GroupBox g_zslice win=$panel,pos={8,208},size={376,96},title=zlabel
1291  Slider sl_zslice_position win=$panel,pos={16,232},size={240,56},proc=PearlAreaDisplay#slp_slice_position
1292  Slider sl_zslice_position win=$panel,limits={0,100,1},variable=z_slice_pos,vert= 0
1293  SetVariable sv_zslice_position win=$panel,pos={20,280},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Z"
1294  SetVariable sv_zslice_position win=$panel,limits={0,100,1},value=z_slice_pos
1295  Button b_zslice_center win=$panel,pos={122,280},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
1296  Button b_zslice_center win=$panel,help={"reset to center position"}
1297  Button b_zslice_extract win=$panel,pos={288,280},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
1298  Button b_zslice_extract win=$panel,help={"extract this slice to a separate wave"}
1299  //CheckBox cb_zslab_active win=$panel,pos={288,280},size={80,16},title="Display Z Slab"
1300  //CheckBox cb_zslab_active win=$panel,value= 0
1301  TitleBox tb_zslice_animation win=$panel,pos={288,232},size={356,16},title="animation",frame=0
1302  TitleBox tb_zslice_animation win=$panel,anchor= MC
1303  Button b_zslice_back win=$panel,pos={288,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
1304  Button b_zslice_back win=$panel,help={"animate backwards"}
1305  Button b_zslice_forward win=$panel,pos={312,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
1306  Button b_zslice_forward win=$panel,help={"animate forward"}
1307  Button b_zslice_stop win=$panel,pos={336,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
1308  Button b_zslice_stop win=$panel,help={"stop animation"}
1309 
1310  TitleBox t_slicerpath win=$panel,pos={8,316},size={128,20},disable=2,title=dlabel
1311  //SetVariable setvar0 win=$panel,pos={240,316},size={120,16},title="slab thickness"
1312  //SetVariable setvar0 win=$panel,limits={1,inf,1},value=slab_thickness
1313 
1314  // update control limits and move slicing planes to the center
1315  setwindow $panel, userdata(control_datafolder) = GetDataFolder(1, viewdf)
1316  setwindow $panel, userdata(brick_path) = brick_path
1317  update_slice_info()
1318  x_slice_pos = dimoffset(data, 0) + dimsize(data, 0) * dimdelta(data, 0) / 2
1319  y_slice_pos = dimoffset(data, 1) + dimsize(data, 1) * dimdelta(data, 1) / 2
1320  z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
1321 
1322  svar /z /sdfr=viewdf gizmo_graphname
1323  if (svar_exists(gizmo_graphname) && (strlen(gizmo_graphname) > 0) && (wintype(gizmo_graphname) == 13))
1324  ad_gizmo_set_plane(data, 0, x_slice_pos)
1325  ad_gizmo_set_plane(data, 1, y_slice_pos)
1326  ad_gizmo_set_plane(data, 2, z_slice_pos)
1327  endif
1328  svar /z /sdfr=viewdf slice_graphname
1329  if (svar_exists(slice_graphname) && (strlen(slice_graphname) > 0) && (wintype(slice_graphname) == 1))
1330  ad_profiles_set_slice(data, 2, z_slice_pos)
1331  endif
1332 
1333  ad_slicer_init_bg()
1334  setdatafolder savedf
1335 end
1336 
1346 function /s ad_display_slice(data)
1347  wave data
1348 
1349  if (WaveDims(data) != 3)
1350  abort "ad_display_slice: data must be three-dimensional."
1351  endif
1352 
1353  dfref savedf = GetDataFolderDFR()
1354  dfref datadf = GetWavesDataFolderDFR(data)
1355  string s_datadf = GetDataFolder(1, datadf)
1356  dfref viewdf = make_view_folder(data)
1357 
1358  setdatafolder viewdf
1359  string dfname = ReplaceString("root:", s_datadf, "")
1360  dfname = dfname[0, strlen(dfname) - 2]
1361  string graphtitle = dfname + " Slice"
1362 
1363  if (exists("slice_graphname") != 2)
1364  string /g slice_graphname = ""
1365  endif
1366  string /g slice_wavename = PearlCleanupName("slice_" + NameOfWave(data))
1367  svar graphname = slice_graphname
1368  svar slicename = slice_wavename
1369 
1370  make /n=(1,1)/o $slicename
1371  wave slice = $slicename
1372  if ((strlen(graphname) == 0) || (wintype(graphname) != 1))
1373  graphname = ad_display_profiles(slice)
1374  endif
1375  variable z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
1376  ad_profiles_set_slice(data, 2, z_slice_pos)
1377  ad_profiles_set_cursor(slice, "A", -inf, -inf, pscale=1)
1378  ad_profiles_set_cursor(slice, "B", +inf, +inf, pscale=1)
1379 
1380  setdatafolder savedf
1381  return graphname
1382 end
1383 
1387 static function update_slice_info()
1388  dfref savedf = GetDataFolderDFR()
1389 
1390  svar brick_path
1391  //svar slicer_panelname
1392  wave brick = $brick_path
1393 
1394  //dowindow /F $slicer_panelname
1395  variable lo, hi, inc
1396  lo = dimoffset(brick, 0)
1397  inc = dimdelta(brick, 0)
1398  hi = lo + inc * (dimsize(brick, 0) - 1)
1399  Slider sl_xslice_position,limits={lo,hi,inc}
1400  SetVariable sv_xslice_position,limits={lo,hi,inc}
1401  lo = dimoffset(brick, 1)
1402  inc = dimdelta(brick, 1)
1403  hi = lo + inc * (dimsize(brick, 1) - 1)
1404  Slider sl_yslice_position,limits={lo,hi,inc}
1405  SetVariable sv_yslice_position,limits={lo,hi,inc}
1406  lo = dimoffset(brick, 2)
1407  inc = dimdelta(brick, 2)
1408  hi = lo + inc * (dimsize(brick, 2) - 1)
1409  Slider sl_zslice_position,limits={lo,hi,inc}
1410  SetVariable sv_zslice_position,limits={lo,hi,inc}
1411 
1412  setdatafolder savedf
1413 end
1414 
1423 function ad_gizmo_set_plane(brick, dim, value)
1424  wave brick
1425  variable dim
1426  variable value
1427 
1428  dfref savedf = GetDataFolderDFR()
1429  dfref datadf = GetWavesDataFolderDFR(brick)
1430  dfref viewdf = get_view_folder(brick)
1431  svar /z /sdfr=viewdf graphname=gizmo_graphname
1432 
1433  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
1434  if ((pp < 0) || (pp >= dimsize(brick, dim)))
1435  return -1 // requested value out of range
1436  endif
1437 
1438  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 13))
1439  string axes = "xyz"
1440  string obj = "surface_" + axes[dim] + "mid"
1441  string cmd
1442  sprintf cmd, "ModifyGizmo /N=%s ModifyObject=%s, property={plane, %d}", graphname, obj, pp
1443  execute /q cmd
1444  else
1445  return -2 // gizmo window not found
1446  endif
1447 
1448  return 0
1449 end
1450 
1459 function ad_profiles_set_slice(brick, dim, value)
1460  wave brick
1461  variable dim
1462  variable value
1463 
1464  dfref savedf = GetDataFolderDFR()
1465  dfref datadf = GetWavesDataFolderDFR(brick)
1466  dfref viewdf = get_view_folder(brick)
1467  svar /z /sdfr=viewdf graphname = slice_graphname
1468  svar /z /sdfr=viewdf slicename = slice_wavename
1469 
1470  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
1471  if ((pp < 0) || (pp >= dimsize(brick, dim)))
1472  return -1 // requested value out of range
1473  endif
1474 
1475  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 1))
1476  setdatafolder viewdf
1477  switch(dim)
1478  case 0: // X
1479  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
1480  ad_update_profiles(wdest)
1481  break
1482  case 1: // Y
1483  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
1484  ad_update_profiles(wdest)
1485  break
1486  case 2: // Z
1487  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
1488  ad_update_profiles(wdest)
1489  break
1490  endswitch
1491  else
1492  return -2 // graph window not found
1493  endif
1494 
1495  setdatafolder savedf
1496  return 0
1497 end
1498 
1500 static function slp_slice_position(sa) : SliderControl
1501  STRUCT WMSliderAction &sa
1502 
1503  dfref savedf = GetDataFolderDFR()
1504 
1505  switch( sa.eventCode )
1506  case -1: // control being killed
1507  break
1508  default:
1509  if( sa.eventCode & 1 ) // value set
1510  string control_datafolder = GetUserData(sa.win, "", "control_datafolder")
1511  setdatafolder control_datafolder
1512  string brick_path = GetUserData(sa.win, "", "brick_path")
1513  string axis = StringFromList(1, sa.ctrlName, "_")
1514  variable dim = char2num(axis[0]) - char2num("x")
1515 
1516  wave /z brick = $brick_path
1517  if (WaveExists(brick))
1518  ad_gizmo_set_plane(brick, dim, sa.curval)
1519  ad_profiles_set_slice(brick, dim, sa.curval)
1520  else
1521  Abort "can't find original wave " + brick_path
1522  endif
1523  endif
1524  break
1525  endswitch
1526 
1527  setdatafolder savedf
1528  return 0
1529 End
1530 
1532 static function svp_slice_position(sva) : SetVariableControl
1533  STRUCT WMSetVariableAction &sva
1534 
1535  dfref savedf = GetDataFolderDFR()
1536 
1537  switch( sva.eventCode )
1538  case 1: // mouse up
1539  case 2: // Enter key
1540  case 3: // Live update
1541  string control_datafolder = GetUserData(sva.win, "", "control_datafolder")
1542  setdatafolder control_datafolder
1543  string brick_path = GetUserData(sva.win, "", "brick_path")
1544  string axis = StringFromList(1, sva.ctrlName, "_")
1545  variable dim = char2num(axis[0]) - char2num("x")
1546 
1547  wave /z brick = $brick_path
1548  if (WaveExists(brick))
1549  ad_gizmo_set_plane(brick, dim, sva.dval)
1550  ad_profiles_set_slice(brick, dim, sva.dval)
1551  else
1552  Abort "can't find original wave " + brick_path
1553  endif
1554  break
1555  case -1: // control being killed
1556  break
1557  endswitch
1558 
1559  setdatafolder savedf
1560  return 0
1561 End
1562 
1564 static function bp_move_slice(ba) : ButtonControl
1565  STRUCT WMButtonAction &ba
1566 
1567  dfref savedf = GetDataFolderDFR()
1568 
1569  switch( ba.eventCode )
1570  case 2: // mouse up
1571  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
1572  setdatafolder control_datafolder
1573  string brick_path = GetUserData(ba.win, "", "brick_path")
1574  string axis = StringFromList(1, ba.ctrlName, "_")
1575  string cmd = StringFromList(2, ba.ctrlName, "_")
1576  variable dim = char2num(axis[0]) - char2num("x")
1577  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
1578  nvar pos = $(posvariable)
1579 
1580  wave /z brick = $brick_path
1581  if (WaveExists(brick))
1582  strswitch (cmd)
1583  case "forward":
1584  ad_slicer_start_bg(brick, dim, posvariable, dimdelta(brick, dim))
1585  break
1586  case "back":
1587  ad_slicer_start_bg(brick, dim, posvariable, -dimdelta(brick, dim))
1588  break
1589  case "center":
1590  ad_slicer_stop_bg(posvariable)
1591  bp_move_slice_center(brick, dim, posvariable)
1592  break
1593  case "stop":
1594  ad_slicer_stop_bg(posvariable)
1595  break
1596  endswitch
1597  else
1598  ad_slicer_stop_bg(posvariable)
1599  Abort "can't find original wave " + brick_path
1600  endif
1601  break
1602  case -1: // control being killed
1603  break
1604  endswitch
1605 
1606  setdatafolder savedf
1607  return 0
1608 End
1609 
1613 static function bp_extract_slice(ba) : ButtonControl
1614  STRUCT WMButtonAction &ba
1615 
1616  dfref savedf = GetDataFolderDFR()
1617 
1618  switch( ba.eventCode )
1619  case 2: // mouse up
1620  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
1621  setdatafolder control_datafolder
1622  string brick_path = GetUserData(ba.win, "", "brick_path")
1623  wave brick = $brick_path
1624  dfref brickdf = GetWavesDataFolderDFR(brick)
1625 
1626  string axis = StringFromList(1, ba.ctrlName, "_")
1627  string cmd = StringFromList(2, ba.ctrlName, "_")
1628  variable dim = char2num(axis[0]) - char2num("x")
1629  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
1630 
1631  nvar pos = $(posvariable)
1632  variable pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
1633  if ((pp < 0) || (pp >= dimsize(brick, dim)))
1634  return -1 // requested value out of range
1635  endif
1636 
1637  variable dig = ceil(log(dimsize(brick, dim)))
1638  string slicename
1639  sprintf slicename, "%s_%s%0*u", NameOfWave(brick), axis[0], dig, pp
1640  setdatafolder brickdf
1641  switch(dim)
1642  case 0: // X
1643  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
1644  break
1645  case 1: // Y
1646  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
1647  break
1648  case 2: // Z
1649  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
1650  break
1651  endswitch
1652 
1653  string msg
1654  sprintf msg, "%s=%g", axis[0], pos
1655  note wdest, msg
1656 
1657  break
1658  case -1: // control being killed
1659  break
1660  endswitch
1661 
1662  setdatafolder savedf
1663  return 0
1664 End
1665 
1667 static function bp_move_slice_center(brick, dim, posvariable)
1668  wave brick
1669  variable dim
1670  string posvariable
1671 
1672  nvar pos = $posvariable
1673  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * dimsize(brick, dim) / 2
1674  ad_gizmo_set_plane(brick, dim, pos)
1675  ad_profiles_set_slice(brick, dim, pos)
1676 end
1677 
1679 static function ad_slicer_move_bg(s)
1680  STRUCT WMBackgroundStruct &s
1681 
1682  dfref savedf = GetDataFolderDFR()
1683  setdatafolder root:pearl_area:slicer
1684  wave /t bg_brickpaths
1685  wave /t bg_graphnames
1686  wave /t bg_variablepaths
1687  wave bg_dimensions
1688  wave bg_increments
1689 
1690  variable ii
1691  variable nn = numpnts(bg_brickpaths)
1692  variable dim
1693  variable pp
1694 
1695  for (ii = 0; ii < nn; ii += 1)
1696  wave /z brick = $bg_brickpaths[ii]
1697  nvar /z pos = $bg_variablepaths[ii]
1698  dim = bg_dimensions[0]
1699  pos += bg_increments[ii]
1700  // wrap around at limits
1701  pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
1702  if (pp <= -0.5)
1703  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * (dimsize(brick, dim) - 1)
1704  elseif (pp >= dimsize(brick, dim) - 0.5)
1705  pos = dimoffset(brick, dim)
1706  endif
1707  if (waveexists(brick))
1708  ad_gizmo_set_plane(brick, dim, pos)
1709  ad_profiles_set_slice(brick, dim, pos)
1710  endif
1711  endfor
1712 
1713  setdatafolder savedf
1714  return 0
1715 End
1716 
1718 function ad_slicer_init_bg()
1719  dfref savedf = GetDataFolderDFR()
1720  setdatafolder root:
1721  newdatafolder /o/s pearl_area
1722  newdatafolder /o/s slicer
1723 
1724  make /n=0/o/t bg_brickpaths
1725  make /n=0/o/t bg_variablepaths
1726  make /n=0/o/i/u bg_dimensions
1727  make /n=0/o bg_increments
1728 
1729  CtrlNamedBackground ad_slicer, period = 30, proc = PearlAreaDisplay#ad_slicer_move_bg
1730 
1731  setdatafolder savedf
1732  return 0
1733 end
1734 
1742 function ad_slicer_start_bg(brick, dimension, posvariable, delta)
1743  wave brick // 3D data wave
1744  variable dimension // dimension to animate, 0, 1, or 2
1745  string posvariable // full path to the global position variable
1746  variable delta // step increment, should be +/- dimdelta
1747 
1748  dfref savedf = GetDataFolderDFR()
1749  setdatafolder root:pearl_area:slicer
1750  wave /t bg_brickpaths
1751  wave /t bg_variablepaths
1752  wave bg_dimensions
1753  wave bg_increments
1754 
1755  // create entry in ad_slicer background task table
1756  variable idx
1757  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
1758  if (v_value >= 0)
1759  idx = v_value
1760  else
1761  idx = numpnts(bg_variablepaths)
1762  InsertPoints idx, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
1763  endif
1764 
1765  // set background task
1766  bg_brickpaths[idx] = GetWavesDataFolder(brick, 2)
1767  bg_variablepaths[idx] = posvariable
1768  bg_dimensions[idx] = dimension
1769  bg_increments[idx] = delta
1770 
1771  // start background task
1772  if (numpnts(bg_variablepaths) > 0)
1773  CtrlNamedBackground ad_slicer, start
1774  endif
1775 
1776  setdatafolder savedf
1777  return 0
1778 end
1779 
1784 function ad_slicer_stop_bg(posvariable)
1785  string posvariable
1786 
1787  dfref savedf = GetDataFolderDFR()
1788  setdatafolder root:pearl_area:slicer
1789  wave /t bg_brickpaths
1790  wave /t bg_variablepaths
1791  wave bg_dimensions
1792  wave bg_increments
1793 
1794  // find entry in ad_slicer background task table
1795  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
1796  if (v_value >= 0)
1797  DeletePoints v_value, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
1798  endif
1799 
1800  // stop background task if task table is empty
1801  if (numpnts(bg_variablepaths) == 0)
1802  CtrlNamedBackground ad_slicer, stop
1803  endif
1804 
1805  setdatafolder savedf
1806  return 0
1807 end
variable ad_profiles_cursor_mode(wave image, variable mode)
switch cursors on a profiles graph
static variable set_trace_colors(string graphname)
variable ad_profiles_crosshairs(wave image, variable clear=defaultValue)
draw permanent crosshairs in a profiles graph.
variable ad_update_profiles(wave image)
update a profiles graph with new data.
variable ad_default_image_filter(wave image, string options)
abstract filter function for image display.
static variable svp_smoothing(WMSetVariableAction *sva)
static dfr get_view_folder(wave source)
find the view data folder corresponding to the given source.
variable ad_calc_histogram(wave image)
calculate the histogram.
static dfr make_view_folder(wave source)
create a view data folder.
string PearlCleanupName(string name)
variable ad_calc_profiles(wave image, variable pa, variable qa, variable pb, variable qb)
calculate profiles, statistics, and histogram of a rectangular region of interest.
variable ad_profiles_set_cursor(wave image, string cursorname, variable xa, variable ya, variable pscale=defaultValue)
move a cursor to the specified position in a profiles graph.
static wave get_view_image(wave source)
find the view image wave corresponding to the given source.
instant visualization of angle scan and manipulator position.
static variable pmp_export(WMPopupAction *pa)
static wave get_source_image(wave view)
find the source image wave corresponding to the given view.
string ad_display_histogram(wave image)
display the histogram of a 2D image.
string ad_display(wave image)
open a new graph window with a 2D image.
static string graphname_from_dfref(dfref df, string prefix)
compose a valid and unique graph name from a data folder reference
variable ad_calc_cursor_profiles(wave image)
calculate profiles, statistics, and histogram of a cross-hair delimited region of interest...
string ad_display_profiles(wave image, string filter=defaultValue)
open a new profiles graph window.
static variable bp_reset_cursors(WMButtonAction *ba)
variable ad_export_profile(wave view_image, variable dim, variable trace=defaultValue, variable show=defaultValue, variable overwrite=defaultValue)
export a profile from a profiles graph to the source data folder.
variable ad_transpose_filter(wave image, string options)
transpose image filter.
string ad_display_slice(wave data)
display three-dimensional data by 2D slice.
variable ad_box_filter(wave image, string options)
boxcar smoothing filter.
string ad_display_brick(wave data)
open a new "gizmo" window with three-dimensional data.
variable ad_profiles_hook(WMWinHookStruct *s)
hook function for user events in the profiles window.