PEARL Procedures  rev-distro-2.1.0-1-gb7390cb-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 
329 function /wave ad_add_overlay(image, [rgba])
330  wave image
331  string rgba
332 
333  if (ParamIsDefault(rgba))
334  rgba = "65535,65532,16385,32767"
335  elseif (ItemsInList(rgba, ",") == 3)
336  rgba += ",32767"
337  endif
338 
339  dfref savedf = GetDataFolderDFR()
340  wave view_image = get_view_image(image)
341  dfref viewdf = GetWavesDataFolderDFR(view_image)
342  svar /sdfr=viewdf graphname = prof_graphname
343  setdatafolder viewdf
344 
345  string overlayname = "view_overlay"
346  duplicate /o image, $overlayname /wave=overlay
347  redimension /b/u overlay
348  overlay = 64
349 
350  string imagenames = ImageNameList(graphname, ";")
351  if (whichlistItem(overlayname, imagenames, ";") < 0)
352  AppendImage /w=$graphname $overlayname
353  rgba = replacestring("(", rgba, "")
354  rgba = replacestring(")", rgba, "")
355  variable rr = str2num(StringFromList(0, rgba, ","))
356  variable gg = str2num(StringFromList(1, rgba, ","))
357  variable bb = str2num(StringFromList(2, rgba, ","))
358  variable aa = str2num(StringFromList(3, rgba, ","))
359 #if IgorVersion() >= 8
360  ModifyImage /w=$graphname $overlayname explicit=1,eval={0,rr,gg,bb,aa},eval={255,-1,-1,-1}
361 #else
362  ModifyImage /w=$graphname $overlayname explicit=1,eval={0,rr,gg,bb},eval={255,-1,-1,-1}
363 #endif
364  endif
365 
366  setdatafolder savedf
367  return overlay
368 end
369 
375 function ad_update_profiles(image)
376  wave image
377 
378  // data folders and references
379  dfref viewdf = get_view_folder(image)
380  if (DataFolderRefStatus(viewdf) == 0)
381  return -1 // data folder not found
382  endif
383  dfref savedf = GetDataFolderDFR()
384  setdatafolder viewdf
385 
386  // data structures
387  string viewname = "view_image"
388  duplicate /o image, $viewname /wave=view
389  string overlayname = "view_overlay"
390  wave /z overlay = $overlayname
391  if (waveexists(overlay))
392  redimension /n=(dimsize(view,0), dimsize(view,1)) overlay
393  endif
394 
395  // data processing
396  svar view_filter
397  svar view_filter_options
398  nvar smoothing_x = view_filter_smoothing_x
399  nvar smoothing_y = view_filter_smoothing_y
400  funcref ad_default_image_filter filterfunc = $view_filter
401  view_filter_options = ReplaceNumberByKey("SmoothingX", view_filter_options, smoothing_x, "=", ";")
402  view_filter_options = ReplaceNumberByKey("SmoothingY", view_filter_options, smoothing_y, "=", ";")
403  filterfunc(view, view_filter_options)
404 
406 
407  setdatafolder savedf
408  return 0
409 end
410 
427 function ad_profiles_cursor_mode(image, mode)
428  wave image
429  variable mode
430 
431  dfref savedf = GetDataFolderDFR()
432  wave view_image = get_view_image(image)
433  dfref viewdf = GetWavesDataFolderDFR(view_image)
434  svar /sdfr=viewdf graphname = prof_graphname
435  nvar /sdfr=viewdf cursor_mode = view_cursor_mode
436  wave /sdfr=viewdf xprofiles, yprofiles
437 
438  variable dx = DimSize(view_image, 0)
439  variable dy = DimSize(view_image, 1)
440  switch(mode)
441  case 1: // background selection
442  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 A view_image 0, 0
443  Cursor /w=$graphname /A=0 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
444  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 C view_image round(0.2 * dx) -1, 0
445  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 D view_image round(0.8 * dx) -1, 0
446  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 E view_image round(0.4 * dx) -1, 0
447  Cursor /w=$graphname /A=0 /P /I /S=2 /H=2 /L=1 F view_image round(0.6 * dx) -1, 0
448 
449  ShowInfo /w=$graphname /CP=0
450  cursor_mode = mode
451  break
452  default:
453  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 A view_image 0,0
454  Cursor /w=$graphname /A=1 /P /I /S=2 /H=1 /L=1 B view_image dx-1, dy-1
455  variable pcurs
456  pcurs = floor(DimSize(xprofiles, 0) / 3)
457  Cursor /w=$graphname /A=0 /P /S=1 /H=0 C xprofiles#2 pcurs
458  pcurs = floor(DimSize(xprofiles, 0) * 2 / 3)
459  Cursor /w=$graphname /A=0 /P /S=1 /H=0 D xprofiles#2 pcurs
460  pcurs = floor(DimSize(yprofiles, 0) / 3)
461  Cursor /w=$graphname /A=0 /P /S=1 /H=0 E yprofiles#2 pcurs
462  pcurs = floor(DimSize(yprofiles, 0) * 2 / 3)
463  Cursor /w=$graphname /A=0 /P /S=1 /H=0 F yprofiles#2 pcurs
464  ShowInfo /w=$graphname /CP=0
465  cursor_mode = 0
466  endswitch
467 
468  setdatafolder savedf
469  return 0
470 end
471 
488 function ad_profiles_set_cursor(image, cursorname, xa, ya, [pscale])
489  wave image
490  string cursorname
491  variable xa, ya
492  variable pscale
493 
494  if (ParamIsDefault(pscale))
495  pscale = 0
496  endif
497 
498  // data folders and references
499  dfref savedf = GetDataFolderDFR()
500  wave view_image = get_view_image(image)
501  dfref viewdf = GetWavesDataFolderDFR(view_image)
502  svar /sdfr=viewdf graphname = prof_graphname
503 
504  variable pa, qa
505  if (pscale)
506  pa = xa
507  qa = ya
508  else
509  pa = round((xa - DimOffset(view_image, 0)) / DimDelta(view_image, 0))
510  qa = round((ya - DimOffset(view_image, 1)) / DimDelta(view_image, 1))
511  endif
512 
513  pa = min(pa, DimSize(view_image, 0) - 1)
514  pa = max(pa, 0)
515  qa = min(qa, DimSize(view_image, 1) - 1)
516  qa = max(qa, 0)
517  Cursor /i /p /w=$graphname $cursorname view_image pa, qa
518 
519  setdatafolder savedf
520  return 0
521 End
522 
533 // the lines can be removed manually using the draw toolbox, or by calling this function with @c clean=1.
540 function ad_profiles_crosshairs(image, [clear])
541  wave image
542  variable clear
543 
544  if (ParamIsDefault(clear))
545  clear = 0
546  endif
547 
548  // data folders and references
549  wave view_image = get_view_image(image)
550  dfref viewdf = GetWavesDataFolderDFR(view_image)
551  svar /sdfr=viewdf graphname = prof_graphname
552 
553  string cursors = "A;B"
554  string colors = "39168,0,0;0,26112,0"
555  string color
556  variable ncursors
557  variable icursor
558  string cursorname
559  string groupname = "crosshairs"
560  variable xx, yy
561  struct RGBColor rgb
562 
563  if (clear == 0)
564  SetDrawEnv /W=$graphname push
565  DrawAction /w=$graphname getgroup=$groupname, delete, begininsert
566  SetDrawEnv /w=$graphname gstart, gname=$groupname
567 
568  SetDrawEnv /W=$graphname dash=4
569  SetDrawEnv /W=$graphname linethick=0.5
570 
571  ncursors = ItemsInList(cursors, ";")
572  for (icursor=0; icursor < ncursors; icursor += 1)
573  cursorname = StringFromList(icursor, cursors, ";")
574  color = StringFromList(icursor, colors, ";")
575  rgb.red = str2num(StringFromList(0, color, ","))
576  rgb.green = str2num(StringFromList(1, color, ","))
577  rgb.blue = str2num(StringFromList(2, color, ","))
578  if (strlen(CsrInfo($cursorname, graphname)) > 0)
579  xx = hcsr($cursorname, graphname)
580  yy = vcsr($cursorname, graphname)
581  SetDrawEnv /W=$graphname linefgc=(rgb.red, rgb.green, rgb.blue)
582  SetDrawEnv /W=$graphname save
583  SetDrawEnv /W=$graphname xcoord=bottom, ycoord=prel
584  DrawLine /W=$graphname xx, 0, xx, 1
585  SetDrawEnv /W=$graphname xcoord=prel, ycoord=left
586  DrawLine /W=$graphname 0, yy, 1, yy
587  endif
588  endfor
589 
590  SetDrawEnv /w=$graphname gstop
591  DrawAction /w=$graphname endinsert
592  SetDrawEnv /W=$graphname pop
593  SetDrawEnv /W=$graphname save
594  else
595  DrawAction /w=$graphname getgroup=$groupname, delete
596  endif
597 
598  return 0
599 end
600 
606 static function /wave get_source_image(view)
607  wave view // image wave displayed in a profiles window
608 
609  dfref viewdf = GetWavesDataFolderDFR(view)
610  svar /z /sdfr=viewdf sourcepath
611  if (svar_exists(sourcepath))
612  wave /z img = $sourcepath
613  else
614  wave /z img = $""
615  endif
616  return img
617 end
618 
620 static function /df make_view_folder(source)
621  wave source // wave which contains the raw data from the detector.
622 
623  // data folders and references
624  dfref savedf = GetDataFolderDFR()
625  dfref imagedf = GetWavesDataFolderDFR(source)
626  string s_imagedf = GetDataFolder(1, imagedf)
627  setdatafolder imagedf
628  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
629  newdatafolder /o/s $s_viewdf
630  dfref viewdf = GetDataFolderDFR()
631 
632  setdatafolder savedf
633  return viewdf
634 end
635 
644 static function /df get_view_folder(source)
645  wave source
646 
647  // data folders and references
648  dfref savedf = GetDataFolderDFR()
649  dfref imagedf = GetWavesDataFolderDFR(source)
650  dfref viewdf
651  setdatafolder imagedf
652  string s_viewdf = PearlCleanupName("view_" + NameOfWave(source))
653  if (DataFolderExists(s_viewdf))
654  setdatafolder $s_viewdf
655  viewdf = GetDataFolderDFR()
656  endif
657 
658  setdatafolder savedf
659  return viewdf
660 end
661 
667 static function /wave get_view_image(source)
668  wave source
669 
670  dfref viewdf = get_view_folder(source)
671  string viewname = "view_image"
672  wave /sdfr=viewdf view = $viewname
673 
674  return view
675 end
676 
677 static function bp_reset_cursors(ba) : ButtonControl
678  STRUCT WMButtonAction &ba
679 
680  switch( ba.eventCode )
681  case 2: // mouse up
682  string imgname = StringFromList(0, ImageNameList(ba.win, ";"))
683  wave /z image = ImageNameToWaveRef(ba.win, imgname)
684  if (waveexists(image))
685  Cursor /i/p A $imgname 0,0
686  Cursor /i/p B $imgname DimSize(image, 0)-1, DimSize(image, 1)-1
687  endif
688  break
689  case -1: // control being killed
690  break
691  endswitch
692 
693  return 0
694 End
695 
696 static function svp_smoothing(sva) : SetVariableControl
697  STRUCT WMSetVariableAction &sva
698 
699  string imglist
700 
701  switch( sva.eventCode )
702  case 1: // mouse up
703  case 2: // Enter key
704  case 3: // Live update
705  imglist = ImageNameList(sva.win, ";")
706  wave /z img = ImageNameToWaveRef(sva.win, StringFromList(0, imglist))
707  if (WaveExists(img))
708  wave source = get_source_image(img)
709  if (WaveExists(source))
710  ad_update_profiles(source)
711  endif
712  endif
713  break
714  case -1: // control being killed
715  break
716  endswitch
717 
718  return 0
719 end
720 
721 static function pmp_export(pa) : PopupMenuControl
722  STRUCT WMPopupAction &pa
723 
724  switch( pa.eventCode )
725  case 2: // mouse up
726  variable popNum = pa.popNum
727 
728  string imgname = StringFromList(0, ImageNameList(pa.win, ";"))
729  wave /z image = ImageNameToWaveRef(pa.win, imgname)
730  if (waveexists(image) && (popNum >= 1) && (popNum <= 2))
731  ad_export_profile(image, popNum - 1, show=1)
732  elseif (waveexists(image) && (popNum >= 3) && (popNum <= 4))
733  ad_export_profile(image, popNum - 3, show=2)
734  endif
735 
736  break
737  case -1: // control being killed
738  break
739  endswitch
740 
741  return 0
742 End
743 
745 function ad_profiles_hook(s)
746  struct WMWinHookStruct &s
747  variable hookresult = 0
748  string imglist
749  string cmd
750  dfref viewdf
751 
752  switch(s.eventCode)
753  case 2: // delete data folder after window is killed
754  imglist = ImageNameList(s.winName, ";")
755  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
756  if (WaveExists(img))
757  viewdf = GetWavesDataFolderDFR(img)
758  cmd = "killdatafolder /z " + GetDataFolder(1, viewdf)
759  Execute /P/Q/Z cmd
760  endif
761  break
762  case 7: // update profiles when cursor is moved
763  imglist = ImageNameList(s.winName, ";")
764  wave /z img = ImageNameToWaveRef(s.winName, StringFromList(0, imglist))
765  if (WaveExists(img))
767  hookresult = 1
768  else
769  hookresult = 0
770  endif
771  break
772  endswitch
773 
774  return hookresult
775 end
776 
785 function ad_calc_cursor_profiles(image)
786  wave image
787 
788  dfref savedf = GetDataFolderDFR()
789  dfref imagedf = GetWavesDataFolderDFR(image)
790  setdatafolder imagedf
791 
792  svar graphname = prof_graphname
793 
794  variable pa, qa // point coordinates cursor A
795  if (strlen(CsrInfo(A, graphname)) > 0)
796  pa = pcsr(A, graphname)
797  qa = qcsr(A, graphname)
798  else
799  pa = 0
800  qa = 0
801  endif
802 
803  variable pb, qb // point coordinates cursor B
804  if (strlen(CsrInfo(B, graphname)) > 0)
805  pb = pcsr(B, graphname)
806  qb = qcsr(B, graphname)
807  else
808  pb = DimSize(image, 0) - 1
809  qb = DimSize(image, 1) - 1
810  endif
811 
812  ad_calc_profiles(image, pa, qa, pb, qb)
813  setdatafolder savedf
814 end
815 
832 function ad_calc_profiles(image, pa, qa, pb, qb)
833  wave image
834  variable pa, qa
835  variable pb, qb
836 
837  dfref savedf = GetDataFolderDFR()
838  dfref imagedf = GetWavesDataFolderDFR(image)
839  setdatafolder imagedf
840 
841  wave xprofiles
842  wave yprofiles
843  nvar graph_avg
844  nvar graph_min
845  nvar graph_max
846  nvar graph_sum
847  nvar graph_sdev
848 
849  // horizontal profiles at crosshairs
850  redimension /n=(dimsize(image,0), 3) xprofiles
851  setscale /p x dimoffset(image,0), dimdelta(image,0), WaveUnits(image,0), xprofiles
852  setscale d 0, 0, waveunits(image,-1), xprofiles
853  xprofiles[][0] = image[p][qa]
854  xprofiles[][1] = image[p][qb]
855 
856  note /k xprofiles
857  note xprofiles, "SourceWave=" + nameofwave(image)
858  note xprofiles, "SourceDimension=0"
859  note xprofiles, "SourceIndex0=" + num2str(qa)
860  note xprofiles, "SourceIndex1=" + num2str(qb)
861 
862  // average horizontal profile between crosshairs
863  variable qq, q0, q1
864  q0 = min(qa, qb)
865  q1 = max(qa, qb)
866  xprofiles[][2] = 0
867  for (qq = q0; qq <= q1; qq += 1)
868  xprofiles[][2] += image[p][qq]
869  endfor
870  xprofiles[][2] /= q1 - q0 + 1
871 
872  // vertical profiles at crosshairs
873  redimension /n=(dimsize(image,1), 3) yprofiles
874  setscale /p x dimoffset(image,1), dimdelta(image,1), WaveUnits(image,1), yprofiles
875  setscale d 0, 0, waveunits(image,-1), yprofiles
876  yprofiles[][0] = image[pa][p]
877  yprofiles[][1] = image[pb][p]
878 
879  note /k yprofiles
880  note yprofiles, "SourceWave=" + nameofwave(image)
881  note yprofiles, "SourceDimension=1"
882  note yprofiles, "SourceIndex0=" + num2str(pa)
883  note yprofiles, "SourceIndex1=" + num2str(pb)
884 
885  // average vertical profile between crosshairs
886  variable pp, p0, p1
887  p0 = min(pa, pb)
888  p1 = max(pa, pb)
889  yprofiles[][2] = 0
890  for (pp = p0; pp <= p1; pp += 1)
891  yprofiles[][2] += image[pp][p]
892  endfor
893  yprofiles[][2] /= p1 - p0 + 1
894 
895  // statistics between crosshairs
896  Duplicate /r=[p0,p1][q0,q1]/o image, roi_image
897  WaveStats /Q roi_image
898  graph_avg = v_avg
899  graph_min = v_min
900  graph_max = v_max
901  graph_sum = v_avg * v_npnts
902  graph_sdev = v_sdev
903 
904  // histogram
905  wave /z hist
906  if (waveexists(hist))
907  Histogram /B=3 roi_image, hist
908  endif
909 
910  setdatafolder savedf
911 end
912 
934 function ad_export_profile(view_image, dim, [trace, show, overwrite])
935  wave view_image
936  variable dim
937  variable trace
938  variable show
939  variable overwrite
940 
941  dfref savedf = GetDataFolderDFR()
942 
943  if (ParamIsDefault(trace))
944  trace = 2
945  endif
946  if (ParamIsDefault(show))
947  show = 0
948  endif
949  if (ParamIsDefault(overwrite))
950  overwrite = 0
951  endif
952 
953  // view folder
954  dfref imagedf = GetWavesDataFolderDFR(view_image)
955  string dim_label
956  switch(dim)
957  case 0:
958  wave /sdfr=imagedf profiles=xprofiles
959  dim_label = "x"
960  break
961  case 1:
962  wave /sdfr=imagedf profiles=yprofiles
963  dim_label = "y"
964  break
965  default:
966  return -1 // invalid argument
967  endswitch
968  string graphname_string = "export_graph_" + dim_label
969  svar /z /sdfr=imagedf linked_graphname = $graphname_string
970 
971  // source folder
972  wave /z source_image = get_source_image(view_image)
973  if (WaveExists(source_image))
974  dfref sourcedf = GetWavesDataFolderDFR(source_image)
975  setdatafolder sourcedf
976  else
977  return -2 // invalid source data folder
978  endif
979 
980  // format dest wave name
981  string profile_note = note(profiles)
982  string name_base
983  string name_dim
984  string name_index
985  string profile_name
986  variable index_width = ceil(log(DimSize(view_image, 1 - dim)))
987  variable index0 = NumberByKey("SourceIndex0", profile_note, "=", "\r")
988  variable index1 = NumberByKey("SourceIndex1", profile_note, "=", "\r")
989  name_dim = "_" + dim_label
990  sprintf name_index, "%0*u_%0*u", index_width, index0, index_width, index1
991  name_base = NameOfWave(source_image)
992  name_base = name_base[0, min(strlen(name_base), 31 - strlen(name_index) - strlen(name_dim) - 1)]
993  profile_name = name_base + name_dim + name_index
994  if ((overwrite == 0) && (CheckName(profile_name, 1)))
995  profile_name = UniqueName(profile_name + "_", 1, 0)
996  endif
997 
998  // create dest wave
999  duplicate /o /r=[][trace] profiles, $profile_name /wave=dest_profile
1000  redimension /n=(dimsize(profiles, 0)) dest_profile
1001  profile_note = ReplaceStringByKey("SourceWave", profile_note, NameOfWave(source_image), "=", "\r")
1002  note /k dest_profile
1003  note dest_profile, profile_note
1004  print "created", GetWavesDataFolder(dest_profile, 2)
1005 
1006  if (show)
1007  string graphname
1008  string graphtitle
1009  if (show == 2)
1010  // common graph for all profiles of a dimension
1011  graphname = "export_profiles_" + dim_label
1012  graphtitle = UpperStr(dim_label) + " Profiles"
1013  else
1014  // one graph per source image
1015  if (svar_exists(linked_graphname) && (ItemsInList(WinList(linked_graphname, ";", "WIN:1"), ";") >= 1))
1016  graphname = linked_graphname
1017  else
1018  graphname = GetWavesDataFolder(source_image, 0) + name_dim
1019  endif
1020  graphtitle = UpperStr(dim_label) + " Profiles: " + GetWavesDataFolder(source_image, 2)
1021  endif
1022 
1023  if ((ItemsInList(WinList(graphname, ";", "WIN:1"), ";") >= 1))
1024  appendtograph /w=$graphname dest_profile
1025  else
1026  setdatafolder imagedf
1027  display /k=1 /n=$graphname dest_profile as graphtitle
1028  graphname = s_name
1029  ModifyGraph /w=$graphname mirror=1,nticks=3,minor=1
1030  ModifyGraph /w=$graphname axThick=0.5,btLen=4
1031  ModifyGraph /w=$graphname gfSize=10
1032  ModifyGraph /w=$graphname grid=2,gridHair=0,gridRGB=(52224,52224,52224)
1033  Legend /w=$graphname /C/N=legend0/F=0/B=1/A=LT/X=0.00/Y=0.00
1034 
1035  if (show != 2)
1036  string /g $graphname_string = graphname
1037  endif
1038  endif
1039  endif
1040 
1041  setdatafolder savedf
1042  return 0
1043 end
1044 
1045 static function set_trace_colors(graphname)
1046  string graphname
1047 
1048  ModifyGraph /w=$graphname /z rgb[0]=(0, 0, 0)
1049  ModifyGraph /w=$graphname /z rgb[1]=(65535, 16385, 16385)
1050  ModifyGraph /w=$graphname /z rgb[2]=(2, 39321, 1)
1051  ModifyGraph /w=$graphname /z rgb[3]=(0, 0, 65535)
1052  ModifyGraph /w=$graphname /z rgb[4]=(39321, 1, 31457)
1053  ModifyGraph /w=$graphname /z rgb[5]=(48059, 48059, 48059)
1054  ModifyGraph /w=$graphname /z rgb[6]=(65535, 32768, 32768)
1055  ModifyGraph /w=$graphname /z rgb[7]=(0, 65535, 0)
1056  ModifyGraph /w=$graphname /z rgb[8]=(16385,65535,65535)
1057  ModifyGraph /w=$graphname /z rgb[9]=(65535, 32768, 58981)
1058 end
1059 
1066 function ad_calc_histogram(image)
1067  wave image
1068 
1069  dfref savedf = GetDataFolderDFR()
1070  dfref imagedf = GetWavesDataFolderDFR(image)
1071  setdatafolder imagedf
1072 
1073  wave hist
1074  Histogram /B=3 image, hist
1075 
1076  setdatafolder savedf
1077 end
1078 
1089 function ad_default_image_filter(image, options)
1090  wave image
1091  string options
1092 end
1093 
1103 function ad_box_filter(image, options)
1104  wave image
1105  string options
1106 
1107  variable xsmoothing = NumberByKey("SmoothingX", options, "=", ";")
1108  variable ysmoothing = NumberByKey("SmoothingY", options, "=", ";")
1109 
1110  if ((NumType(xsmoothing) == 0) && (xsmoothing >= 2))
1111  Smooth /B /DIM=0 /E=3 xsmoothing, image
1112  endif
1113  if ((NumType(ysmoothing) == 0) && (ysmoothing >= 2))
1114  Smooth /B /DIM=1 /E=3 ysmoothing, image
1115  endif
1116 end
1117 
1125 function ad_transpose_filter(image, options)
1126  wave image
1127  string options
1128 
1129  MatrixTranspose image
1130 end
1131 
1132 
1133 // ################### 3D DATA ##################
1134 
1141 function /s ad_display_brick(data)
1142  wave data
1143 
1144  if(exists("NewGizmo") != 4)
1145  abort "Gizmo XOP must be installed."
1146  endif
1147  if (WaveDims(data) != 3)
1148  abort "ad_display_brick: data must be three-dimensional."
1149  endif
1150 
1151  dfref savedf = GetDataFolderDFR()
1152  dfref datadf = GetWavesDataFolderDFR(data)
1153  string s_datadf = GetDataFolder(1, datadf)
1154  dfref viewdf = make_view_folder(data)
1155 
1156  setdatafolder viewdf
1157  string dfname = ReplaceString("root:", s_datadf, "")
1158  string graphtitle = dfname + " Gizmo"
1159  string /g gizmo_graphname = graphname_from_dfref(datadf, "giz_")
1160  svar graphname = gizmo_graphname
1161 
1162  if ((strlen(graphname) > 0) && (wintype(graphname) == 13))
1163  setdatafolder savedf
1164  return graphname // gizmo window exists
1165  endif
1166 
1167  variable nx = dimsize(data, 0)
1168  variable ny = dimsize(data, 1)
1169  variable nz = dimsize(data, 2)
1170 
1171  variable pp
1172  string obj
1173  string cmd
1174 
1175  // igor does not allow calling gizmo functions directly
1176  setdatafolder datadf
1177  sprintf cmd, "NewGizmo /k=1 /n=%s /w=(100,100,500,400) /t=\"%s\"", graphname, graphtitle
1178  execute /q cmd
1179  cmd = "AppendToGizmo /D Axes=BoxAxes, name=axes0"
1180  execute /q cmd
1181 
1182  obj = "surface_xmid"
1183  pp = round(nx / 2 - 1)
1184  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
1185  execute /q cmd
1186  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 128}", obj
1187  execute /q cmd
1188  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
1189  execute /q cmd
1190  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
1191  execute /q cmd
1192  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
1193  execute /q cmd
1194  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
1195  execute /q cmd
1196 
1197  obj = "surface_ymid"
1198  pp = round(ny / 2 - 1)
1199  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
1200  execute /q cmd
1201  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 64}", obj
1202  execute /q cmd
1203  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
1204  execute /q cmd
1205  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
1206  execute /q cmd
1207  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
1208  execute /q cmd
1209  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
1210  execute /q cmd
1211 
1212  obj = "surface_zmid"
1213  pp = round(nz / 2 - 1)
1214  sprintf cmd, "AppendToGizmo /D surface=%s, name=%s", nameofwave(data), obj
1215  execute /q cmd
1216  sprintf cmd, "ModifyGizmo modifyObject=%s, property={srcMode, 32}", obj
1217  execute /q cmd
1218  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={plane, %d}", obj, pp
1219  execute /q cmd
1220  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCtab, BlueGreenOrange}", obj
1221  execute /q cmd
1222  sprintf cmd, "ModifyGizmo ModifyObject=%s, property={SurfaceCTABScaling,128}", obj
1223  execute /q cmd
1224  sprintf cmd, "ModifyGizmo modifyObject=%s, property={surfaceCTABAlpha, 1.0}", obj
1225  execute /q cmd
1226 
1227  obj = "axes0"
1228  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisScalingMode,1}", obj
1229  execute /q cmd
1230  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={-1,axisColor,0,0,0,1}", obj
1231  execute /q cmd
1232  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={0,ticks,3}", obj
1233  execute /q cmd
1234  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={1,ticks,3}", obj
1235  execute /q cmd
1236  sprintf cmd, "ModifyGizmo ModifyObject=%s,property={2,ticks,3}", obj
1237  execute /q cmd
1238  sprintf cmd, "ModifyGizmo modifyObject=%s property={Clipped,0}", obj
1239  execute /q cmd
1240  sprintf cmd, "ModifyGizmo modifyObject=%s property={-1,fontScaleFactor,2}", obj
1241  execute /q cmd
1242 
1243  sprintf cmd, "ModifyGizmo showAxisCue=1"
1244  execute /q cmd
1245 
1246  setdatafolder savedf
1247  return graphname
1248 end
1249 
1256 function ad_brick_slicer(data)
1257  wave data
1258 
1259  // data folders and references
1260  dfref savedf = GetDataFolderDFR()
1261  dfref datadf = GetWavesDataFolderDFR(data)
1262  string s_datadf = GetDataFolder(1, datadf)
1263  dfref viewdf = make_view_folder(data)
1264 
1265  setdatafolder viewdf
1266  svar /z ex_panel = slicer_panelname
1267  if (svar_exists(ex_panel))
1268  string panels = WinList("SlicerPanel*", ";", "WIN:64")
1269  if (WhichListItem(ex_panel, panels, ";") >= 0)
1270  dowindow /f $(StringFromList(0, panels, ";"))
1271  return 0
1272  endif
1273  endif
1274 
1275  variable /g x_slice_pos
1276  variable /g y_slice_pos
1277  variable /g z_slice_pos
1278  variable /g slab_thickness
1279  string /g brick_path = getwavesdatafolder(data, 2)
1280  variable /g x_autoinc = 0
1281  variable /g y_autoinc = 0
1282  variable /g z_autoinc = 0
1283 
1284  // axis labels
1285  string labels = note(data)
1286  string xlabel = StringByKey("AxisLabelX", labels, "=", "\r")
1287  if (!strlen(xlabel))
1288  xlabel = "X"
1289  endif
1290  string ylabel = StringByKey("AxisLabelY", labels, "=", "\r")
1291  if (!strlen(ylabel))
1292  ylabel = "Y"
1293  endif
1294  string zlabel = StringByKey("AxisLabelZ", labels, "=", "\r")
1295  if (!strlen(zlabel))
1296  zlabel = "Z"
1297  endif
1298  string dlabel = StringByKey("Dataset", labels, "=", "\r")
1299  if (!strlen(dlabel))
1300  dlabel = NameOfWave(data)
1301  endif
1302 
1303  // this section copied from slicer panel
1304  NewPanel /k=1 /W=(500,600,890,940) /N=SlicerPanel as "Brick Slicer"
1305  string /g slicer_panelname = S_name
1306  string panel = s_name
1307 
1308  GroupBox g_xslice win=$panel,pos={8,8},size={376,96},title=xlabel
1309  Slider sl_xslice_position win=$panel,pos={16,32},size={240,56},proc=PearlAreaDisplay#slp_slice_position
1310  Slider sl_xslice_position win=$panel,limits={0,100,1},variable=x_slice_pos,vert= 0
1311  SetVariable sv_xslice_position win=$panel,pos={20,80},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="X"
1312  SetVariable sv_xslice_position win=$panel,limits={0,100,1},value=x_slice_pos
1313  Button b_xslice_center win=$panel,pos={122,80},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
1314  Button b_xslice_center win=$panel,help={"reset to center position"}
1315  Button b_xslice_extract win=$panel,pos={288,80},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
1316  Button b_xslice_extract win=$panel,help={"extract this slice to a separate wave"}
1317  //CheckBox cb_xslab_active win=$panel,pos={288,80},size={80,16},title="Display X Slab"
1318  //CheckBox cb_xslab_active win=$panel,value= 0
1319  TitleBox tb_xslice_animation win=$panel,pos={288,32},size={356,16},title="animation",frame=0
1320  TitleBox tb_xslice_animation win=$panel,anchor= MC
1321  Button b_xslice_back win=$panel,pos={288,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
1322  Button b_xslice_back win=$panel,help={"animate backwards"}
1323  Button b_xslice_forward win=$panel,pos={312,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
1324  Button b_xslice_forward win=$panel,help={"animate forward"}
1325  Button b_xslice_stop win=$panel,pos={336,48},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
1326  Button b_xslice_stop win=$panel,help={"stop animation"}
1327 
1328  GroupBox g_yslice win=$panel,pos={8,108},size={376,96},title=ylabel
1329  Slider sl_yslice_position win=$panel,pos={16,132},size={240,56},proc=PearlAreaDisplay#slp_slice_position
1330  Slider sl_yslice_position win=$panel,limits={0,100,1},variable=y_slice_pos,vert= 0
1331  SetVariable sv_yslice_position win=$panel,pos={20,180},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Y"
1332  SetVariable sv_yslice_position win=$panel,limits={0,100,1},value=y_slice_pos
1333  Button b_yslice_center win=$panel,pos={122,180},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
1334  Button b_yslice_center win=$panel,help={"reset to center position"}
1335  Button b_yslice_extract win=$panel,pos={288,180},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
1336  Button b_yslice_extract win=$panel,help={"extract this slice to a separate wave"}
1337  //CheckBox cb_yslab_active win=$panel,pos={288,180},size={80,16},title="Display Y Slab"
1338  //CheckBox cb_yslab_active win=$panel,value= 0
1339  TitleBox tb_yslice_animation win=$panel,pos={288,132},size={356,16},title="animation",frame=0
1340  TitleBox tb_yslice_animation win=$panel,anchor= MC
1341  Button b_yslice_back win=$panel,pos={288,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
1342  Button b_yslice_back win=$panel,help={"animate backwards"}
1343  Button b_yslice_forward win=$panel,pos={312,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
1344  Button b_yslice_forward win=$panel,help={"animate forward"}
1345  Button b_yslice_stop win=$panel,pos={336,148},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
1346  Button b_yslice_stop win=$panel,help={"stop animation"}
1347 
1348  GroupBox g_zslice win=$panel,pos={8,208},size={376,96},title=zlabel
1349  Slider sl_zslice_position win=$panel,pos={16,232},size={240,56},proc=PearlAreaDisplay#slp_slice_position
1350  Slider sl_zslice_position win=$panel,limits={0,100,1},variable=z_slice_pos,vert= 0
1351  SetVariable sv_zslice_position win=$panel,pos={20,280},size={92,16},proc=PearlAreaDisplay#svp_slice_position,title="Z"
1352  SetVariable sv_zslice_position win=$panel,limits={0,100,1},value=z_slice_pos
1353  Button b_zslice_center win=$panel,pos={122,280},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W618"
1354  Button b_zslice_center win=$panel,help={"reset to center position"}
1355  Button b_zslice_extract win=$panel,pos={288,280},size={68,20},proc=PearlAreaDisplay#bp_extract_slice,title="extract slice"
1356  Button b_zslice_extract win=$panel,help={"extract this slice to a separate wave"}
1357  //CheckBox cb_zslab_active win=$panel,pos={288,280},size={80,16},title="Display Z Slab"
1358  //CheckBox cb_zslab_active win=$panel,value= 0
1359  TitleBox tb_zslice_animation win=$panel,pos={288,232},size={356,16},title="animation",frame=0
1360  TitleBox tb_zslice_animation win=$panel,anchor= MC
1361  Button b_zslice_back win=$panel,pos={288,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W646"
1362  Button b_zslice_back win=$panel,help={"animate backwards"}
1363  Button b_zslice_forward win=$panel,pos={312,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W649"
1364  Button b_zslice_forward win=$panel,help={"animate forward"}
1365  Button b_zslice_stop win=$panel,pos={336,248},size={20,20},proc=PearlAreaDisplay#bp_move_slice,title="\\W616"
1366  Button b_zslice_stop win=$panel,help={"stop animation"}
1367 
1368  TitleBox t_slicerpath win=$panel,pos={8,316},size={128,20},disable=2,title=dlabel
1369  //SetVariable setvar0 win=$panel,pos={240,316},size={120,16},title="slab thickness"
1370  //SetVariable setvar0 win=$panel,limits={1,inf,1},value=slab_thickness
1371 
1372  // update control limits and move slicing planes to the center
1373  setwindow $panel, userdata(control_datafolder) = GetDataFolder(1, viewdf)
1374  setwindow $panel, userdata(brick_path) = brick_path
1375  update_slice_info()
1376  x_slice_pos = dimoffset(data, 0) + dimsize(data, 0) * dimdelta(data, 0) / 2
1377  y_slice_pos = dimoffset(data, 1) + dimsize(data, 1) * dimdelta(data, 1) / 2
1378  z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
1379 
1380  svar /z /sdfr=viewdf gizmo_graphname
1381  if (svar_exists(gizmo_graphname) && (strlen(gizmo_graphname) > 0) && (wintype(gizmo_graphname) == 13))
1382  ad_gizmo_set_plane(data, 0, x_slice_pos)
1383  ad_gizmo_set_plane(data, 1, y_slice_pos)
1384  ad_gizmo_set_plane(data, 2, z_slice_pos)
1385  endif
1386  svar /z /sdfr=viewdf slice_graphname
1387  if (svar_exists(slice_graphname) && (strlen(slice_graphname) > 0) && (wintype(slice_graphname) == 1))
1388  ad_profiles_set_slice(data, 2, z_slice_pos)
1389  endif
1390 
1391  ad_slicer_init_bg()
1392  setdatafolder savedf
1393 end
1394 
1404 function /s ad_display_slice(data)
1405  wave data
1406 
1407  if (WaveDims(data) != 3)
1408  abort "ad_display_slice: data must be three-dimensional."
1409  endif
1410 
1411  dfref savedf = GetDataFolderDFR()
1412  dfref datadf = GetWavesDataFolderDFR(data)
1413  string s_datadf = GetDataFolder(1, datadf)
1414  dfref viewdf = make_view_folder(data)
1415 
1416  setdatafolder viewdf
1417  string dfname = ReplaceString("root:", s_datadf, "")
1418  dfname = dfname[0, strlen(dfname) - 2]
1419  string graphtitle = dfname + " Slice"
1420 
1421  if (exists("slice_graphname") != 2)
1422  string /g slice_graphname = ""
1423  endif
1424  string /g slice_wavename = PearlCleanupName("slice_" + NameOfWave(data))
1425  svar graphname = slice_graphname
1426  svar slicename = slice_wavename
1427 
1428  make /n=(1,1)/o $slicename
1429  wave slice = $slicename
1430  if ((strlen(graphname) == 0) || (wintype(graphname) != 1))
1431  graphname = ad_display_profiles(slice)
1432  endif
1433  variable z_slice_pos = dimoffset(data, 2) + dimsize(data, 2) * dimdelta(data, 2) / 2
1434  ad_profiles_set_slice(data, 2, z_slice_pos)
1435  ad_profiles_set_cursor(slice, "A", -inf, -inf, pscale=1)
1436  ad_profiles_set_cursor(slice, "B", +inf, +inf, pscale=1)
1437 
1438  setdatafolder savedf
1439  return graphname
1440 end
1441 
1445 static function update_slice_info()
1446  dfref savedf = GetDataFolderDFR()
1447 
1448  svar brick_path
1449  //svar slicer_panelname
1450  wave brick = $brick_path
1451 
1452  //dowindow /F $slicer_panelname
1453  variable lo, hi, inc
1454  lo = dimoffset(brick, 0)
1455  inc = dimdelta(brick, 0)
1456  hi = lo + inc * (dimsize(brick, 0) - 1)
1457  Slider sl_xslice_position,limits={lo,hi,inc}
1458  SetVariable sv_xslice_position,limits={lo,hi,inc}
1459  lo = dimoffset(brick, 1)
1460  inc = dimdelta(brick, 1)
1461  hi = lo + inc * (dimsize(brick, 1) - 1)
1462  Slider sl_yslice_position,limits={lo,hi,inc}
1463  SetVariable sv_yslice_position,limits={lo,hi,inc}
1464  lo = dimoffset(brick, 2)
1465  inc = dimdelta(brick, 2)
1466  hi = lo + inc * (dimsize(brick, 2) - 1)
1467  Slider sl_zslice_position,limits={lo,hi,inc}
1468  SetVariable sv_zslice_position,limits={lo,hi,inc}
1469 
1470  setdatafolder savedf
1471 end
1472 
1481 function ad_gizmo_set_plane(brick, dim, value)
1482  wave brick
1483  variable dim
1484  variable value
1485 
1486  dfref savedf = GetDataFolderDFR()
1487  dfref datadf = GetWavesDataFolderDFR(brick)
1488  dfref viewdf = get_view_folder(brick)
1489  svar /z /sdfr=viewdf graphname=gizmo_graphname
1490 
1491  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
1492  if ((pp < 0) || (pp >= dimsize(brick, dim)))
1493  return -1 // requested value out of range
1494  endif
1495 
1496  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 13))
1497  string axes = "xyz"
1498  string obj = "surface_" + axes[dim] + "mid"
1499  string cmd
1500  sprintf cmd, "ModifyGizmo /N=%s ModifyObject=%s, property={plane, %d}", graphname, obj, pp
1501  execute /q cmd
1502  else
1503  return -2 // gizmo window not found
1504  endif
1505 
1506  return 0
1507 end
1508 
1517 function ad_profiles_set_slice(brick, dim, value)
1518  wave brick
1519  variable dim
1520  variable value
1521 
1522  dfref savedf = GetDataFolderDFR()
1523  dfref datadf = GetWavesDataFolderDFR(brick)
1524  dfref viewdf = get_view_folder(brick)
1525  svar /z /sdfr=viewdf graphname = slice_graphname
1526  svar /z /sdfr=viewdf slicename = slice_wavename
1527 
1528  variable pp = round((value - dimoffset(brick, dim)) / dimdelta(brick, dim))
1529  if ((pp < 0) || (pp >= dimsize(brick, dim)))
1530  return -1 // requested value out of range
1531  endif
1532 
1533  if (svar_exists(graphname) && (strlen(graphname) > 0) && (wintype(graphname) == 1))
1534  setdatafolder viewdf
1535  switch(dim)
1536  case 0: // X
1537  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
1538  ad_update_profiles(wdest)
1539  break
1540  case 1: // Y
1541  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
1542  ad_update_profiles(wdest)
1543  break
1544  case 2: // Z
1545  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
1546  ad_update_profiles(wdest)
1547  break
1548  endswitch
1549  else
1550  return -2 // graph window not found
1551  endif
1552 
1553  setdatafolder savedf
1554  return 0
1555 end
1556 
1558 static function slp_slice_position(sa) : SliderControl
1559  STRUCT WMSliderAction &sa
1560 
1561  dfref savedf = GetDataFolderDFR()
1562 
1563  switch( sa.eventCode )
1564  case -1: // control being killed
1565  break
1566  default:
1567  if( sa.eventCode & 1 ) // value set
1568  string control_datafolder = GetUserData(sa.win, "", "control_datafolder")
1569  setdatafolder control_datafolder
1570  string brick_path = GetUserData(sa.win, "", "brick_path")
1571  string axis = StringFromList(1, sa.ctrlName, "_")
1572  variable dim = char2num(axis[0]) - char2num("x")
1573 
1574  wave /z brick = $brick_path
1575  if (WaveExists(brick))
1576  ad_gizmo_set_plane(brick, dim, sa.curval)
1577  ad_profiles_set_slice(brick, dim, sa.curval)
1578  else
1579  Abort "can't find original wave " + brick_path
1580  endif
1581  endif
1582  break
1583  endswitch
1584 
1585  setdatafolder savedf
1586  return 0
1587 End
1588 
1590 static function svp_slice_position(sva) : SetVariableControl
1591  STRUCT WMSetVariableAction &sva
1592 
1593  dfref savedf = GetDataFolderDFR()
1594 
1595  switch( sva.eventCode )
1596  case 1: // mouse up
1597  case 2: // Enter key
1598  case 3: // Live update
1599  string control_datafolder = GetUserData(sva.win, "", "control_datafolder")
1600  setdatafolder control_datafolder
1601  string brick_path = GetUserData(sva.win, "", "brick_path")
1602  string axis = StringFromList(1, sva.ctrlName, "_")
1603  variable dim = char2num(axis[0]) - char2num("x")
1604 
1605  wave /z brick = $brick_path
1606  if (WaveExists(brick))
1607  ad_gizmo_set_plane(brick, dim, sva.dval)
1608  ad_profiles_set_slice(brick, dim, sva.dval)
1609  else
1610  Abort "can't find original wave " + brick_path
1611  endif
1612  break
1613  case -1: // control being killed
1614  break
1615  endswitch
1616 
1617  setdatafolder savedf
1618  return 0
1619 End
1620 
1622 static function bp_move_slice(ba) : ButtonControl
1623  STRUCT WMButtonAction &ba
1624 
1625  dfref savedf = GetDataFolderDFR()
1626 
1627  switch( ba.eventCode )
1628  case 2: // mouse up
1629  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
1630  setdatafolder control_datafolder
1631  string brick_path = GetUserData(ba.win, "", "brick_path")
1632  string axis = StringFromList(1, ba.ctrlName, "_")
1633  string cmd = StringFromList(2, ba.ctrlName, "_")
1634  variable dim = char2num(axis[0]) - char2num("x")
1635  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
1636  nvar pos = $(posvariable)
1637 
1638  wave /z brick = $brick_path
1639  if (WaveExists(brick))
1640  strswitch (cmd)
1641  case "forward":
1642  ad_slicer_start_bg(brick, dim, posvariable, dimdelta(brick, dim))
1643  break
1644  case "back":
1645  ad_slicer_start_bg(brick, dim, posvariable, -dimdelta(brick, dim))
1646  break
1647  case "center":
1648  ad_slicer_stop_bg(posvariable)
1649  bp_move_slice_center(brick, dim, posvariable)
1650  break
1651  case "stop":
1652  ad_slicer_stop_bg(posvariable)
1653  break
1654  endswitch
1655  else
1656  ad_slicer_stop_bg(posvariable)
1657  Abort "can't find original wave " + brick_path
1658  endif
1659  break
1660  case -1: // control being killed
1661  break
1662  endswitch
1663 
1664  setdatafolder savedf
1665  return 0
1666 End
1667 
1671 static function bp_extract_slice(ba) : ButtonControl
1672  STRUCT WMButtonAction &ba
1673 
1674  dfref savedf = GetDataFolderDFR()
1675 
1676  switch( ba.eventCode )
1677  case 2: // mouse up
1678  string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
1679  setdatafolder control_datafolder
1680  string brick_path = GetUserData(ba.win, "", "brick_path")
1681  wave brick = $brick_path
1682  dfref brickdf = GetWavesDataFolderDFR(brick)
1683 
1684  string axis = StringFromList(1, ba.ctrlName, "_")
1685  string cmd = StringFromList(2, ba.ctrlName, "_")
1686  variable dim = char2num(axis[0]) - char2num("x")
1687  string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
1688 
1689  nvar pos = $(posvariable)
1690  variable pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
1691  if ((pp < 0) || (pp >= dimsize(brick, dim)))
1692  return -1 // requested value out of range
1693  endif
1694 
1695  variable dig = ceil(log(dimsize(brick, dim)))
1696  string slicename
1697  sprintf slicename, "%s_%s%0*u", NameOfWave(brick), axis[0], dig, pp
1698  setdatafolder brickdf
1699  switch(dim)
1700  case 0: // X
1701  wave wdest = ad_extract_slab_x(brick, pp, pp, slicename)
1702  break
1703  case 1: // Y
1704  wave wdest = ad_extract_slab_y(brick, pp, pp, slicename)
1705  break
1706  case 2: // Z
1707  wave wdest = ad_extract_slab_z(brick, pp, pp, slicename)
1708  break
1709  endswitch
1710 
1711  string msg
1712  sprintf msg, "%s=%g", axis[0], pos
1713  note wdest, msg
1714 
1715  break
1716  case -1: // control being killed
1717  break
1718  endswitch
1719 
1720  setdatafolder savedf
1721  return 0
1722 End
1723 
1725 static function bp_move_slice_center(brick, dim, posvariable)
1726  wave brick
1727  variable dim
1728  string posvariable
1729 
1730  nvar pos = $posvariable
1731  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * dimsize(brick, dim) / 2
1732  ad_gizmo_set_plane(brick, dim, pos)
1733  ad_profiles_set_slice(brick, dim, pos)
1734 end
1735 
1737 static function ad_slicer_move_bg(s)
1738  STRUCT WMBackgroundStruct &s
1739 
1740  dfref savedf = GetDataFolderDFR()
1741  setdatafolder root:pearl_area:slicer
1742  wave /t bg_brickpaths
1743  wave /t bg_graphnames
1744  wave /t bg_variablepaths
1745  wave bg_dimensions
1746  wave bg_increments
1747 
1748  variable ii
1749  variable nn = numpnts(bg_brickpaths)
1750  variable dim
1751  variable pp
1752 
1753  for (ii = 0; ii < nn; ii += 1)
1754  wave /z brick = $bg_brickpaths[ii]
1755  nvar /z pos = $bg_variablepaths[ii]
1756  dim = bg_dimensions[0]
1757  pos += bg_increments[ii]
1758  // wrap around at limits
1759  pp = round((pos - dimoffset(brick, dim)) / dimdelta(brick, dim))
1760  if (pp <= -0.5)
1761  pos = dimoffset(brick, dim) + dimdelta(brick, dim) * (dimsize(brick, dim) - 1)
1762  elseif (pp >= dimsize(brick, dim) - 0.5)
1763  pos = dimoffset(brick, dim)
1764  endif
1765  if (waveexists(brick))
1766  ad_gizmo_set_plane(brick, dim, pos)
1767  ad_profiles_set_slice(brick, dim, pos)
1768  endif
1769  endfor
1770 
1771  setdatafolder savedf
1772  return 0
1773 End
1774 
1776 function ad_slicer_init_bg()
1777  dfref savedf = GetDataFolderDFR()
1778  setdatafolder root:
1779  newdatafolder /o/s pearl_area
1780  newdatafolder /o/s slicer
1781 
1782  make /n=0/o/t bg_brickpaths
1783  make /n=0/o/t bg_variablepaths
1784  make /n=0/o/i/u bg_dimensions
1785  make /n=0/o bg_increments
1786 
1787  CtrlNamedBackground ad_slicer, period = 30, proc = PearlAreaDisplay#ad_slicer_move_bg
1788 
1789  setdatafolder savedf
1790  return 0
1791 end
1792 
1800 function ad_slicer_start_bg(brick, dimension, posvariable, delta)
1801  wave brick // 3D data wave
1802  variable dimension // dimension to animate, 0, 1, or 2
1803  string posvariable // full path to the global position variable
1804  variable delta // step increment, should be +/- dimdelta
1805 
1806  dfref savedf = GetDataFolderDFR()
1807  setdatafolder root:pearl_area:slicer
1808  wave /t bg_brickpaths
1809  wave /t bg_variablepaths
1810  wave bg_dimensions
1811  wave bg_increments
1812 
1813  // create entry in ad_slicer background task table
1814  variable idx
1815  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
1816  if (v_value >= 0)
1817  idx = v_value
1818  else
1819  idx = numpnts(bg_variablepaths)
1820  InsertPoints idx, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
1821  endif
1822 
1823  // set background task
1824  bg_brickpaths[idx] = GetWavesDataFolder(brick, 2)
1825  bg_variablepaths[idx] = posvariable
1826  bg_dimensions[idx] = dimension
1827  bg_increments[idx] = delta
1828 
1829  // start background task
1830  if (numpnts(bg_variablepaths) > 0)
1831  CtrlNamedBackground ad_slicer, start
1832  endif
1833 
1834  setdatafolder savedf
1835  return 0
1836 end
1837 
1842 function ad_slicer_stop_bg(posvariable)
1843  string posvariable
1844 
1845  dfref savedf = GetDataFolderDFR()
1846  setdatafolder root:pearl_area:slicer
1847  wave /t bg_brickpaths
1848  wave /t bg_variablepaths
1849  wave bg_dimensions
1850  wave bg_increments
1851 
1852  // find entry in ad_slicer background task table
1853  FindValue /TEXT=posvariable /TXOP=4 /Z bg_variablepaths
1854  if (v_value >= 0)
1855  DeletePoints v_value, 1, bg_brickpaths, bg_variablepaths, bg_dimensions, bg_increments
1856  endif
1857 
1858  // stop background task if task table is empty
1859  if (numpnts(bg_variablepaths) == 0)
1860  CtrlNamedBackground ad_slicer, stop
1861  endif
1862 
1863  setdatafolder savedf
1864  return 0
1865 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
wave ad_add_overlay(wave image, string rgba=defaultValue)
add an overlay on top of the displayed image
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.