-
Notifications
You must be signed in to change notification settings - Fork 0
/
runcalib.pro
1444 lines (1284 loc) · 59.7 KB
/
runcalib.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 runcalib, pickpath=pickpath, skypath=skypath, sub=sub, linear=linear, cubic=cubic, plot=plot, extlist=extlist, skipgc=skipgc
; This procedure is devoted to the reduction of cross scans acquired on flux calibrators and
; achieve the conversion factors cnt->Jy.
; It plots and analyses the data obtained by stacking all the subscans contained in any scan
; (i.e. subfolder) stored in the working folder.
; If users want to graphically choose the data folder, they must use:
;
; IDL> runcalib, /pickpath in order to select the path to the data parent folder (otherwise the chosen path is ./CALIBRATORS)
; IDL> runcalib, /skypath in order to select the path to the folder containing the Tau.txt file (otherwise the chosen path is ./SKYDIPS)
;
; Measurements for all the single subscans can be obtained by explicitly choosing this option:
;
; IDL> runcalib, /sub
;
; The gaussian fitting performed on the (sub)scans can be run using three different baseline-fitting options,
; in particular:
;
; IDL> runcalib, /linear performs, and outputs, only the linear fitting of baselines
; IDL> runcalib, /cubic performs, and outputs, only the cubic fitting of baselines
; IDL> runcalib, /both performs, and outputs, both the cubic and linear fitting of baselines
;
; By default, the choice is 'both'.
;
; Plot output in PDF is exceedingly slow, in particular for single subscans (if the /sub option is selected).
; So it is disabled by default.
; To enable it, explicitly set the option:
;
; IDL> runcalib, /plot
;
; If non-standard calibrators are to be considered, users must specify the /extlist option,
; which allows them to pick a proper external list, where source names and nominal flux
; densities (Jy) are provided in the simple format (A,D).
;
; The option
;
; IDL> runcalib, /skipgc
;
; overrides the use of the standard gain curves; it poses Gain=1 for all the elevations,
; thus practically avoiding the elevation-dependent gain compensation.
;
; COMPATIBILITY WITH CONVERTED FILES
; FITS files achieved with older versions of DISCOS (dating back to years 2008-2015)
; need to be converted into the proper FITS format (ask for procedure named updatefits.pro).
; The program automatically handles the TP-like files resulting from the
; conversion of SARDARA acquisitions, which have raw counts levels in the
; orders of magnitude of 10E+06..10E+07, producing properly-formatted output tables.
;
; Authors: Marcello Giroletti, Simona Righini
; Last edited: November 24, 2020 by Simona
;
common logistics, workpath, calpath, sep, skydippath, myextlist, fitchoice, dosingle, doplot, applygc, applytau
close, /all ; to close possible pending text files
sep=path_sep()
if keyword_set (sub) then dosingle='y' else dosingle='n'
if keyword_set(pickpath) then begin
workpath=dialog_pickfile(/DIRECTORY, TITLE='Please pick PARENT FOLDER containing CALIBRATION SCANS')
endif else begin
CD, CURRENT=curr
workpath=curr+sep+'CALIBRATORS'+sep
endelse
if keyword_set(skypath) then begin
skydippath=dialog_pickfile(/DIRECTORY, TITLE='Please pick folder containing file Tau.txt')
endif else begin
CD, CURRENT=curr
applytau='No'
skydippath=curr+sep+'SKYDIPS'+sep
endelse
if keyword_set(linear) then begin
fitchoice='linear'
endif else begin
if keyword_set(cubic) then fitchoice='cubic' else fitchoice='both'
endelse
if keyword_set(plot) then doplot='y' else doplot='n'
if keyword_set(extlist) then begin
myextlist=dialog_pickfile(TITLE='Please pick EXTERNAL LIST of calibrators')
endif else begin
myextlist=' '
endelse
if keyword_set(skipgc) then applygc='No' else applygc='Yes'
cal_stack, freq=freq
return
end
PRO cal_gfunct, X, A, F, pder
EX2 = A[0]*EXP(-(X-A[1])^2/(2*A[2]^2))
F = EX2 + A[3] + A[4]*X +A[5]*X^2 +A[6]*X^3
IF N_PARAMS() GE 4 THEN $
pder = [[EX2/A[0]], [EX2*(X-A[1])/(A[2]^2)], [EX2*((X-A[1])^2)/(A[2]^3)], [replicate(1.0, N_ELEMENTS(X))], [X], [X^2], [X^3]]
END
function cal_wmean, val, dval, nan = nan, error = error
compile_opt idl2
on_error, 2
;- check inputs
if n_params() ne 2 then begin
return, !values.f_nan
endif
sz = n_elements(val)
if n_elements(dval) ne sz then $
message, 'val and dval must contain the same number of elements'
;- the calculation
;- requires at least one finite value
if keyword_set(nan) then begin
hit = where(finite(val) and finite(dval), ct)
if ct eq 0 then begin
error = !values.f_nan
return, !values.f_nan
endif
endif
dw = total(1D / dval^2, nan = keyword_set(nan))
sum = total(1D * val / dval^2, nan = keyword_set(nan)) / dw
error = sqrt(1D / dw)
return, sum
end
pro cal_stack, path=path, out=out, plot=plot, beam=beam, speed=speed, dt=dt, source=source, flux=flux, freq=freq
common logistics
; !EXCEPT=2 ; enabling the indications of location/line numbers in exception messages
!EXCEPT=0 ; silencing the printout of exception messages
; reads first file from first scan to set basic info in output files
list = FILE_SEARCH(workpath+'20*', COUNT=number, /TEST_DIRECTORY)
timings=dblarr(number+1)
gap=dblarr(number+1)
timings[0]=systime(1)
gap[0]=0
sublist = FILE_SEARCH(list[0]+sep+'20*.fits', COUNT=subnumber)
; XXX ToDO: ripetere la lettura per un file di ogni sub-folder e verificare che siano omogenei
data=MRDFITS(sublist[0],4,/SILENT)
RFinfo=MRDFITS(sublist[0],2,/SILENT)
Sectinfo=MRDFITS(sublist[0],1,/SILENT)
gaintime=data[0].time ; associated MJD (first sample of first subscan)
firstscanname=strsplit(sublist[0],sep,/extract)
firstscandate=strsplit(firstscanname[-1],'-',/extract)
datesplit=strsplit(firstscandate[0],path_sep(),/extract)
yyyymmdd=datesplit[-1]
; read frequency and bandwidth from RF table
bw=RFinfo[0].bandWidth
freq=RFinfo[0].frequency+bw/2.0
dt=1.0/(Sectinfo[0].sampleRate*1e6)
if double(yyyymmdd) le double(20110301) then begin
cnt2K_0=-99.0 ; dummy
cnt2K_1=-99.0 ; dummy
ksectchoice='mf' ; K-band receiver in MED was multi-feed
endif else begin
if (double(yyyymmdd) gt double(20110301)) and (double(yyyymmdd) lt double(20120101)) and (freq ge 18000.0) then begin
Tant=MRDFITS(sublist[0],5,/SILENT)
cnt2K_0=Tant[0].ch10/data[0].ch10 ; K/cnt ricavato da uso della marca pre-scan
cnt2K_1=Tant[0].ch11/data[0].ch11 ; K/cnt ricavato da uso della marca pre-scan
ksectchoice='mf' ; K-band receiver in MED was multi-feed
endif else begin
Tant=MRDFITS(sublist[0],5,/SILENT)
cnt2K_0=Tant[0].ch0/data[0].ch0 ; K/cnt ricavato da uso della marca pre-scan
cnt2K_1=Tant[0].ch1/data[0].ch1 ; K/cnt ricavato da uso della marca pre-scan
ksectchoice='df' ; K-band receiver in MED was dual-feed
endelse
endelse
; which telescope was used? Let's get to a 3-char code to be used afterwards
firstmainh=mrdfits(sublist[0],0,firsthead0,/silent)
findh0key, firsthead0, '*ANTENNA =*', keylab, sitename, infolab, siteflag
splitsitename=strsplit(sitename,"'",/extract)
cleansite=strupcase(strcompress(splitsitename[1],/remove_all))
site=strmid(cleansite,0,3) ; this way, possible cases will be MED, SRT and NOT
case site of
'MED': begin
beam=38.7/(freq/1000.0) ; beam in arcmin
; stop
; frequency dependent normalized gain polynomials
; http://www.med.ira.inaf.it/ManualeMedicina/English/5.%20Efficiency.htm
; taken on 2015 September 17
if (freq gt 4000 and freq lt 6000) then begin
; this is C band
A_0=[7.9212981E-1,6.2403816E-3,-4.6834953E-5,0]
A_1=[7.9212981E-1,6.2403816E-3,-4.6834953E-5,0]
endif
if (freq gt 8000 and freq lt 10000) then begin
; this is X band
A_0=[0.730487,0.00773332,-5.54743e-05,0] ; updated 2015, but it is not opacity-corrected
A_1=[0.730487,0.00773332,-5.54743e-05,0] ; updated 2015, but it is not opacity-corrected
; A_0=[6.1059261E-01,1.0623634E-02,-7.2457279E-05,0] ; origin???
; A_1=[6.1059261E-01,1.0623634E-02,-7.2457279E-05,0] ; origin???
endif
if (freq gt 18000 and freq le 18500) then begin
if gaintime gt 55926.0 then begin
; this is K-low band
A_0=[0.8373589,0.005140111,-4.058370E-5,0] ; as of Sept.30, 2015
A_1=[0.8373589,0.005140111,-4.058370E-5,0] ; as of Sept.30, 2015
endif else begin
; multi-feed gain curve for feed0
A_0=[0.59778067,0.013571075,-0.00011447367,0]
A_1=[0.59778067,0.013571075,-0.00011447367,0]
print, 'BEWARE: Using gain curve for multi-feed K-band receiver'
endelse
endif
if (freq gt 18500 and freq le 26500) then begin
; this is K-high band
if gaintime gt 55926.0 then begin
A_0=[0.7929185,0.005900533,-4.203179E-5,0] ; as of Sept.30, 2015
A_1=[0.7929185,0.005900533,-4.203179E-5,0] ; as of Sept.30, 2015
endif else begin
; multi-feed gain curve for feed0
A_0=[0.59778067,0.013571075,-0.00011447367,0]
A_1=[0.59778067,0.013571075,-0.00011447367,0]
print, 'BEWARE: Using gain curve for multi-feed K-band receiver'
endelse
endif
end
'SRT': begin
; frequency dependent normalized gain polynomials
; as provided by Andrea Orlati (commissioning)
if (freq gt 4000 and freq lt 8000) then begin
; this is C band
beam=18.937/(freq/1000.0) ; beam in arcmin
A_0=[0.939813,0.00139,-0.000009,0] ; XXX To be updated
A_1=[0.939813,0.00139,-0.000009,0] ; XXX To be updated
endif
if (freq ge 18000 and freq lt 27000) then begin
; this is K band
beam=18.264/(freq/1000.0) ; beam in arcmin
if freq lt 21000 then begin
A_0=[0.508145,0.014839,-0.000111,0] ; from official SRT page
A_1=[0.508145,0.014839,-0.000111,0] ; from official SRT page
endif
if freq ge 21000 and freq le 23000 then begin
A_0=[0.606733,0.01132,-0.000081,0] ; from official SRT page
A_1=[0.606733,0.01132,-0.000081,0] ; from official SRT page
endif
if freq gt 23000 then begin
A_0=[0.533025,0.015561,-0.000129,0] ; from official SRT page
A_1=[0.533025,0.015561,-0.000129,0] ; from official SRT page
endif
endif
end
'NOT': begin
;beam=38.7/(freq/1000.0) ; beam in arcmin - CLONED FROM MEDICINA XXX
if (freq gt 4000 and freq lt 6000) then begin
; this is C band
beam=7.5 ; fixed value!
; A_0=[0.98463659,0.00017053038,1.9348601e-09,0] ; old
; A_1=[0.98463659,0.00017053038,1.9348601e-09,0] ; old
A_0=[0.95227062926,0.00198726460815,-2.0685473288e-05,0] ; Cassaro, Oct 16th 2017
A_1=[0.95227062926,0.00198726460815,-2.0685473288e-05,0] ; Cassaro, Oct 16th 2017
endif
if (freq gt 8000 and freq lt 10000) then begin
; this is X band
print, 'X Curve for Noto is not available, yet. Returning.'
return
endif
if (freq gt 18000 and freq le 26500) then begin
; this is K band
print, 'K Curve for Noto is not available, yet. Returning.'
return
endif
end
else: begin
print, 'UNKNOWN SITE: cannot apply gain curves. Returning.'
return
end
endcase
beamd=beam/60.
sd=beamd/(2*SQRT(2*ALOG(2)))
; open the main output files
if fitchoice eq 'linear' or fitchoice eq 'both' then begin
openw, Unit0, workpath+'cal_stack_lin_final.txt', /GET_LUN
openw, Unit1, workpath+'cal_stack_lin_sep.txt', /GET_LUN
printf, Unit0, FORMAT = '(A7,1X,A3)', "Site =",site
endif
if fitchoice eq 'cubic' or fitchoice eq 'both' then begin
openw, Unit10, workpath+'cal_stack_cub_final.txt', /GET_LUN
openw, Unit11, workpath+'cal_stack_cub_sep.txt', /GET_LUN
endif
if strmatch(sublist[0],'*TPlike*.*',/FOLD_CASE) then begin
TPlike=1 ; this is a SARDARA file converted/integrated in TotalPower-like format
if fitchoice eq 'linear' or fitchoice eq 'both' then begin
printf, Unit0, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1'
printf, Unit0, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt'
printf, Unit1, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1 SNR_0 SNR_1 Offset FW/HP Type'
printf, Unit1, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt deg '
endif
if fitchoice eq 'cubic' or fitchoice eq 'both' then begin
printf, Unit10, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1'
printf, Unit10, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt'
printf, Unit11, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1 SNR_0 SNR_1 Offset FW/HP Type'
printf, Unit11, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt deg '
endif
endif else begin
TPlike=2 ; this is an original TotalPower FITS
if fitchoice eq 'linear' or fitchoice eq 'both' then begin
printf, Unit0, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1'
printf, Unit0, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt'
printf, Unit1, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1 SNR_0 SNR_1 Offset FW/HP Type'
printf, Unit1, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt deg '
endif
if fitchoice eq 'cubic' or fitchoice eq 'both' then begin
printf, Unit10, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1'
printf, Unit10, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt'
printf, Unit11, ' Name HHMMSS # MJD Freq Elev Amp_0 Amp_1 e_Amp_0 e_Amp_1 c2J_0 c2J_1 e_c2J_0 e_c2J_1 SNR_0 SNR_1 Offset FW/HP Type'
printf, Unit11, ' MHz deg count count count count Jy/cnt Jy/cnt Jy/cnt Jy/cnt deg '
endif
endelse
openw, Unit2, workpath+'cal_prints.txt', /GET_LUN
openw, Unit19, workpath+'gain_lin.txt', /GET_LUN
printf, Unit19, '# Gain estimates obtained using the Tant data table inside FITS,'
printf, Unit19, '# in turn produced considering the pre-scan ON-OFF mark usage during Tsys measurements.'
printf, Unit19, '# This estimate is by default corrected for the nominal gain curve shape'
printf, Unit19, '# (i.e. corrected for the elevation position).'
printf, Unit19, '# Furthermore, if the /skypath option was chosen for the analysis and a'
printf, Unit19, '# correct Tau.txt file was found, these estimates are also corrected for opacity.'
printf, Unit19, ' '
printf, Unit19, '# If “apparent” gains are needed, i.e. not compensated for opacity'
printf, Unit19, '# and elevation, use the pipeline without the /skypath option and'
printf, Unit19, '# selecting the /skipgc option. This way, no opacity or gain curve'
printf, Unit19, '# correction will be applied.'
printf, Unit19, ' '
printf, Unit19, ' CALIBRATOR Elevat MJD G_0 G_1'
printf, Unit19, ' deg K/Jy K/Jy'
openw, Unit20, workpath+'gain_cub.txt', /GET_LUN
printf, Unit20, '# Gain estimates obtained using the Tant data table inside FITS,'
printf, Unit20, '# in turn produced considering the pre-scan ON-OFF mark usage during Tsys measurements.'
printf, Unit20, '# This estimate is by default corrected for the nominal gain curve shape'
printf, Unit20, '# (i.e. corrected for the elevation position).'
printf, Unit20, '# Furthermore, if the /skypath option was chosen for the analysis and a'
printf, Unit20, '# correct Tau.txt file was found, these estimates are also corrected for opacity.'
printf, Unit20, ' '
printf, Unit20, '# If “apparent” gains are needed, i.e. not compensated for opacity'
printf, Unit20, '# and elevation, use the pipeline without the /skypath option and'
printf, Unit20, '# selecting the /skipgc option. This way, no opacity or gain curve'
printf, Unit20, '# correction will be applied.'
printf, Unit20, ' '
printf, Unit20, ' CALIBRATOR Elevat MJD G_0 G_1'
printf, Unit20, ' deg K/Jy K/Jy'
; reads skydip information
ans=file_test(skydippath+'Tau.txt')
if ans eq 1 then begin
readcol, skydippath+'Tau.txt', tau_mjd, tau_freq, t30l, t90l, t30r, t90r, tau_empL, tau_empR, tau0L, tau0R, format='(d,d,d,d,d,d,d,d,d,d)', /SILENT
for t=0,n_elements(tau_mjd)-1 do begin
; if for any reason tau_emp is considered more reliable than tau0, uncomment the following two lines
; tau0L[t]=tau_empL[t]
; tau0R[t]=tau_empR[t]
endfor
caltau = 1
applytau = 'Yes'
endif else begin
print, ' '
print, '+++++++++++++++++++++++++++++++++++++++++++++'
print, 'Beware: no Tau.txt available, assuming tau0=0'
print, '+++++++++++++++++++++++++++++++++++++++++++++'
applytau = 'No'
wait, 0.5
tau0L=[0,0]
tau0R=[0,0]
caltau = 0
endelse
; definition of arrays
p0=fltArr(2)
p1=fltArr(2)
e0=fltArr(2)
e1=fltArr(2)
c0=fltArr(2) ; count to jansky array
c1=fltArr(2)
d0=fltArr(2) ; error on count to jansky array
d1=fltArr(2)
SNR0=fltArr(2)
SNR1=fltArr(2)
offset=dblArr(2)
p0c=fltArr(2)
p1c=fltArr(2)
e0c=fltArr(2)
e1c=fltArr(2)
c0c=fltArr(2) ; count to jansky array
c1c=fltArr(2)
d0c=fltArr(2) ; error on count to jansky array
d1c=fltArr(2)
SNR0c=fltArr(2)
SNR1c=fltArr(2)
offsetc=dblArr(2)
fw_ratio0=fltarr(2)
fw_ratio1=fltarr(2)
fw_ratio0c=fltarr(2)
fw_ratio1c=fltarr(2)
; scan-based analysis
for i =0,number-1 do begin
print, ' '
print, '========================================='
print, 'Now analysing scan ', list[i]
print, '========================================='
sommaL=0
sommaR=0
sommaLA = 0
sommaRA = 0
numLA = 0
numRA = 0
iiA = 0
ffA = 0
sommaLB = 0
sommaRB = 0
numLB = 0
numRB = 0
iiB = 0
ffB = 0
splitfoldname1=strsplit(list[i],sep,/extract)
foldname=splitfoldname1[-1]
splitfoldname2=strsplit(foldname,'-',/extract)
hhmmss = splitfoldname2[1]
sublist = FILE_SEARCH(list[i]+sep+'2*.fits', COUNT=subnumber)
subscan=file_basename(sublist)
; reads flagging info
err=0
checkfile = list[i]+sep+'checkfile_'+foldname+'.txt'
openr, Unit9, checkfile, ERROR=err, /GET_LUN
flagcode=strarr(subnumber)
flagcode[*]='+1cx'
if (err lt 0) then begin
print, "No valid flagging information for this scan --> assuming all scans are good"
endif else begin
readcol, checkfile, F='a,a,a', subscan_t, flagcode_t, who, /SILENT
if (n_elements(subscan_t) lt subnumber) then begin
print, "Some subscans lack flagging information --> assuming those subscans are good"
endif
for n_flag = 0, n_elements(subscan_t)-1 do begin
for j_flag = 0, subnumber-1 do begin
if (subscan_t[n_flag] eq subscan[j_flag]) then begin
flagcode[j_flag]=flagcode_t[n_flag]
endif
endfor
endfor
close, Unit9
free_lun, Unit9
endelse
if dosingle eq 'y' then begin
; creating output files for single-subscan analysis
if fitchoice eq 'linear' or fitchoice eq 'both' then begin
openw, Unit3, list[i]+sep+'cal_single_linear.txt', /GET_LUN
printf, Unit3,' Name # MJD El(r) El(d) cnt_0 cnt_1 e_c_0 e_c_1 offL(d) offR(d) FW/HP scantype'
endif
if fitchoice eq 'cubic' or fitchoice eq 'both' then begin
openw, Unit4, list[i]+sep+'cal_single_cubic.txt', /GET_LUN
printf, Unit4,' Name # MJD El(r) El(d) cnt_0 cnt_1 e_c_0 e_c_1 offL(d) offR(d) FW/HP scantype'
endif
openw, Unit5, list[i]+sep+'cal_prints.txt', /GET_LUN
endif
; Dynamic arrays (for amplitudes and errors, for each section)
Lampl=[ ]
Rampl=[ ]
Lerrs=[ ]
Rerrs=[ ]
offset_sub=[ ]
type=[ ]
mean_lat=[ ]
; subscan-based measurements
for j=0,subnumber-1 do begin
k2Jy_0=-99.0 ; default value
k2Jy_1=-99.0 ; default value
; READ DATA TABLE (binary data table of the MegaTable FITS file)
data=MRDFITS(sublist[j],4,/SILENT)
RFinfo=MRDFITS(sublist[j],2,/SILENT)
Sectinfo=MRDFITS(sublist[j],1,/SILENT)
; read frequency and bandwith from RF table
bw=RFinfo[0].bandWidth
freq=RFinfo[0].frequency+bw/2.0
dt=1.0/(Sectinfo[0].sampleRate*1e6)
ndat = (size(data.time))
; takes source name and subscantype from header
mainh=mrdfits(sublist[j],0,head0,/silent)
; assessing whether this is an old converted FITS
findh0key, head0, '*Converted FITS*', keylab, converted, infolab, convertedflag
findh0key, head0, '*Obtained from ESCS 0.1 TP FITS*', keylab, version, infolab, oldestflag
if convertedflag eq 0 then begin ; this IS NOT a converted file: ESCS 0.3 keyword names hold
findh0key, head0, '*SOURCE*', keylab, target, infolab, tarflag
findh0key, head0, '*SubScanType =*', keylab, orscantype, infolab, tarflag
findh0key, head0, '*Azimuth Offset =*', keylab, hAZoff, infolab, typeflag ; offset utente e di sistema
findh0key, head0, '*Elevation Offset =*', keylab, hELoff, infolab, typeflag ; offset utente e di sistema
findh0key, head0, '*RightAscension Offset =*', keylab, hRAoff, infolab, typeflag ; offset utente e di sistema
findh0key, head0, '*Declination Offset =*', keylab, hDECoff, infolab, typeflag ; offset utente e di sistema
findh0key, head0, '*RightAscension =*', keylab, ras, infolab, typeflag ; RA nominale del target, radianti
findh0key, head0, '*Declination =*', keylab, decs, infolab, typeflag ; DEC nominale del target, radianti
endif else begin ; this IS a converted file: custom 8-char keyword names hold according to original FITS date, and offsets are not present
findh0key, head0, '*SOURCE*', keylab, target, infolab, tarflag
findh0key, head0, '*SUBSCANT=*', keylab, orscantype, infolab, tarflag
hAZoff=0.0d
hELoff=0.0d
hRAoff=0.0d
hDECoff=0.0d
if oldestflag eq 0 then begin
findh0key, head0, '*RightAscension =*', keylab, ras, infolab, typeflag ; RA nominale del target, radianti
findh0key, head0, '*Declination =*', keylab, decs, infolab, typeflag ; DEC nominale del target, radianti
endif else begin ; these are the oldest FITS, where several more keywords have converted names
findh0key, head0, '*RIGHTASC=*', keylab, ras, infolab, typeflag ; RA nominale del target, radianti
findh0key, head0, '*DECLINAT=*', keylab, decs, infolab, typeflag ; DEC nominale del target, radianti
endelse
endelse
; assigning labels and coefficients to calibrators
target=strcompress(target, /remove_all)
cleantarget=strsplit(target,"'",/extract)
target=cleantarget[0]
sourcename=target
method='none'
case strupcase(target) of
'3C48': begin
calflux, strupcase(target), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C123': begin
; here follows a patch made necessary by a schedule mistake: 3C48 was observed instead of 3C123, using 3C123 as target name!
if abs(ras*180.0/!dpi - 24.4221) lt 0.1 and abs(decs*180.0/!dpi - 33.1598) lt 0.1 then begin
target='3C48'
sourcename=target
endif
calflux, strupcase(target), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C123RA': begin
calflux, strupcase('3C123'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C123DEC': begin
calflux, strupcase('3C123'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C147': begin
calflux, strupcase(target), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C161': begin
a=1.250
b=+0.726
c=-0.2286
low=1408
high=10550
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='Ott'
end
'3C286': begin
calflux, strupcase(target), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C286RA': begin
calflux, strupcase('3C286'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C286DEC': begin
calflux, strupcase('3C286'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C295': begin
calflux, strupcase(target), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C295RA': begin
calflux, strupcase('3C295'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'3C295DEC': begin
calflux, strupcase('3C295'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'NGC7027': begin
calflux, strupcase(target), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'NGC7027RA': begin
calflux, strupcase('NGC7027'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'NGC7027DEC': begin
calflux, strupcase('NGC7027'), freq/1000.0, intSnu, intSnu_err
method='P&B'
end
'DR21': begin
a=1.810
b=-0.122
c=0.0
low=7000
high=31000
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='Ott'
end
'MYSRC': begin
; assuming flux density = 1 Jy
a=0.00
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
end
'CAL100': begin
; fake source for tests, having flux density=0.1 Jy
a=-1.00
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
end
'CAL0500': begin
; fake source for tests, having flux density=0.5 Jy
a=-0.301030
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
end
'CAL1000': begin
; fake source for tests, having flux density=1 Jy
a=0.00
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
end
'CAL2000': begin
; fake source for tests, having flux density=2 Jy
a=0.30103
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
end
'CAL3000': begin
; fake source for tests, having flux density=3 Jy
a=0.4771212
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
end
else: begin
; reading external list
if myextlist ne ' ' then begin
readcol, myextlist, extcalname, extcalflux, format='(A,D)', /SILENT
foundit=where(strmatch(extcalname,target,/FOLD_CASE) eq 1)
if foundit eq -1 then begin
print, ' '
print, target+' is an unknown calibrator, cannot retrieve a flux density to use:'
print, 'it will return dummy values in the measurements'
print, ' '
a=4.00
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
endif else begin
a=alog10(extcalflux[foundit]) ; fixed value, as the external list does not contain polynomials
b=0.00
c=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
endelse
endif else begin
print, ' '
print, target+' is an unknown calibrator, cannot retrieve a flux density to use:'
print, 'it will return dummy values in the measurements'
print, ' '
a=0.00
b=0.00
flux=10^(a+b*alog10(freq)+c*alog10(freq)*alog10(freq))
method='CustomSRC'
endelse
endelse
endcase
; aligning the P&B estimates to the general nomenclature
if method eq 'P&B' then begin
flux=intSnu
method="Perley & Butler, 2013"
endif
if j eq 0 then begin
; expliciting the flux density computation result, only for the first subscan
print, ' '
print, '*********************'
print, sourcename, 'Flux density', flux, ' Jy at', freq/1000.0, 'GHz', format='(A,1X,A,1X,D6.3,1X,A,1X,D5.2,1X,A3)'
print, 'Estimate by', method, format='(A,1X,A)'
print, '*********************'
endif
; nominal target coordinates, converted in degrees
rasd=ras*180.0d/!dpi
decsd=decs*180.0d/!dpi
elapsed=(double(data.time)-double(data[0].time))*24.0*3600.0 ; elapsed time from first sample
duration=dt*ndat[1]/60.0 ; duration of the whole subscan (approx)
; RA and DEC span of the subscan
deltaDec=abs(data[0].decj2000-data[-1].decj2000)/!dpi*180.0
deltaRA=abs(data[0].raj2000-data[-1].raj2000)*cos(mean(data.decj2000))/!dpi*180.0
; determine speed (deg/min) along scan direction
; if type is AZ or EL, treats is as DEC or RA depending on which quantity spans a larger range
splitscantype=strsplit(orscantype,"'",/extract)
cleanscantype=strcompress(splitscantype[1], /remove_all) ; cleaning the string so that it become more manageable
case cleanscantype of
'DEC': begin
if (data[0].decj2000 lt data[-1].decj2000) then scantype = 1 else scantype = 2
speed=deltaDec/duration
end
'RA': begin
if (data[0].raj2000 lt data[-1].raj2000) then scantype = 3 else scantype = 4
speed=deltaRA/duration
end
'AZ': begin
if (deltaDec gt deltaRA) then begin
if (data[0].decj2000 lt data[-1].decj2000) then scantype = 1 else scantype = 2
speed=deltaDec/duration
endif
if (deltaDec lt deltaRA) then begin
if (data[0].raj2000 lt data[-1].raj2000) then scantype = 3 else scantype = 4
speed=deltaRA/duration
endif
end
'EL': begin
if (deltaDec gt deltaRA) then begin
if (data[0].decj2000 lt data[-1].decj2000) then scantype = 1 else scantype = 2
speed=deltaDec/duration
endif
if (deltaDec lt deltaRA) then begin
if (data[0].raj2000 lt data[-1].raj2000) then scantype = 3 else scantype = 4
speed=deltaRA/duration
endif
end
'UNKNOWN': begin
if (deltaDec gt deltaRA) then begin
if (data[0].decj2000 lt data[-1].decj2000) then scantype = 1 else scantype = 2
speed=deltaDec/duration
endif
if (deltaDec lt deltaRA) then begin
if (data[0].raj2000 lt data[-1].raj2000) then scantype = 3 else scantype = 4
speed=deltaRA/duration
endif
end
endcase
; check for spikes in X-band wide bandwidth data XXX Perché farlo solo per la banda X?
if (bw gt 500 and freq lt 10000) then begin
for k=3, ndat[1]-4 do begin
temp0=[data[k-3].ch0,data[k-2].ch0,data[k-1].ch0,data[k+1].ch0,data[k+2].ch0,data[k+3].ch0]
temp1=[data[k-3].ch1,data[k-2].ch1,data[k-1].ch1,data[k+1].ch1,data[k+2].ch1,data[k+3].ch1]
avech0=mean(temp0)
avech1=mean(temp1)
stdch0=stddev(temp0)
stdch1=stddev(temp1)
if ((data[k].ch0-avech0) gt 7*stdch0) then begin
data[k].ch0=avech0
endif
if ((data[k].ch1-avech1) gt 7*stdch1) then begin
data[k].ch1=avech1
endif
endfor
endif
; reverse arrays for scans in decreasing RA or Dec
if (scantype eq 2 or scantype eq 4) then begin
; data=reverse(data)
data.raj2000=reverse(data.raj2000)
data.decj2000=reverse(data.decj2000)
if freq ge 18000 and site eq 'MED' and ksectchoice eq 'mf' then begin
data.ch10=reverse(data.ch10) ; original line
data.ch11=reverse(data.ch11)
endif else begin
data.ch0=reverse(data.ch0) ; original line
data.ch1=reverse(data.ch1)
endelse
endif
; computing the sample offset with respect to the source position
xdec=(data.decj2000-decs)/!dpi*180.0
xra=(data.raj2000-ras)*cos(mean(data.decj2000))/!dpi*180.0
scanname = sublist[j]
case flagcode[j] of
'-1c0': begin
k0=1
k1=0
end
'-1c1': begin
k0=0
k1=1
end
'+0cx': begin
k0=1
k1=1
end
'+1cx': begin
k0=1
k1=1
end
'-1cx': begin
k0=0
k1=0
end
endcase
; shift scans of type 'Dec' so they align with first one; sets start and end value of array with data from every scan
if (scantype eq 1 or scantype eq 2) then begin
if ((numLA+numRA) eq 0) then begin
dataA=data
ndatA=ndat
xdecA=xdec
iiA=0
if (k0+k1 gt 0) then ffA=ndatA[1]-1
decoffA = min(xdecA,xdec0A,/ABSOLUTE) ; xdec0A is the number of sample at the source declination for scan A
endif else begin
decoff = min(xdec,xdec0,/ABSOLUTE)
; shift data by (xdec0-xdec0B) samples
ndelta=xdec0-xdec0A
if (ndelta gt 0) then begin
iiA=iiA
if (k0+k1 gt 0) then ffA=min([ffA,ndat[1]-1-ndelta])
for k=iiA,ffA do begin
if (k0+k1 gt 0) then data[k]=data[k+ndelta]
endfor
endif
if (ndelta lt 0) then begin
if (k0+k1 gt 0) then iiA=max([iiA,0-ndelta])
; here we have a problem: we would like to start from ffA and go down to iiA, since ffA can be filled by shifting "data" right. but data only has dimension ndat, not ndat-ndelta (ndelta is <0)
; ffA=min([ffA,ndat[1]-1-ndelta])
if (k0+k1 gt 0) then ffA=min([ffA,ndat[1]-1])
for k=ffA,iiA,-1 do begin
if (k0+k1 gt 0) then data[k]=data[k+ndelta]
endfor
endif
if (ndelta eq 0) then begin
if (k0+k1 gt 0) then ffA=min([ffA,ndat[1]-1])
endif
endelse
endif
; shifts scans of type 'RA' so they align with first one; sets start and end value of array with data from every scan
if (scantype eq 3 or scantype eq 4) then begin
if ((numLB+numRB) eq 0) then begin
dataB=data
ndatB=ndat
xraB=xra
iiB=0
if (k0+k1 gt 0) then ffB=ndatB[1]-1
raoffB = min(xraB,xra0B,/ABSOLUTE) ; xra0B is the number of sample at the source right ascension for scan B
endif else begin
raoff = min(xra,xra0,/ABSOLUTE)
; shift data by (xra0-xra0B) samples
ndelta=xra0-xra0B
if (ndelta gt 0) then begin
iiB=iiB
if (k0+k1 gt 0) then ffB=min([ffB,ndat[1]-1-ndelta])
for k=iiB,ffB do begin
if (k0+k1 gt 0) then data[k]=data[k+ndelta]
endfor
endif
if (ndelta lt 0) then begin
if (k0+k1 gt 0) then iiB=max([iiB,0-ndelta])
; here we have a problem: we would like to start from ffB and go down to iiB, since ffB can be filled by shifting "data" right. but data only has dimension ndat, not ndat-ndelta (ndelta is <0)
; ffB=min([ffB,ndat[1]-1-ndelta])
if (k0+k1 gt 0) then ffB=min([ffB,ndat[1]-1])
for k=ffB,iiB,-1 do begin
if (k0+k1 gt 0) then data[k]=data[k+ndelta]
endfor
endif
if (ndelta eq 0) then begin
if (k0+k1 gt 0) then ffB=min([ffB,ndat[1]-1])
endif
endelse
endif
time_s = (data.time-data[round(ndat[1]/2)].time)*24.d0*3600.d0
midscan=FIX(ndat[1]/2)
beamspan= beam/speed ; duration of acquisition for one beamwidth
Nsamples=ROUND(beamspan/dt) ; number of samples in one beamwidth
el_d=data[midscan].el*180.0/!dpi
g_0=A_0[0]+A_0[1]*el_d+A_0[2]*el_d^2+A_0[3]*el_d^3
g_1=A_1[0]+A_1[1]*el_d+A_1[2]*el_d^2+A_1[3]*el_d^3
if applygc eq 'No' then begin
; Overriding the gain computation and applying a flat gain curve (constant value = 1.0)
g_0=1.0
g_1=1.0
endif
; actually sums counts only for scans flagged as good and sets inputs for single scan fit
if ( scantype eq 1 or scantype eq 2) then begin
if freq ge 18000 and site eq 'MED' and ksectchoice eq 'mf' then begin
if (k0 ne 0) then sommaLA = sommaLA + k0*data.ch10/g_0 ; original line
if (k1 ne 0) then sommaRA = sommaRA + k1*data.ch11/g_1
endif else begin
if (k0 ne 0) then sommaLA = sommaLA + k0*data.ch0/g_0 ; original line
if (k1 ne 0) then sommaRA = sommaRA + k1*data.ch1/g_1
endelse
numLA = numLA + k0*1
numRA = numRA + k1*1
ascissa=(data.decj2000-hDECoff)*180d/!dpi
gpos=decsd
endif else begin
if freq ge 18000 and site eq 'MED' and ksectchoice eq 'mf' then begin
if (k0 ne 0) then sommaLB = sommaLB + k0*data.ch10/g_0 ; original line
if (k1 ne 0) then sommaRB = sommaRB + k1*data.ch11/g_1
endif else begin
if (k0 ne 0) then sommaLB = sommaLB + k0*data.ch0/g_0 ; original line
if (k1 ne 0) then sommaRB = sommaRB + k1*data.ch1/g_1
endelse
numLB = numLB + k0*1
numRB = numRB + k1*1
ascissa=(data.raj2000-hRAoff/cos(mean(data.decj2000)))*180d/!dpi
gpos=rasd
endelse
if dosingle eq 'y' then begin
if (fitchoice eq 'linear') or (fitchoice eq 'both') then begin
; fit single subscans with linear + gaussian
Lfwhm=0
Rfwhm=0
if freq ge 18000 and site eq 'MED' and ksectchoice eq 'mf' then begin
yy0=data.ch10/g_0 ; original line
yy1=data.ch11/g_1
endif else begin
yy0=data.ch0/g_0 ; original line
yy1=data.ch1/g_1
endelse
if (scantype eq 1 or scantype eq 2) then tipo=0 else tipo=1
calibfit, k0,'single','linear','Ch_0',tipo,list[i],subscan[j],Unit5,flux,data[0].el,tau0L,ascissa,yy0,0,ndat[1]-1,midscan,Nsamples,sd*(1.+tipo*(1./cos(decs)-1.)),gpos,decsd,rasd, Lfwhm, nL, offL, peak_cnt_0, err_cnt_0, dum3, dum4, dum5, psingle, doplot
calibfit, k1,'single','linear','Ch_1',tipo,list[i],subscan[j],Unit5,flux,data[0].el,tau0R,ascissa,yy1,0,ndat[1]-1,midscan,Nsamples,sd*(1.+tipo*(1./cos(decs)-1.)),gpos,decsd,rasd, Rfwhm, nR, offR, peak_cnt_1, err_cnt_1, dum3, dum4, dum5, psingle, doplot
if doplot eq 'y' then begin
splitscan=strsplit(subscan[j],'.',/extract)
scanroot=splitscan[0]
if (j eq subnumber-1) then begin
; psingle.save, list[i]+'_lin_single.pdf', /LANDSCAPE, RESOLUTION=300, /APPEND, /CLOSE
endif else begin
; psingle.save, list[i]+sep+scanroot+'_single.pdf', /LANDSCAPE, RESOLUTION=300, /APPEND
endelse
endif
if TPlike eq 2 then begin
printf, Unit3, FORMAT = '(a15,D12.5,9(" ",D08.4),i)', sourcename, data[midscan].time,$
data[midscan].el, el_d, peak_cnt_0, peak_cnt_1, err_cnt_0, err_cnt_1, offL, offR, Lfwhm/beam, scantype
endif else begin
printf, Unit3, FORMAT = '(a15,1X,D12.5,1X,D08.4,1X,D08.4,1X,E12.6,1X,E12.6,1X,E12.6,1X,E12.6,1X,D08.4,1X,D08.4,1X,D08.4,1X,i)', sourcename, data[midscan].time,$