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