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