-
Notifications
You must be signed in to change notification settings - Fork 1
/
firehose_tspec.pro
1624 lines (1391 loc) · 70.9 KB
/
firehose_tspec.pro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
PRO fire_tspec_event, ev
COMMON share, firestrct ;flatinter, traceinter, singlesinter, fire_pipe_inter, fire_pipe_clobber, fire_pipe_verbose, fire_pipe_bright, fire_mkstrct_verbose, fire_mkstrct_loud, xtell_clobber, xtell_quick, fire_pipe_plot
COMPILE_OPT hidden
func_name = "fire_tspec_event"
widget_control, ev.id, get_uvalue=uvalue ;event handler
;; Programming Note: uvalue here should really be uname! This would have freed up the uvalue slot
;; to be used for other parameter values of any type (whereas uname has to be a string). We'll live
;; with the current convention...
IF N_ELEMENTS(uvalue) EQ 1 AND size(uvalue, /type) NE 8 THEN CASE uvalue OF
'list':
'tab':
;; MENU Buttons
'quit': BEGIN
ans = dialog_message("Quit firehose? ", /Question, /center)
if (ans EQ "Yes") then begin
WIDGET_CONTROL, ev.TOP, /DESTROY
return
endif else begin
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Thanks for stickin' around.", /append
endelse
END
'clear': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.wtext, set_value="All clear..."
END
'pwd': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
spawn, 'pwd', cwd
WIDGET_CONTROL, s.wtext, set_value='Current working directory is '+cwd, /append
END
'raw': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
WIDGET_CONTROL, s.wtext, set_value='Current raw data directory is '+rawpath, /append
END
'website': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.wtext, set_value='FIRE website: https://wikis.mit.edu/confluence/display/FIRE/FIRE+Data+Reduction', /append
END
'fire_logo': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.wtext, set_value='FIRE website: https://wikis.mit.edu/confluence/display/FIRE/FIRE+Data+Reduction', /append
END
'about': about = DIALOG_MESSAGE(['FIRE Spectral Extractor v0.01 - Written by John Bochanski, Adam Burgasser, Mike Matejek, Rob Simcoe', '', 'For more information: [email protected]'], title='About')
'arcsdir': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
dir = strtrim(reduxpath,2)+'/Arcs/'
cmd = 'ls '+ dir
spawn, cmd, vals
WIDGET_CONTROL, s.wtext, set_value="", /append
WIDGET_CONTROL, s.wtext, set_value='Contents of Arcs/ directory (' + dir + '):', /append
WIDGET_CONTROL, s.wtext, set_value=fire_str_array_to_str(vals), /append
WIDGET_CONTROL, s.wtext, set_value="", /append
END
'finaldir': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
dir = strtrim(reduxpath,2)+'/Final/'
cmd = 'ls '+ dir
spawn, cmd, vals
WIDGET_CONTROL, s.wtext, set_value="", /append
WIDGET_CONTROL, s.wtext, set_value='Contents of Final/ directory (' + dir + '):', /append
WIDGET_CONTROL, s.wtext, set_value=fire_str_array_to_str(vals), /append
WIDGET_CONTROL, s.wtext, set_value="", /append
END
'flatdir': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
dir = strtrim(reduxpath,2)+'/Flat/'
cmd = 'ls '+ dir
spawn, cmd, vals
WIDGET_CONTROL, s.wtext, set_value="", /append
WIDGET_CONTROL, s.wtext, set_value='Contents of Flat/ directory (' + dir + '):', /append
WIDGET_CONTROL, s.wtext, set_value=fire_str_array_to_str(vals), /append
WIDGET_CONTROL, s.wtext, set_value="", /append
END
'objectdir': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
dir = strtrim(reduxpath,2)+'/Object/'
cmd = 'ls '+ dir
spawn, cmd, vals
WIDGET_CONTROL, s.wtext, set_value="", /append
WIDGET_CONTROL, s.wtext, set_value='Contents of Object/ directory (' + dir + '):', /append
WIDGET_CONTROL, s.wtext, set_value=fire_str_array_to_str(vals), /append
WIDGET_CONTROL, s.wtext, set_value="", /append
END
'timesaved': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.strctname, get_value=file
out = file_info(file)
if out.exists EQ 0 then begin
fire_siren, func_name + ": firestrct file named " + file + " does not exist!" + $
" Please use the 'Structure' tag to create this structure.", widget = s.wtext, /append
endif else begin
ctime = systime(0, out.ctime)
WIDGET_CONTROL, s.wtext, set_value='Time ' + file + ' last saved: ' + ctime, /append
endelse
END
'default_raw': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
spawn, 'pwd', cwd
arr = strsplit(cwd, "/")
rawdir = strmid(cwd,0,arr[n_elements(arr)-1])+strtrim('/Raw/',2)
if (x_chkfil(rawdir, /SILENT) EQ 0) then begin ;; Default Raw directory doesn't exist.
rawdir = cwd
endif
; Determine the new path
WIDGET_CONTROL, s.setupdir, set_value=rawdir
WIDGET_CONTROL, s.wtext, set_value='Raw path has been updated to '+rawdir, /append
WIDGET_CONTROL, s.wtext, set_value='Current working directory is '+cwd, /append
END
'default_redux': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
spawn, 'pwd', cwd
reduxdir = strtrim(cwd,2)+'/'
WIDGET_CONTROL, s.reduxdir, set_value=reduxdir
WIDGET_CONTROL, s.wtext, set_value='Reductions path has been updated to '+reduxdir, /append
WIDGET_CONTROL, s.wtext, set_value='Current working directory is '+cwd, /append
END
'reduxdir': BEGIN ;; user edits raw dir using edit box
;get IDs from the main widget
WIDGET_CONTROL, ev.top, get_uvalue=s
; Determine the new path
WIDGET_CONTROL, s.reduxdir, get_value=new_path
; Check if the new path exists, complain if not
if( FILE_TEST( new_path, /directory) EQ 0 ) then begin
spawn, 'pwd', cwd
arr = strsplit(cwd, "/")
new_path = strmid(cwd,0,arr[n_elements(arr)-1])+strtrim('/Raw/',2)
if (x_chkfil(new_path, /SILENT) EQ 0) then begin ;; Default Raw directory doesn't exist.
new_path = cwd
endif
fire_siren, func_name + ": ERROR! Entered redux directory path as " + new_path + $
", but this directory does not exist! Resetting to the default = " + new_path,$
WIDGET=s.wtext, /append
WIDGET_CONTROL, s.reduxdir, set_value=new_path
endif else begin
WIDGET_CONTROL, s.wtext, set_value='Raw path has been updated to '+new_path, /append
spawn, 'pwd', cwd
WIDGET_CONTROL, s.wtext, set_value='Current working directory is '+cwd, /append
endelse
END
'rawdir': BEGIN ;; user edits raw dir using edit box
;get IDs from the main widget
WIDGET_CONTROL, ev.top, get_uvalue=s
; Determine the new path
WIDGET_CONTROL, s.setupdir, get_value=new_path
; Check if the new path exists, complain if not
if( FILE_TEST( new_path, /directory) EQ 0 ) then begin
spawn, 'pwd', cwd
arr = strsplit(cwd, "/")
new_path = strmid(cwd,0,arr[n_elements(arr)-1])+strtrim('/Raw/',2)
if (x_chkfil(new_path, /SILENT) EQ 0) then begin ;; Default Raw directory doesn't exist.
new_path = cwd
endif
fire_siren, func_name + ": ERROR! Entered raw directory path as " + new_path + $
", but this directory does not exist! Resetting to the default = " + new_path,$
WIDGET=s.wtext, /append
WIDGET_CONTROL, s.setupdir, set_value=new_path
endif else begin
WIDGET_CONTROL, s.wtext, set_value='Raw path has been updated to '+new_path, /append
spawn, 'pwd', cwd
WIDGET_CONTROL, s.wtext, set_value='Current working directory is '+cwd, /append
endelse
END
'raw_pick': BEGIN ;; user edits raw dir using browse button
;get IDs from the main widget
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=inipath
;pick raw data directory
path=DIALOG_PICKFILE(/Directory, /must_exist, title='Please choose raw data directory', path=inipath)
;; Check if path is null string (will be true if user hits 'Cancel')
if( is_empty( path ) EQ 1 ) then begin
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Raw path not changed, remains " + $
inipath, /append
endif else begin
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.setupdir, set_value=path
WIDGET_CONTROL, s.wtext, set_value='Raw path has been updated to '+path, /append
spawn, 'pwd', cwd
WIDGET_CONTROL, s.wtext, set_value='Current working directory is '+cwd, /append
endelse
END
'redux_pick': BEGIN ;; user edits raw dir using browse button
;get IDs from the main widget
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.reduxdir, get_value=inipath
;pick reductions data directory
path=DIALOG_PICKFILE(/Directory, /must_exist, title='Please choose reductions data directory', path=inipath)
;; Check if path is null string (will be true if user hits 'Cancel')
if( is_empty( path ) EQ 1 ) then begin
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Reduction path not changed, remains " + $
inipath, /append
endif else begin
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.reduxdir, set_value=path
WIDGET_CONTROL, s.wtext, set_value='Reductions path has been updated to '+path, /append
spawn, 'pwd', cwd
WIDGET_CONTROL, s.wtext, set_value='Current working directory is '+cwd, /append
endelse
END
'cat_pick': BEGIN
;get IDs from the main widget
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=inipath
;pick working directory
obscat=DIALOG_PICKFILE(/multiple_files, /must_exist, title='Please pick an observing catalog')
if( is_empty( obscat ) EQ 1 ) then begin ;; user hit cancel button
WIDGET_CONTROL, s.obscat_list, get_uvalue=obscat
if( is_empty( obscat ) EQ 1 OR strmatch(obscat, 'tab', /FOLD_CASE) EQ 1 ) then begin
obscat = "(unknown)"
endif
WIDGET_CONTROL, s.wtext, set_value="Action aported by user. Observing catalog remains " + $
obscat + ".", /append
endif else begin
WIDGET_CONTROL, s.wtext, set_value="Observing catalog changed to " + $
obscat + ".", /append
WIDGET_CONTROL, s.obscat_list, set_value=obscat, set_uvalue=obscat
endelse
END
'trace_pick': BEGIN
;pick working directory
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
file=DIALOG_PICKFILE(filter='*.fits', /read, path=rawpath, title="Please select one or more trace flat files", /must_exist, /multiple_files)
if( is_empty(file) EQ 0 ) then begin
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.tflt_file, set_value=file
WIDGET_CONTROL, s.wtext, set_value='Trace flat' + s_or_not(n_elements(file)) + ' added: '+ fire_str_array_to_str(file), /append
endif else begin ;; user hit 'Cancel'
WIDGET_CONTROL, s.tflt_file, get_value=file
if( is_empty(file) EQ 1 ) then begin
file = "(unknown)"
endif
nfiles = n_elements(file)
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Trace flat" + s_or_not(nfiles) + $
" remain" + s_or_not(nfiles, /reverse) + " " + fire_str_array_to_str(file), /append
endelse
END
'go_trace': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
WIDGET_CONTROL, s.tflt_file, get_value=tflt_file
bad_input = 0
;; Make sure that trace flats have been entered
if is_empty(tflt_file) then begin
fire_siren, func_name + ": ERROR! Forgot to input Trace Flat(s). Please use the 'Browse' " + $
" button, input Trace Flats, and try again!", widget = s.wtext, /append
break
endif
;; Make sure that these trace flats exist
if min( FILE_TEST(tflt_file), bad_files) EQ 0 then begin
bad_input = 1
fire_siren, func_name + ": ERROR! At least one of the Trace Flats (" + tflt_file[bad_files] + $
") does not exist! Please use the 'Browse' " + $
" button, input Trace Flats, and try again!", widget = s.wtext, /append
endif
if bad_input EQ 0 then begin
WIDGET_CONTROL, s.wtext, set_value='Tracing orders. ATV will launch on completion; Press q to continue after inspecting trace.' + fire_str_time(), /append
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
if (x_chkfil(tflt_file[0]) GT 0) then begin
if (n_elements(tflt_file) EQ 1) then begin
orderfile=strtrim(reduxpath,2)+'/Flat/Orders_'+$
(strtrim(strsplit(tflt_file[0],'to', /extract),2))[1]
ostr_file=strtrim(reduxpath,2)+'/Flat/OStr_'+$
(strtrim(strsplit(tflt_file[0],'to', /extract),2))[1]
endif else begin
orderfile=strtrim(reduxpath,2)+'/Flat/Orders_'+$
(strtrim(strsplit(tflt_file[0],'_.', /extract),2))[1]$
+'_'+$
(strtrim(strsplit(tflt_file[n_elements(tflt_file)-1],'_.',$
/extract),2))[1]
ostr_file=strtrim(reduxpath,2)+'/Flat/OStr_'+$
(strtrim(strsplit(tflt_file[0],'_.', /extract),2))[1]$
+'_'+$
(strtrim(strsplit(tflt_file[n_elements(tflt_file)-1],'_.',$
/extract),2))[1]
endelse
fire_timer, time, /start
inter = WIDGET_INFO(s.traceinterbt,/button_set)
tset_slits=tspec_findslits(traceflat=tflt_file, /CLOBBER, /CHK, $
INTER=inter)
; orderfile=orderfile, $
; ordr_str_file=ostr_file,
fire_timer, time, /stop
WIDGET_CONTROL, s.wtext, set_value='Orders have been traced.' + fire_str_time(elapsed=time), /append
endif else begin
WIDGET_CONTROL, s.wtext, set_value='Error: trace flat file not found.', /append
endelse
endif
END
'pix_arc_pick': BEGIN
; determine working directory
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
file=DIALOG_PICKFILE(filter='*.fits', /read, path=rawpath, $
title="Please select a Slit Tilt File", /must_exist)
if( is_empty( file ) EQ 0 ) then begin
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.pixarcfile, set_value=file
WIDGET_CONTROL, s.wtext, set_value='Pixel arc for flats added as '+file, /append
endif else begin
WIDGET_CONTROL, s.pixarcfile, get_value=file
if( is_empty(file) EQ 1 ) then begin
file = "(unknown)"
endif
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Pixel arc for flats remains "+file, /append
endelse
END
;; 'go_piximage': BEGIN
;; WIDGET_CONTROL, ev.top, get_uvalue=s
;; WIDGET_CONTROL, s.setupdir, get_value=rawpath
;; WIDGET_CONTROL, s.pixarcfile, get_value=pixarcfile
;; WIDGET_CONTROL, s.piximgfile, get_value=piximgfile
;; tset_slits=mrdfits('Orders.fits', 1)
;; IF pixinter THEN WIDGET_CONTROL, s.wtext, set_value='Launching ATV; Press q to continue through each order', /append
;; mage_makepix, pixarcfile, piximgfile, tset_slits, chk=pixinter
;; WIDGET_CONTROL, s.wtext, set_value='Pixel Image written to '+ piximgfile, /append
;; END
;; 'pix_arc_inter_tog':BEGIN
;; WIDGET_CONTROL, ev.top, get_uvalue=s
;; pixinter = ev.select
;; END
'flat_pick': BEGIN
;pick working directory
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
files=DIALOG_PICKFILE(filter='*.fits', /read, path=rawpath, $
title="Please select one or more Flat Field Files", /must_exist, /multiple_files)
if( is_empty(files) EQ 0 ) then begin
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.flatfiles, set_value=files
WIDGET_CONTROL, s.wtext, set_value='Flat Field files added as '+ fire_str_array_to_str(files), /append
endif else begin
WIDGET_CONTROL, s.flatfiles, get_value=files
if( is_empty(files) EQ 1 ) then begin
files = "(unknown)"
endif
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Flat files remain " + fire_str_array_to_str(files), /append
endelse
END
'illum_flat_pick': BEGIN
; determine working directory
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
files=DIALOG_PICKFILE(filter='*.fits', /read, path=rawpath, /must_exist, $
title="Please select one or more IllumFlat Files", /multiple_files)
if( is_empty(files) EQ 0 ) then begin
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.illumflatfiles, set_value=files
WIDGET_CONTROL, s.wtext, set_value='Illum flat files added as '+ fire_str_array_to_str(files), /append
endif else begin ;; user hit cancel
WIDGET_CONTROL, s.illumflatfiles, get_value=files
if( is_empty(files) EQ 1 ) then begin
files = "(unknown)"
endif
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Illumflat files remain " + fire_str_array_to_str(files), /append
endelse
END
'omsk_pick': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
pickpath = strtrim(reduxpath,2)+'/Flat/'
files=DIALOG_PICKFILE(filter='Orders*.fits', /read, path=pickpath, $
title="Please select one or more Order Mask Files", /must_exist)
WIDGET_CONTROL, ev.top, get_uvalue=s
if( is_empty(files) EQ 0 ) then begin
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.omsk, set_value=files
WIDGET_CONTROL, s.wtext, set_value='Order mask file added as '+files, /append
endif else begin ;; user hit cancel
WIDGET_CONTROL, s.omsk, get_value=files
if( is_empty(files) EQ 1 ) then begin
files = "(unknown)"
endif
WIDGET_CONTROL, s.wtext, set_value="Action aborted by user. Order mask files remain " + files, /append
endelse
END
'flat_inter_tog':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
flatinter = ev.select
END
'trace_inter_tog':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
traceinter = ev.select
END
'single_tog':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
singlesinter = ev.select
END
'fire_pipe_chkbt':BEGIN
fire_pipe_inter = ev.select
END
'fire_pipe_clobber':BEGIN
fire_pipe_clobber = ev.select
END
'fire_pipe_plot': BEGIN
fire_pipe_plot = ev.select
END
'firehose_label': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.wtext, set_value="Please enter the new title in the IDL terminal, then hit return.", /append
new_title = ''
print, "Please enter the new title, then hit return: "
READ, "", new_title
WIDGET_CONTROL, s.wtext, set_value="New title entered as: " + new_title, /append
WIDGET_CONTROL, ev.top, tlb_set_title=new_title
END
'play': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
if( is_undefined(firestrct) EQ 1 ) then begin
fire_siren, func_name + ": ERROR! Cannot provide access to firestrct because it has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
fire_timer, time, /start
WIDGET_CONTROL, s.wtext, set_value=[ "", "**** Play with firestrct **** (recommended for advanced users only). Go to your IDL terminal. A 'stop' has been placed in the function play_with_firestrct.pro, whose only input is firestrct. Make any changes desired, and then hit .con to exit out of play-mode." + fire_str_time() ], /append
play_with_firestrct, firestrct
fire_timer, time, /stop
WIDGET_CONTROL, s.wtext, set_value=[ " ...done playing with firestrct. Changes NOT saved." + $
" Visit 'Structure' tab to save changes, if desired." + fire_str_time(ELAPSED=time), "" ], /append
END
'fire_pipe_bright':BEGIN
fire_pipe_bright = ev.select
END
'fire_pipe_verbose':BEGIN
fire_pipe_verbose = ev.select
END
'fire_mkstrct_verbose': BEGIN
fire_mkstrct_verbose = ev.select
END
'fire_mkstrct_loud': BEGIN
fire_mkstrct_loud = ev.select
END
'xtell_clobber':BEGIN
xtell_clobber = ev.select
END
'xtell_quick':BEGIN
xtell_quick = ev.select
END
'multispec_out':BEGIN
multispec_out = ev.select
END
'fire_no_cat': BEGIN
fire_no_cat = ev.select
END
'go_flat': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
WIDGET_CONTROL, s.pixarcfile, get_value=pixarcfile
WIDGET_CONTROL, s.flatfiles, get_value=flatfiles
WIDGET_CONTROL, s.illumflatfiles, get_value=illumflatfiles
WIDGET_CONTROL, s.omsk, get_value=ordermask
bad_input = 0
;; Make sure that files were actually loaded in by the user...
if is_empty(pixarcfile) EQ 1 then begin
bad_input = 1
bad_type = 'Slit Tilt File'
endif else if is_empty(flatfiles) EQ 1 then begin
bad_input = 1
bad_type = 'Flat Field Files'
endif else if is_empty(illumflatfiles) EQ 1 then begin
bad_input = 1
bad_type = 'Illum Flat Files'
endif else if is_empty(ordermask) EQ 1 then begin
bad_input = 1
bad_type = 'Order Mask'
endif
if( bad_input NE 1 ) then begin
;; Make sure that the user inputs actually exist.
if min( FILE_TEST(pixarcfile), bad_files) EQ 0 then begin
bad_input = 2
all_files = pixarcfile
bad_type = 'Slit Tilt File'
endif else if min( FILE_TEST(flatfiles), bad_files) EQ 0 then begin
bad_input = 2
all_files = flatfiles
bad_type = 'Flat Field Files'
endif else if min( FILE_TEST(illumflatfiles), bad_files) EQ 0 then begin
bad_input = 2
all_files = illumflatfiles
bad_type = 'Illum Flat Files'
endif else if min( FILE_TEST(ordermask), bad_files) EQ 0 then begin
bad_input = 2
all_files = ordermask
bad_type = 'Order Mask'
endif
endif
;; If all is well, then continue on...
if bad_input EQ 0 then begin
WIDGET_CONTROL, s.wtext, set_value='Generating Flat Field...this takes 5-10 minutes' + fire_str_time(), /append
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
pixfile = strtrim(reduxpath,2)+'/Flat/Piximg_'$
+strtrim((strsplit(pixarcfile[0],'_.', /extract))[1],2) ; Pixel image
; Pixel flat
if (n_elements(flatfiles) EQ 1) then begin
pixflat = strtrim(reduxpath,2)+'/Flat/Pixflat_'$
+strtrim((strsplit(flatfiles[0],'_.', /extract))[1],2)
endif else begin
pixflat = strtrim(reduxpath,2)+'/Flat/Pixflat_'$
+strtrim((strsplit(flatfiles[0],'_.', /extract))[1],2)+'_'$
+strtrim((strsplit(flatfiles[n_elements(flatfiles)-1],'_.', $
/extract))[1],2)
endelse
; Illumination Flat
if (n_elements(illumflatfiles) EQ 1) then begin
outfile = strtrim(reduxpath,2)+'/Flat/Illumflat_'$
+strtrim((strsplit(illumflatfiles[0],'_.', /extract))[1],2)
endif else begin
outfile = strtrim(reduxpath,2)+'/Flat/Illumflat_'$
+strtrim((strsplit(illumflatfiles[0],'_.', /extract))[1],2)+'_'$
+strtrim((strsplit(illumflatfiles[n_elements(illumflatfiles)-1],$
'.', /extract))[1],2)
endelse
fire_timer, time, /start
chk = WIDGET_INFO(s.flatinterbt,/button_set)
tspec_makeflat, flatfiles=flatfiles, illum=illumflatfiles, $
orders=ordermask, arcfile=pixarcfile[0], $
scifile=pixarcfile[0], chk=chk, /clobber
fire_timer, time, /stop
WIDGET_CONTROL, s.wtext, set_value='...done generating Flat Field!' + fire_str_time(ELAPSED=time), /append
endif else if bad_input EQ 1 then begin
;; If we're in here, then the user has forgotten to input some file
fire_siren, func_name + ": ERROR! User has not input the " + $
bad_type + "! Use the 'Browse' button and select the correct files. Exiting " + $
"without running fire_makeflat!", widget = s.wtext, /append
endif else if bad_input EQ 2 then begin
;; If we're in here, then at least one of the user inputs does not exist
fire_siren, func_name + ": ERROR! At least one of the input " + $
bad_type + " (" + all_files[bad_files] + ") does not exist! Use the 'Browse' button " + $
"and select the correct files. Exiting " + $
"without running fire_makeflat!", widget = s.wtext, /append
endif
END
'make_struct':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
WIDGET_CONTROL, s.strctname, get_value=strctname
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
slct_pixflats = WIDGET_INFO(s.strctflats, /list_select)
slct_ilflats = WIDGET_INFO(s.strctiflats, /list_select)
slct_omask = WIDGET_INFO(s.strctomask, /list_select)
if (FILE_TEST(strtrim(reduxpath,2)+"/Flat", /dir)) then begin
spawn, "ls "+strtrim(reduxpath,2)+"/Flat/Pixflat*", flatls
spawn, "ls "+strtrim(reduxpath,2)+"/Flat/Illumflat*", iflatls
spawn, "ls "+strtrim(reduxpath,2)+"/Flat/Orders*", omaskls
spawn, "ls "+strtrim(reduxpath,2)+"/Flat/OStr*", ostrls
if (slct_pixflats[0] EQ -1) then pixflats = flatls else $
pixflats=flatls[slct_pixflats]
if (slct_ilflats[0] EQ -1) then illflats = iflatls else $
illflats=iflatls[slct_ilflats]
if (slct_omask[0] EQ -1) then begin
omasks = omaskls
ostrs = ostrls
endif else begin
omasks=omaskls[slct_omask]
ostrs=ostrls[slct_omask]
endelse
endif
;make structure
;; Get the catalog name
WIDGET_CONTROL, s.obscat_list, get_uvalue=obscat
no_cat = WIDGET_INFO( s.fire_no_cat, /button_set )
if strmatch( obscat, 'tab', /FOLD_CASE ) EQ 1 AND no_cat EQ 0 then begin
fire_siren, func_name + ": WARNING! No observation catalog entered! (See the " + $
"'Setup' tab within the GUI.) fire_mkstrct() can work without one, but inputting your " + $
" Magellan telescope operator source file dramatically reduces the amount of editing " + $
"required later. Type '.con' in the IDL terminal from within which firehose was launched" + $
" to continue without it, or type 'retall', upload the catalog, and try again." + $
" Select the 'Do not use Catalog' button in the GUI to avoid this message when running " + $
"fire_mkstrct() without a catalog.", widget = s.wtext, /append, /both
stop
endif else if no_cat EQ 1 then begin
obscat1 = 0
endif else begin
obscat1 = obscat
endelse
WIDGET_CONTROL, s.wtext, set_value="Creating fire structure" + $
fire_str_time() + ". This takes about half a minute...", /append
fire_timer, time, /start
verbose = WIDGET_INFO(s.fire_mkstrct_verbosebt,/button_set)
loud = WIDGET_INFO(s.fire_mkstrct_loudbt,/button_set)
tspec_mkstrct, fire, rawpath=rawpath, pixflats=pixflats, $
illumflats=illflats, omask=omasks, ostrs=ostrs, $
objcats=obscat1, loud=loud, $
verbose=verbose, widget=s.wtext, /tellcats
fire_timer, time, /stop
;; Must now use 'Save Structure' button for this
;;write it to a file
;;mwrfits, fire, strctname[0], /create
firestrct = fire
WIDGET_CONTROL, s.wtext, set_value="FIRE structure created but NOT saved" + $
fire_str_time(ELAPSED=time) + ". To save this file to " + $
strctname[0] +", hit the 'Save Structure' button.", /append
; Get a list of unique object names (by object ID)
scis = firestrct[where(firestrct.obj_id GE 0)]
scisort = scis[sort(scis.obj_id)]
targets = scisort[uniq(scisort.obj_id)].object
; Populate the Extract tab with objects in the selection window
WIDGET_CONTROL, s.w_spec_target, set_value=targets
WIDGET_CONTROL, s.w_spec_target, set_uvalue=targets
;; Populate the 'Telluric' tab file tree
populate_telluric_tree, firestrct, ev
END
'write_struct':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.strctname, get_value=strctname
if( is_undefined(firestrct) EQ 1 ) then begin
fire_siren, func_name + ": ERROR! Cannot save structure because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
fire = firestrct
mwrfits, fire, strctname[0], /create
scis = firestrct[where(firestrct.obj_id GE 0)]
scisort = scis[sort(scis.obj_id)]
targets = scisort[uniq(scisort.obj_id)].object
WIDGET_CONTROL, s.w_spec_target, set_value=targets
WIDGET_CONTROL, s.w_spec_target, set_uvalue=targets
WIDGET_CONTROL, s.wtext, set_value='FIRE structure written to '+strctname[0] + fire_str_time(), /append
END
'load_struct':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.strctname, get_value=strctname
if FILE_TEST( strctname[0] ) EQ 1 then begin
fire = xmrdfits(strctname[0], 1)
firestrct = {firestrct}
firestrct = replicate(firestrct, n_elements(fire))
copy_struct, fire, firestrct, ntags
if ntags NE n_tags(fire) then begin
WIDGET_CONTROL, s.wtext, set_value='Old version of firestrct structure definition detected. Not a problem ' + $
'(useless tags removed), but you might want to resave right now so that the latest version is stored.', /append
endif
scis = firestrct[where(firestrct.obj_id GE 0)]
scisort = scis[sort(scis.obj_id)]
targets = scisort[uniq(scisort.obj_id)].object
IF size(targets, /type) NE 7 THEN targets=fire_string(lindgen(n_elements(firestrct)))
WIDGET_CONTROL, s.w_spec_target, set_value=targets
WIDGET_CONTROL, s.w_spec_target, set_uvalue=targets
WIDGET_CONTROL, s.wtext, set_value='FIRE structure loaded from '+strctname[0]+fire_str_time(), /append
;; Populate the 'Telluric' tab file tree
populate_telluric_tree, firestrct, ev
endif else begin
fire_siren, func_name + ": ERROR! File " + strctname[0] + " does not exist! (Either " + $
"it was not previously created and saved, or you are in the wrong directory.) " + $
"Exiting without loading the structure!", widget = s.wtext, /append
endelse
END
'edit_struct':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.strctname, get_value=strctname
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
WIDGET_CONTROL, s.setupdir, get_value=rawpath
fire = xmrdfits(strctname[0], 1)
if( is_undefined(firestrct) EQ 1 ) then begin
fire_siren, func_name + ": ERROR! Cannot edit firestrct because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
fitsfile = strtrim(reduxpath,2)+strctname[0]
tspec_editstrct, firestrct, fitsname=fitsfile, raw=rawpath
fire = xmrdfits(strctname[0], 1)
firestrct = fire
scis = firestrct[where(firestrct.obj_id GE 0)]
scisort = scis[sort(scis.obj_id)]
targets = scisort[uniq(scisort.obj_id)].object
IF n_elements(targets) EQ 0 THEN targets=fire_string( lindgen(n_elements(firestrct)) )
WIDGET_CONTROL, s.w_spec_target, set_value=targets
WIDGET_CONTROL, s.w_spec_target, set_uvalue=targets
WIDGET_CONTROL, s.wtext, set_value='FIRE structure loaded from '+strctname[0]+fire_str_time(), /append
WIDGET_CONTROL, s.wtext, set_value='FIRE structure has been edited and written to '+strctname[0], /append
END
'edit_script':BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
if( is_undefined(firestrct) EQ 1 ) then begin
fire_siren, func_name + ": ERROR! Cannot run edit script because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
WIDGET_CONTROL, s.wtext, set_value='Reading in template and editing data' $
+ fire_str_time() + '...', /append
fire_timer, time, /start
;; Run the edit script
verbose = WIDGET_INFO(s.fire_mkstrct_verbosebt,/button_set)
loud = WIDGET_INFO(s.fire_mkstrct_loudbt,/button_set)
run_firestrct_script, firestrct, WIDGET=s.wtext, VERBOSE=verbose, LOUD=loud, RAWPATH=s.cwd
;; Save the result
fire = firestrct
WIDGET_CONTROL, s.strctname, get_value=strctname
mwrfits, fire, strctname[0], /create
scis = firestrct[where(firestrct.obj_id GE 0)]
scisort = scis[sort(scis.obj_id)]
targets = scisort[uniq(scisort.obj_id)].object
fire_timer, time, /stop
WIDGET_CONTROL, s.w_spec_target, set_value=targets
WIDGET_CONTROL, s.w_spec_target, set_uvalue=targets
WIDGET_CONTROL, s.wtext, set_value='FIRE structure edited and result written to '+strctname[0] $
+ fire_str_time(ELAPSED=time), /append
END
'show_objids': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.strctname, get_value=strctname
WIDGET_CONTROL, s.reduxdir, get_value=reduxpath
WIDGET_CONTROL, s.setupdir, get_value=rawpath
if( is_undefined(firestrct) EQ 1 ) then begin
fire_siren, func_name + ": ERROR! Cannot determine obj_ids because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
inds = uniq( firestrct.obj_id, sort(firestrct.obj_id) )
good_spots = where( firestrct(inds).obj_id GT -1, ngood )
if ngood EQ 0 then begin
WIDGET_CONTROL, s.wtext, set_value='No valid obj ids exist', /append
break
endif else begin
names = firestrct(inds(good_spots)).object
ids = firestrct(inds(good_spots)).obj_id
message = " obj id: " + string(ids, FORMAT='(I3)') + " object: " + fire_string(names)
WIDGET_CONTROL, s.wtext, set_value='Object IDs' + fire_str_time(), /append
WIDGET_CONTROL, s.wtext, set_value=message, /append
endelse
END
'rebuild_telluric_tree': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
if is_undefined(firestrct) EQ 0 then begin
populate_telluric_tree, firestrct, ev
endif else begin
fire_siren, func_name + ": ERROR! Cannot populate telluric tree because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
endelse
END
'strctname': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.strctname, get_value=strctname
if( is_fits( strctname ) EQ 0 ) then begin
strctname = strctname + ".fits"
WIDGET_CONTROL, s.strctname, set_value=strctname
endif
;; Check if a saved data file with this name already exists.
exists = FILE_TEST( s.cwd + '/' + strctname[0] )
if( exists EQ 0 ) then begin
WIDGET_CONTROL, s.wtext, set_value="Structure filename changed to "+strctname[0] $
+ fire_str_time() + ". No file currently saved under this name exists in the " +$
"current working directory. Hit 'Save Structure' button to save a loaded structure" + $
" to this new file name.", /append
endif else begin
WIDGET_CONTROL, s.wtext, set_value="Structure filename changed to "+strctname[0] $
+ fire_str_time() + ". A file currently saved under this name exists in the " +$
"current working directory. Hit 'Load Structure' button to read in this loaded structure.", $
/append
endelse
END
'std_pick': BEGIN
;pick working directory
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
file=DIALOG_PICKFILE(filter='*.fits', /read, path=rawpath, /must_exist)
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.stdfile, set_value=file
WIDGET_CONTROL, s.wtext, set_value='Standard star file added as '+file, /append
END
;; 'std_arc_pick': BEGIN
;; ;pick working directory
;; WIDGET_CONTROL, ev.top, get_uvalue=s
;; WIDGET_CONTROL, s.setupdir, get_value=rawpath
;; file=DIALOG_PICKFILE(filter='*.fits', /read, path=rawpath, /must_exist)
;; ;figure out which setup dir, send the path back to the top
;; WIDGET_CONTROL, s.stdarcfile, set_value=file
;; WIDGET_CONTROL, s.wtext, set_value='Standard star arc file added as '+file, /append
;; END
'std_flux_pick': BEGIN
;pick working directory
WIDGET_CONTROL, ev.top, get_uvalue=s
WIDGET_CONTROL, s.setupdir, get_value=rawpath
file=DIALOG_PICKFILE(filter='*.dat', /read, path='~/idl/xidl/Spec/Flux/', /must_exist)
;figure out which setup dir, send the path back to the top
WIDGET_CONTROL, s.stdflxfile, set_value=file
WIDGET_CONTROL, s.wtext, set_value='Standard star flux table added as '+file, /append
END
'go_sensfunc': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
if is_undefined(firestrct) EQ 1 then begin
fire_siren, func_name + ": ERROR! Cannot correct tellurics because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
fire = firestrct
slct = WIDGET_INFO(s.w_telcor_targets, /tree_select)
if( slct EQ -1 ) then begin
fire_siren, func_name + ": ERROR! Cannot correct tellurics because target has not " + $
"been chosen! Please choose a target for which to calibrate tellurics, and" + $
" then try again.", widget = s.wtext, /append
break
endif
WIDGET_CONTROL, slct, get_value=sci_object
if( is_empty(sci_object) EQ 1 OR strmatch(sci_object, "*.fits") EQ 0 ) then begin
fire_siren, func_name + ": ERROR! Cannot correct tellurics because target has not " + $
"been chosen! Please choose a target for which to calibrate tellurics, and" + $
" then try again.", widget = s.wtext, /append
break
endif
spot = where(strmatch(firestrct.objstrfile, "*" + sci_object, /FOLD_CASE), nmatches)
if nmatches EQ 1 then begin
object_name = strtrim(firestrct(spot).object,2)
WIDGET_CONTROL, s.wtext, set_value='Calibrating telluric associated with object structure ' $
+ sci_object + ', ' + object_name + fire_str_time(), /append
endif else begin
WIDGET_CONTROL, s.wtext, set_value='Calibrating telluric associated with object structure ' $
+ sci_object + fire_str_time(), /append
endelse
fire_timer, time, /start
quick = WIDGET_INFO(s.xtell_quickbt,/button_set)
clobber = WIDGET_INFO(s.xtell_clobberbt,/button_set)
fire_telluric, fire, objstrfile=sci_object, clobber=clobber, quick=quick, name = object_name
fire_timer, time, /stop
;;WIDGET_CONTROL, s.wtext, set_value='Done calibrating telluric for science object ' $
;; + sci_object + fire_str_time(Elapsed=time), /append
END
'telluric_branch': BEGIN
; fire=firestrct
; WIDGET_CONTROL, ev.top, get_uvalue=s
; slct = WIDGET_INFO(s.w_telcor_targets, /tree_select)
; WIDGET_CONTROL, slct, get_value=sci_object
; print, sci_object
; stop
END
'telluric_leaf': BEGIN
if is_undefined(firestrct) EQ 1 then begin
fire_siren, func_name + ": ERROR! Cannot select target because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
fire = firestrct
WIDGET_CONTROL, ev.top, get_uvalue=s
slct = WIDGET_INFO(s.w_telcor_targets, /tree_select)
if( slct NE -1 ) then begin
WIDGET_CONTROL, slct, get_value=sci_object
;print, sci_object
endif else begin
sci_object = ''
endelse
if (ev.clicks EQ 2) AND is_empty(sci_object) EQ 0 then begin
WIDGET_CONTROL, s.wtext, set_value='Calibrating telluric associated with object structure ' $
+ sci_object + fire_str_time(), /append
fire_telluric, fire, objstrfile=sci_object
endif
END
'go_combine': BEGIN
WIDGET_CONTROL, ev.top, get_uvalue=s
if( is_undefined(firestrct) EQ 1 ) then begin
fire_siren, func_name + ": ERROR! Cannot combine targets because firestrct has not " + $
"been created or loaded yet! Please visit the 'Structure' tag, generate/load a structure, and" + $
" then try again.", widget = s.wtext, /append
break
endif
fire=firestrct
slct = WIDGET_INFO(s.w_combine_targets, /list_select)
if( n_elements(slct) EQ 1 ) then begin
if slct EQ -1 then begin