-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathselfcal_LTS.py
2102 lines (1843 loc) · 96.5 KB
/
selfcal_LTS.py
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
'''
This module contains all the functions required by selfcal_LTS.py to perform selfcal.
'''
import sys
import os
import numpy as np
import time
import glob
import pickle,pyfits
#from numpy import nanstd, nanmedian #For CASA 5.1
from scipy.stats import nanstd,nanmedian
import datetime as dt
import numpy.ma as ma
from numpy import matrix
import matplotlib.pyplot as plt
import selfcal_input
reload(selfcal_input)
del selfcal_input
from selfcal_input import *
def apply_acorr(dat, ants1, ants2, idx_ant, elen, tile, uvw, BW, fout):
"""
Amplitude correction for the beamformer-to-receiver cable length
differences (""decorrelation"")
"""
c_speed_of_light = 299792458. # m/s
tauw_sign = +1.
iau = np.where(ants1 == ants2)[0] # Pointers into ants where a1 == a2
uant = ants1[iau] # Unique antennas in the same order as they appear
nant = len(uant) # Number of unique antennas
antmax = ants1.max() # Max antenna numeric *name*
#
# Fill in the array of antenna indices idx_ant
#
iuant = 0
for ia in uant:
idx_ant[ia] = iuant
iuant = iuant + 1
#
# Baseline u,v,w coordinates and lengths
#
u = uvw[0,:]
v = uvw[1,:]
w = uvw[2,:]
blen = np.sqrt(u**2 + v**2)
#
# Amplitude-corrected data block
#
cdat = np.zeros_like(dat)
ndat = len(dat[0,0,:]) # Number of correlations per a pol and a chan
#
# Loop over all the baselines
#
fout.write('# a1 tl1 elen1 tau1 a2 tl2 ' \
'elen2 tau2 blen w tauw acor\n')
for idat in xrange(ndat):
a1 = ants1[idat] # First antenna 'name'
a2 = ants2[idat] # Second antenna 'name'
ia1 = idx_ant[a1] # First antenna index
ia2 = idx_ant[a2] # Second antenna index
#
# Here we calculate the cable delays for each pair of tiles,
# tau1 and tau2, from their electrical cable lengths, elen.
# Also, from the wave number (in meters), w, we get the
# geometric delay between the tiles, tauw.
# The delays are combined in tau:
#
tau1 = elen[ia1]/c_speed_of_light
tau2 = elen[ia2]/c_speed_of_light
# Let us not take this into account for a time being
tauw = w[idat]/c_speed_of_light
tau = tau2 - tau1 + tauw_sign*tauw
#
# The correction factor, acor, is the result of integration:
#
# acor = {1/BW}\int_{-BW/2}^{+BW/2} cos(2\pi f tau) df = sinc(BW tau).
#
acor = np.sinc(BW*tau)
line = '%4d %4d %9.2f %12.5e %4d %4d %9.2f %12.5e ' \
'%8.2f %8.2f %12.5e %9.6f\n' % \
(a1, tile[ia1], elen[ia1], tau1, \
a2, tile[ia2], elen[ia2], tau2, \
blen[idat], w[idat], tauw, acor)
fout.write(line)
#print 'tau2=%g, tau1=%g, tauw=%g, w=%g, tau=%g, acor=%g' % \
# (tau2, tau1, tauw, w[idat], tau, acor)
cdat[:,:,idat] = dat[:,:,idat] / acor
return cdat
def calc_flagged_ant(msname):
ms.open(msname)
ms.selectinit(datadescid=0)
flag = ms.getdata("flag",ifraxis=True)["flag"]
ms.close()
flagged_ant = 0
for ant1 in range(128):
temp=0
for ant2 in range(128):
if (ant1==ant2):
continue
min_ant=min(ant1,ant2)
max_ant=max(ant1,ant2)
index=128*min_ant-(min_ant-1)*min_ant/2+(max_ant-min_ant)
if flag[0,0,index,0]==True or flag[1,0,index,0]==True:
temp+=1
if (temp>100):
flagged_ant+=1
print 'Flagged antenna: ',flagged_ant
del flag
del max_ant
del min_ant
del index
del ant1
del ant2
return flagged_ant
def calc_psf(freq):
lambda1 = 299792458.0/freq
psf = 1.42*lambda1/max_baseline*180/np.pi*3600 #### this is in arcsecs
del lambda1
return psf
def check_inellipse(x,y,x0,y0,a,b,R=np.eye(2)):
x_v=np.matrix([[x-x0],[y-y0]])
R=np.matrix(R)
xp_v=R*x_v
xp_v=np.array(xp_v.transpose()).reshape(2)
if xp_v[0]**2/a**2 + xp_v[1]**2/b**2<1:
out=True
else:
out=False
del x_v
del R
del xp_v
return out
def check_source_true_loc(true_loc_folder,msname,ref_time_str,timerange,cellsize,imsize,STOKES,fitstim,chan,taper):
'''
This code takes in the MS name and time chosen as reference (ref_pos_time) to solar position on the sky. Code assumes the MS to have calibrator cal tables applied. This code will apply the phase solutions coresponding to the ref_pos_time MS and cleans. It notes the location of the brightest source.
'''
strt=time.time()
cal_tabs=glob.glob(ref_time_str)
if len(cal_tabs)==0:
raise RuntimeError('Calibration tables for reference position time slice don\'t exist')
applycal(vis=msname,gaintable=cal_tabs,timerange=timerange)
print 'Applycal done..',cal_tabs[0:2],'..etc'
junkname='test_loc_img'
clean(vis=msname,threshold='10Jy',niter=1000,imagename=junkname,timerange=timerange,cell=cellsize,imsize=imsize,weighting='natural',stokes=STOKES,psfmode='hogbom',uvtaper=True,outertaper=[taper+'lambda', taper+'lambda', '0deg'],innertaper=['0deg','0deg','0deg'],robust=0.0,gain=0.05)
exportfits(imagename=junkname+'.image',fitsimage=true_loc_folder+'/Sun_trueloc_img_'+fitstim+'_'+chan+'_full_'+STOKES+'.fits',overwrite=True)
print 'True location image written out: ','Sun_trueloc_img_',fitstim+'_',chan,'_full_',STOKES,'.fits'
st=imstat(junkname+'.image')
maxpix=st['max'][0]
maxpos=st['maxpos'][0:2]
clearcal(msname)
del st
### Test for dominant source...Reliability of the max pos and derived centroid shift depends on this.###
st=imhead(junkname+'.image')
circ1=st['restoringbeam']['major']['value']/cellsize*1.05
circ2=st['restoringbeam']['minor']['value']/cellsize*1.05
posang=st['restoringbeam']['positionangle']['value']*np.pi/180.
rad=np.max([circ1,circ2])/2*1.6
del st
ia.open(junkname+'.image')
mat=ia.getchunk([maxpos[0]-rad,maxpos[1]-rad],[maxpos[0]+rad,maxpos[1]+rad])
mat=mat.reshape(mat.shape[0],mat.shape[1])
ia.close()
m=mat.shape[0]
n=mat.shape[1]
xb,yb=np.where(mat==np.max(mat))
xb=xb[0]
yb=yb[0]
R=np.array([[np.cos(posang),-np.sin(posang)],[np.sin(posang),np.cos(posang)]])
for i in range(m):
for j in range(n):
if(check_inellipse(i,j,xb,yb,circ1/2,circ2/2,R)):
mat[i,j]=np.nan
if(check_inellipse(i,j,xb,yb,circ1*3/4,circ2*3/4,R)==False):
mat[i,j]=np.nan
medpix=nanmedian(mat.flatten())
if medpix<maxpix*0.6:
reliability=True
else:
reliability=False
os.system('rm -rf '+junkname+'*')
print 'Source True loc found...'
print 'Time taken: ',(time.time()-strt)/60.,' min.'
del mat
del R
del circ1
del circ2
del posang
del rad
del strt
del cal_tabs
del medpix
del maxpix
del xb
del yb
del junkname
return reliability,maxpos
def choose_scales(cellsize,psf):
sun_dia = 16*60 ### in arcsecs
psf_pix = int(psf/cellsize)
scale=[0,psf_pix,3*psf_pix,int(sun_dia/cellsize)] ### choosing scale to be [0,psf,3*psf, sun_dia/2]
del sun_dia
del psf_pix
return scale
def clean_as_necessary(want_deep,msname,final_image_poln,cellsize,imsize,weighting,sigma,maskfile,fits_imagename,fits_modelname,BOX,header_dict,scales,threshold='',selfcal_success=True):
print 'Final deep clean being done..'
junkimg='junk_'+msname[:-3]
if (want_deep==True):
saturate_clean=False
dyn_range=0
clean_iter=0
while (saturate_clean==False):
clean(vis=msname,imagename=junkimg,outlierfile="",field="",spw="",selectdata=True,timerange='',uvrange="",antenna="",scan="", observation="",intent="",mode="mfs",resmooth=False,gridmode="widefield",wprojplanes=1,facets=1, cfcache="cfcache.dir",rotpainc=5.0,painc=360.0,aterm=True,psterm=False,mterm=True,wbawp=False,conjbeams=True,epjtable="", interpolation="linear", niter=2000,gain=0.05,threshold="0Jy",psfmode="hogbom",imagermode="",ftmachine="mosaic",mosweight=False,scaletype="SAULT",multiscale=scales,negcomponent=-1, smallscalebias=0.6,interactive=False,mask=[maskfile],nchan=-1,start=0,width=1,outframe="",veltype="radio", imsize=imsize,cell=cellsize, phasecenter="",restfreq="",stokes=final_image_poln,weighting=weighting,robust=0.0,uvtaper=False,outertaper=[],innertaper=[], modelimage='',restoringbeam=[''],pbcor=False,minpb=0.2,usescratch=False, noise="1.0Jy",npixels=0,npercycle=100, cyclefactor=5,cyclespeedup=-1,nterms=1,reffreq="",chaniter=False,flatnoise=True,allowchunk=False)
rms = imstat(imagename=junkimg+".image",axes=-1,region=region_file,box=BOX,chans="",stokes="",listit=True,verbose=True,mask=[],stretch=False,logfile="",append=True,algorithm="classic",fence=-1,center="mean",lside=True,zscore=-1,maxiter=-1,clmethod="auto")["rms"][0]
max_pix = imstat(imagename=junkimg+".image",axes=-1,region="",box="",chans="",stokes="",listit=True,verbose=True,mask=[],stretch=False,logfile="",append=True,algorithm="classic",fence=-1,center="mean",lside=True,zscore=-1,maxiter=-1,clmethod="auto")["max"][0]
if (max_pix/rms<dyn_range or clean_iter>150000):
saturate_clean=True
dyn_range=max_pix/rms
clean_iter+=2000
exportfits(imagename=junkimg+".image",fitsimage=fits_imagename,history=False,dropdeg=False,overwrite=True)
exportfits(imagename=junkimg+".model",fitsimage=fits_modelname,history=False,dropdeg=False,overwrite=True)
print 'Fits image and model written out..'
os.system("rm -rf "+junkimg+".*")
del rms
del max_pix
else:
if len(threshold)==0:
imgtag='_'.join(msname.split('_')[:-1])+'*.image'
lastimg=sorted(glob.glob(imgtag))[-1]
rms=imstat(imagename=lastimg,box=BOX,listit=True)['rms'][0]
threshold=str(sigma*rms)+"Jy"
clean(vis=msname,imagename=junkimg,outlierfile="",field="",spw="",selectdata=True,timerange='',uvrange="",antenna="",scan="",observation="", intent="",mode="mfs",resmooth=False,gridmode="",wprojplanes=-1,facets=1,cfcache="cfcache.dir",rotpainc=5.0,painc=360.0,aterm=True,psterm=False, mterm=True,wbawp=False,conjbeams=True,epjtable="",interpolation="linear",niter=1000000000,gain=0.05,threshold=threshold,psfmode="hogbom",imagermode="",ftmachine="mosaic",mosweight=False,scaletype="SAULT",multiscale=scales,negcomponent=-1,smallscalebias=0.6, interactive=False,mask=[maskfile],nchan=-1,start=0,width=1,outframe="",veltype="radio",imsize=imsize,cell=cellsize,phasecenter="",restfreq="", stokes=final_image_poln,weighting=weighting,robust=0.0,uvtaper=False,outertaper=[],innertaper=[],modelimage='',restoringbeam=[''],pbcor=False,minpb=0.2,usescratch=False,noise="1.0Jy",npixels=0,npercycle=100,cyclefactor=5, cyclespeedup=-1, nterms=1,reffreq="",chaniter=False, flatnoise=True,allowchunk=False)
exportfits(imagename=junkimg+".image",fitsimage=fits_imagename,history=False,dropdeg=False,overwrite=True)
if selfcal_success==True:
exportfits(imagename=junkimg+".model",fitsimage=fits_modelname,history=False,dropdeg=False,overwrite=True)
os.system("rm -rf "+junkimg+".*")
rms_val=imstat(imagename=fits_imagename,box=BOX)['rms'][0]
max_val=imstat(imagename=fits_imagename)['max'][0]
dyn_range=max_val/rms_val
del max_val
del rms_val
hdu=pyfits.open(fits_imagename,mode='update')
head=hdu[0].header
head.update(key='Creators',value='Surajit Mondal, Atul Mohan and Divya Oberoi')
params,vals=np.genfromtxt('clean.last',delimiter='=',dtype=str,autostrip=True,skip_header=13,skip_footer=True,usecols=(0,1),unpack=True)
for key,value in zip(params,vals):
if value=='""':
value='NIL'
head.update(key=key[:8],value=value)
#head.update(key='Input',value=header_dict)
hdu.flush()
hdu.close()
del head
del hdu
del params
del vals
del junkimg
return round(dyn_range,2)
def count_tot_antenna_for_clean(antenna_to_use):
if '~' in antenna_to_use:
ends=np.array(antenna_to_use.split('~')).astype(int)
count=ends[1]-ends[0]+1
if ',' in antenna_to_use:
ends=antenna_to_use.split(',')
count=len(ends)
del ends
return count
def do_uvsub(msname):
print 'Doing uvsub..',msname
uvsub(vis=msname)
ms.open(msname)
ms.selectinit(datadescid=0)
data=ms.getdata('corrected_data')['corrected_data']
flag=ms.getdata('flag')['flag']
ms.close()
MAD,threshold,median=flagger(msname,data,flag)
del data
del flag
return MAD,threshold,median
def decor(msname,metafits,n_tblk,single_time): # n_tblk: Size of a read/write block: how many individual times in it
c_speed_of_light = 299792458. # m/s
#
# The sign of geometric delay term
#
tauw_sign = +1.
#tauw_sign = -1.
#
# Read the cable delays (electrical cable lengths, elen)
# from the metafits file.
#
ms_dir = msname
hl = pyfits.open(metafits)
#
# The second HDU is a fits table with 256 (nPol*nTile) rows.
# The order of the rows is a little strange, but they can be
# ordered in the same order as casa as follows:
# Find the CASA order of the tiles and elen:
#
h1 = hl[1]
tile_order = np.argsort(h1.data['Tile'])
#
# The lengths are prefixed by "EL_" which indicates that the
# lengths given (in metres) are electrical lengths.
# Cut off the 'EL_' prefixes and reorder the e-lengths:
#
tile = [til for til in h1.data['Tile'][tile_order][::2]]
tile = np.array(tile, dtype=int)
elen = [float(Len[3:]) for Len in h1.data['Length'][tile_order][::2]]
elen = np.array(elen, dtype=np.float64)
hl.close()
#raise SystemExit
sqrt_2 = np.sqrt(2.)
r2d = 180./np.pi
before = time.time()
fout = open('decor_'+msname.split('/')[-1]+'.txt', 'w')
ms.open(ms_dir, nomodify=False)
#
# Find exact number of individual times in MS
#
md = ms.metadata()
if single_time:
n_times = 1
else:
tims = md.timesforfield(0)
n_times = len(tims)
# Convert MS times from metadata to yyyymmdd hh:mm:ss
ymds = []
for tim in tims:
q = qa.quantity(tim, 's')
ymd = qa.time(q, form='ymd', prec=8) # 8 means 12:34:56.75 format
ymds.append(ymd)
cwids = md.chanwidths(0) # Hz, 64 channel widths (40000.Hz = 4 kHz)
cwid = cwids[0]
#cwid0 = 40000. # Hz, channel width (40000.Hz = 4 kHz)
IntgTime = md.exposuretime(scan=1, spwid=0, polid=0)
tintg = IntgTime['value'] # Integration time. IntgTime['unit'] = 's'
an_samp = cwid*tintg # = 20000, cplx samples in 0.5s of 40kHz channel
#an_samp = cwid0*tintg # = 20000, cplx samples in 0.5s of 40kHz channel
n_samp = int(an_samp)
ms.selectinit(datadescid=0) # Untranslatable CASA dirty swearword
if single_time:
# Select the whole MS dataset
rec = ms.getdata(['data'])
dat = np.copy(rec['data'])
ants1 = ms.getdata(['antenna1'])['antenna1']
ants2 = ms.getdata(['antenna2'])['antenna2']
tims = ms.getdata(['time'])['time']
uvw = ms.getdata(['uvw'])['uvw']
idx_ant = 999999*np.ones(512, dtype=int) # Fill with 999999 where empty
cdat = apply_acorr(dat, ants1, ants2, idx_ant, elen, tile, \
uvw, cwid, fout)
rec['data'][:,:,:] = cdat
print '%5d, time = %.2f' % (0, tims[0]) # Only one single time
#
# Put the corrected data back to the MS database
#
ms.putdata(rec)
else:
n_io = n_times//n_tblk
if n_times % n_tblk <> 0: n_io = n_io + 1
tblk = np.arange(n_io + 1)*n_tblk
tblk[-1] = n_times
for iblk in xrange(n_io):
it0 = tblk[iblk] # Block start (points at the first)
it1 = tblk[iblk+1] # Block end (points at the next after the last)
tim0 = tims[it0]
tim1 = tims[it1-1]
ms.selectinit(reset=True) # Reset the cumulative selection!!!
ms.select({'time':[tim0, tim1]})
rec = ms.getdata(['data'])
blkdat = np.copy(rec['data'])
blkants1 = ms.getdata(['antenna1'])['antenna1']
blkants2 = ms.getdata(['antenna2'])['antenna2']
blktims = ms.getdata(['time'])['time']
blkuvw = ms.getdata(['uvw'])['uvw']
blkcdat = np.zeros_like(blkdat) # Corrected data to be written to MS
#
# Start/end indices of same times into blktims[]
#
ibt = np.where(np.diff(blktims) <> 0)[0] + 1
ibt = np.hstack((0, ibt, len(blkants1)))
idx_ant = 999999*np.ones(512, dtype=int) # Fill with 999999 where empty
#raise SystemExit
#sys.exit(0)
#
# Apply amplitude corrections to the (large) piece of correlation data
# loaded to RAM. For each single time 'tim' and full set of
# baselines (ants1, ants2), a corresponding data block 'dat' is
# extracted
# from 'blkdata', corrected, and stored in 'vdat'.
#
for itim in xrange(it0,it1):
tim = tims[itim]
ibt0 = ibt[itim-it0]
ibt1 = ibt[itim-it0+1]
dat = blkdat[:,:,ibt0:ibt1]
ants1 = blkants1[ibt0:ibt1]
ants2 = blkants2[ibt0:ibt1]
uvw = blkuvw[:,ibt0:ibt1]
cdat = apply_acorr(dat, ants1, ants2, idx_ant, elen, tile, \
uvw, cwid, fout)
blkcdat[:,:,ibt0:ibt1] = cdat
tymd = qa.time(qa.quantity(tim, 's'), form='ymd', prec=8)[0]
print '%5d, time = %.2f or %s' % (itim, tim, tymd)
print 'Block %d-%d done.' % (it0,it1-1)
#
# Store the corrected correlations in the measurement set
#
rec['data'][:,:,:] = blkcdat
#
# Put the corrected data back to the MS database
#
ms.putdata(rec)
ms.close()
fout.close()
return
def error_msgs(err_code):
if err_code==1:
return "split problem"
elif err_code==2:
return "dirty image not produced"
elif err_code==3:
return "large number of flagged antennas"
elif err_code==4:
return "failed to make image in a selfcal iteration"
elif err_code==5:
return "decreasing dynamic range"
elif err_code==6:
return "no good solution found"
elif err_code==7:
return "maximum iteration exceeded."
elif err_code==8:
return "Bad choice of reference time."
else:
return "succeeded"
def extend_calibrator_flags(calibrator_cal,num_ant=128,need_both_poln=True):
bpass,flag, success = read_bandpass(calibrator_cal,num_ant)
num_chan = np.size(flag[0,:,0,0])
for ant in range(num_ant):
pos1 = np.where(flag[0,:,0,ant]==True)[0]
pos2 = np.where(flag[1,:,0,ant]==True)[0]
if ((len(pos1)>0.6*num_chan or len(pos2)>0.6*num_chan) and need_both_poln==True):
flag[:,:,0,ant]=True
elif (len(pos1)>0.6*num_chan):
flag[0,:,0,ant]=True
elif (len(pos2)>0.6*num_chan):
flag[0,:,0,ant]=True
BCAL = tb.open(calibrator_cal,nomodify=False)
flag1 = tb.getcol('FLAG') # Extract FLAG column from bandpass table
dims = np.shape(flag1)
flag = np.reshape(flag,dims)
flag1 = flag
tb.putcol('FLAG',flag1)
tb.flush()
tb.close()
del flag1
del flag
del BCAL
del bpass
del success
return
def field_of_view(freq):
FOV=np.sqrt(610)*150*10**6/freq #610 deg^2 is the image FoV at 150MHz. So extrapolating this to cntrfq
return FOV*3600 ### in arcsecs
def find_bpass(msname,spwr,UVRANGE,TIMERANGE,snr,ref_ant,APMODE):
bandpass(vis=msname,caltable=msname[:-3]+'.cal',field="",spw=spwr,intent="",selectdata=True,timerange=TIMERANGE,uvrange=UVRANGE,antenna="",\
scan="",observation="",msselect="",solint="inf",combine="scan",refant=str(ref_ant),minblperant=4,minsnr=snr,solnorm=False,bandtype="B",smodel=[],\
append=False,fillgaps=0,degamp=3,degphase=3,visnorm=False,maskcenter=0,maskedge=5,docallib=False,callib="",gaintable=[],gainfield=[],\
interp=[],spwmap=[],parang=False)
def find_phase_sol(msname,spwr,UVRANGE,TIMERANGE,snr,ref_ant,APMODE):
cb.open(msname)
cb.selectvis(chanmode='none',spw=spwr,uvrange=UVRANGE,time=TIMERANGE)
PHASE_CAL_TABLE_OUT=msname[:-3]+'.cal'
cb.setsolve(type='B',t='inf',refant=str(ref_ant),apmode=APMODE,table=PHASE_CAL_TABLE_OUT,append=False,minsnr=snr)
cb.solve()
cb.close()
def flag_antennas(msname,antenna_to_use):
if '~' in antenna_to_use:
return
antenna_used=np.array(antenna_to_use.split(',')).astype(int)
print 'Antenna used in clean: ',antenna_used
flagged_antennas=','.join(np.setdiff1d(np.arange(1,129,1),antenna_used,assume_unique=True).astype(str))
print 'Antenna to be Flagged: ',flagged_antennas
print "MS name: ",msname
if flagged_antennas!='':
flagdata(vis=msname,mode='manual',antenna=flagged_antennas)
del flagged_antennas
del antenna_used
return
def flagger(msname,data,flag):
mask_data=ma.array(np.abs(data),mask=flag)
median=ma.median(mask_data)
MAD=ma.median(np.abs(mask_data-median))
sigma=MAD*1.4826
flagdata(vis=msname,mode='clip',clipminmax=[0,median+6.5*sigma],clipoutside=True,datacolumn='corrected',flagbackup=False)
del mask_data
return MAD,median+6.5*sigma,median
def gen_time_array(starttime,ref_timeslice_done,times,ref_time,tdt,endtime): #### This function generates the indices of the times
#### which are to be imaged and also index of the
#### reference timeslice.
yrstr=str(starttime.date())
wholerng=[]
stt=starttime
DSx=[]
i=0
while stt<=endtime:
tempt=stt.time().strftime('%H:%M:%S.%f')[:-5]
stt+=tdt
wholerng+=[tempt]
DSx+=[i]
i+=1
time_DSx=dict(zip(wholerng,DSx))
if ref_timeslice_done==False:
times=[ref_time]+times
ref_time_index=time_DSx[ref_time]
timeranges=[]
for i in times:
if '~' not in i:
timeranges+=[i]
continue
ts=i.split('~')
strt=ts[0]
endt=ts[1]
stt=dt.datetime.strptime(yrstr+' '+strt,'%Y-%m-%d %H:%M:%S.%f')
endtime=dt.datetime.strptime(yrstr+' '+endt,'%Y-%m-%d %H:%M:%S.%f')
while stt<=endtime:
tmp=stt.time().strftime('%H:%M:%S.%f')[:-5]
ntmp=stt+tdt
timeranges+=[tmp] # Change the image averaging time delta here
stt+=tdt
time_beg=[time_DSx[i] for i in timeranges]
return time_beg,ref_time_index
def generate_new_bookkeeping_array():
max_pix_array=np.zeros(20)*np.nan
dyn_range_array=np.zeros(20)*np.nan
return max_pix_array,dyn_range_array
def getnearpos(array,value):
### returns index of two elements nearest to a given number #####
a = abs(array-value)
b=np.argsort(a)
del a
return b[0],b[1]
def model_phase_rms_curve(phase_rms,iteration,time):
### here I assume that the rms curve is similar for both polarisations.
### will model rms for XX only ####
num_cal_done=len(phase_rms)
start_new_cal=num_cal_done+1
time_temp=scan_timeranges(time)
filename="time_"+"_".join(time_temp.split("~")[0].split(":"))+"_self_"+str(start_new_cal)+".cal"
while (os.path.isdir(filename)):
bpass,flag,success=read_bandpass(filename,128)
pos = np.where(flag==True)[0]
bpass[pos] = np.nan
polx_data = np.angle(bpass[0,0,0,:])
phase_rms.append(nanstd(polx_data))
iteration.append(start_new_cal)
start_new_cal+=1
filename="time_"+"_".join(time_temp.split("~")[0].split(":"))+"_self_"+str(start_new_cal)+".cal"
temp=np.log10(np.array(phase_rms))
iter_temp=iteration[-np.size(iteration)/3:-5]
temp=temp[-np.size(temp)/3:-5]
if (np.size(temp)>10):
line=np.polyfit(iter_temp,temp,deg=1)
return line[0]*180/np.pi
else:
return 0
def num_pixels(FOV,cellsize):
num = FOV/cellsize
pow2 = int(np.log2(num))
possibility= np.array([2**(pow2-1)*3,2**(pow2-2)*5,2**(pow2-2)*7,2**(pow2+1)])
return possibility[getnearpos(possibility,num)[0]]
def pixelsize(freq):
psf = calc_psf(freq)
pixel = int(psf/3)
return pixel
def read_bandpass(CALTABLE,NANT):
BCAL=tb.open(CALTABLE,nomodify=True) # Open the bandpass table
bpass=tb.getcol('CPARAM') # Extract the CPARAM=GAIN column from the bandpass table
flag=tb.getcol('FLAG') # Extract FLAG column from bandpass table
snr=tb.getcol('SNR');
dims = bpass.shape
NPOL = dims[0]
NCHAN = dims[1]
NTIME = dims[2]/NANT
flag = np.reshape(flag,[NPOL,NCHAN,NTIME,NANT])
bpass= np.reshape(bpass,[NPOL,NCHAN,NTIME,NANT])
success=True
tb.close()
del BCAL
del snr
del NPOL
del NCHAN
del NTIME
return bpass,flag, success
def scan_timeranges(casa_times):
frac_sec = casa_times-int(casa_times)
time_string = time.gmtime(casa_times) #### Remember gmtime ignores fractional seconds.
time1 = str(time_string[3])+":"+str(time_string[4])+":"
if (frac_sec<0.5): #### MWA times are in .25 or in .75 seconds.
time1 = time1+str(time_string[5])+"~"+time1+str(time_string[5])+".5"
else:
time1 = time1+str(time_string[5])+".5"+"~"+time1+str(time_string[5]+1)
del frac_sec
del time_string
return time1
def sigma_in_unknown(slope):
#### calculates by how much sigma should go down in unknown ######
if slope==0:
return 0
elif slope>-0.17:
return 0
else:
return 0.2
def stop_sigma(max_pix,intelligence_file):
#### intelligence array has first element as flux and second element as sigma
intelligence_array=pickle.load(open(intelligence_file,"rb"))
intelligence_array=np.array(intelligence_array)
idx1,idx2=getnearpos(intelligence_array[:,0],max_pix)
intell_pix1=intelligence_array[idx1,0]
intell_pix2=intelligence_array[idx2,0]
intell_sig1=np.log10(intelligence_array[idx1,1])
intell_sig2=np.log10(intelligence_array[idx2,1])
sigma=intell_sig2+(intell_sig2-intell_sig1)/(intell_pix2-intell_pix1)*(max_pix-intell_pix2)
del intelligence_array
del idx1
del idx2
del intell_pix1
del intell_pix2
del intell_sig1
del intell_sig2
return max(10**sigma,1.5)
def update_bookkeeping_arrays(max_pix,dyn_range,max_pix_array,dyn_range_array):
pos=np.where(np.isnan(dyn_range_array)==True)[0]
if np.size(pos)!=0: #### that means that the book-keeping arrays are not filled
dyn_range_array[pos[0]]=dyn_range ### numpy where stores in a sequential order.
### hence using first element for updating
max_pix_array[pos[0]]=max_pix
else:
dyn_range_array[:-1]=dyn_range_array[1:]
max_pix_array[:-1]=max_pix_array[1:]
dyn_range_array[-1]=dyn_range
max_pix_array[-1]=max_pix
print '$$$$$$$$$$$$$$$$$$$$$$'
print 'Updated Dyn Range array: ',dyn_range_array[0:5]
print '$$$$$$$$$$$$$$$$$$$$$$$'
return max_pix_array,dyn_range_array
####################################################### Main Selfcal Functions #########################################################
def skip_selfcal(channel_msname,part_time,header_dict,chan,final_image_poln,modeldir='',basedir='',imagedir='',corr="XX,YY",region_file='',BOX='',cell=0,imsize=[0],scales=[-1],maskfile='',phase_snr=3,refant='1',selfcal_failed=False,continuous=True,):
print "entered skip selfcal\n"
log_file=open('CASA_imaging.txt','a')
print '#### scan_timeranges '
gen_str=scan_timeranges(part_time).split('~')[0]
#channel=channel_msname.split('~')[-1].split('.ms')[0]
channel=channel_msname.split('.ms')[0].split('_')[-1]
chan=channel
ftim=scan_timeranges(part_time).split('~')[0].split(':')
if len(ftim[-1])==1:
ftim[-1]='0'+ftim[-1]
ftim[-1]=ftim[-1]+'.0'
elif len(ftim[-1])==2 and '.' not in ftim[-1]:
ftim[-1]+='.0'
elif len(ftim[-1])==3 and '.' in ftim[-1]:
ftim[-1]='0'+ftim[-1]
if len(ftim[0])!=2:
ftim[0]='0'+ftim[0]
if len(ftim[1])!=2:
ftim[1]='0'+ftim[1]
fitstim=''.join(ftim)
time_to_image=fitstim.split('~')[0]
time_to_image_object=dt.datetime(1,1,1,int(time_to_image[0:2]),int(time_to_image[2:4]),int(time_to_image[4:6]),int(time_to_image[7])*100000) #### assume that the day is same
final_model_name=basedir+'/'+modeldir+'/'+'Sun_Clean_Matrix_'+fitstim+'_'+chan+'_full_'+final_image_poln+'_model.fits'
final_image_name=basedir+'/'+imagedir+'/'+'Sun_Clean_Matrix_'+fitstim+'_'+chan+'_full_'+final_image_poln+'.fits'
final_uvfits='Sun_Clean_Matrix_'+fitstim+'_'+chan+'_full_'+final_image_poln+'.uvfits'
relevant_files=sorted(glob.glob(basedir+'/'+modeldir+'/'+'Sun_Clean_Matrix_*'+'_'+chan+'_full_'+final_image_poln+'_model.fits'))
temp=[i.split('Sun_Clean_Matrix_')[-1].split('_')[0] for i in relevant_files]
times_done_object=[dt.datetime(1,1,1,int(i[0:2]),int(i[2:4]),int(i[4:6]),int(i[7])*100000) for i in temp]
time_diff=[i-time_to_image_object for i in times_done_object]
del times_done_object
del temp
absolute_time_diff=abs(np.array([i.days*86400+i.seconds+i.microseconds*1e-6 for i in time_diff]))
del time_diff
rel_pos1=np.argsort(absolute_time_diff)[0]
time_diff=absolute_time_diff[rel_pos1]
if time_diff>max_time_delta and selfcal_failed==False:
log_file.write(gen_str+" time difference large\n")
log_file.write(gen_str+" going for a selfcal\n")
log_file.close()
return 9
#rel_pos1,rel_pos2=getnearpos(times_done,float(fitstim))
#print rel_pos1,rel_pos2
nearest_selfcal_model=relevant_files[rel_pos1]
nearest_time=nearest_selfcal_model.split('/')[-1].split('_')[3]
nearest_caltable='caltables/caltable_'+nearest_time+'.cal'
nearest_selfcal_image=basedir+'/'+imagedir+'/'+nearest_selfcal_model.split('/')[-1].split('_model.fits')[0]+".fits"
#nearest_time_imaged=nearest_selfcal_image.split('_')[3]
filename="time_"+'_'.join((scan_timeranges(part_time).split('~')[0]).split(':'))
os.system("rm -rf "+filename+"_self_*") #### this is to delete any folder which has a name same as this
ms_out = filename+"_self_1.ms"
num_split_trials=0
ms_size=0
ms_file_made=False
while (ms_size==0 and ms_file_made==False and num_split_trials<5):
if (os.path.isdir(ms_out)):
os.system("rm -rf "+ms_out)
split(vis=channel_msname,outputvis=ms_out,keepmms=True,field="",spw="",scan="",antenna="",correlation=corr,timerange=scan_timeranges(part_time),intent="",array="",uvrange="",observation="",feed="",datacolumn="data",keepflags=True,width=1,timebin="0s",combine="")
ms_file_made=os.path.isdir(ms_out)
if ms_file_made==False:
num_split_trials+=1
continue
ms_size=os.stat(ms_out+"/table.f21_TSM0").st_size
num_split_trials+=1
if (num_split_trials==5):
#### if initial split did not work not point in continuing #####
log_file.write(gen_str+" split problem\n")
log_file.close()
return 1
log_file.write(gen_str+" Applying solutions from "+nearest_selfcal_model+"\n")
msname=ms_out
try:
os.mkdir('caltables')
except OSError:
pass
if nearest_time[-1]=='0':
timerange=nearest_time[0:2]+":"+nearest_time[2:4]+":"+nearest_time[4:]+"~"+nearest_time[0:2]+":"+nearest_time[2:4]+":"+nearest_time[4:6]+".5"
else:
timerange=nearest_time[0:2]+":"+nearest_time[2:4]+":"+nearest_time[4:]+"~"+nearest_time[0:2]+":"+nearest_time[2:4]+":"+nearest_time[4:6]+".9999"
if os.path.isdir(nearest_caltable)==False:
importfits(fitsimage=nearest_selfcal_model,imagename=nearest_selfcal_model[:-5]+".model")
ft(vis=channel_msname,model=nearest_selfcal_model[:-5]+".model",usescratch=True)
bandpass(vis=channel_msname, caltable=nearest_caltable, refant=str(refant), minsnr=phase_snr, timerange=timerange)
delmod(vis=channel_msname,scr=True)
os.system("rm -rf "+nearest_selfcal_model[:-5]+".model")
applycal(vis=msname,gaintable=nearest_caltable,interp=["nearest","nearest"],timerange=scan_timeranges(part_time))
rms=imstat(imagename=nearest_selfcal_image,region=region_file,box=BOX)["rms"][0]
log_file.write(gen_str+" rms of nearby selfcal image: "+str(rms)+"\n")
dyn_range=clean_as_necessary(want_deep,msname,final_image_poln,cell,imsize,weighting,deep_sigma,maskfile,final_image_name,final_model_name,BOX,header_dict,scales,threshold=str((deep_sigma+increase_threshold_no_selfcal)*rms)+"Jy",selfcal_success=False)
if (dyn_range<worst_DR_allowed and selfcal_failed==False):
os.system("rm -rf "+final_image_name)
log_file.write(gen_str+" DR very bad: "+str(dyn_range)+"\n")
log_file.write(gen_str+" going for a selfcal\n")
log_file.close()
return 9
exportuvfits(vis=msname,fitsfile=final_uvfits,datacolumn='corrected',overwrite=True)
os.system("rm -rf "+msname[:-2]+"ms*")
DRfil=open('Dynamic_Ranges.txt','a')
DRfil.write(fitstim+'\t'+str(dyn_range)+'\n')
DRfil.close()
log_file.write(gen_str+" DR good: "+str(dyn_range)+"\n")
log_file.close()
return 0
def do_selfcal(channel_msname,part_time,scratch=True,corr="XX,YY",ref_ant=1,max_iter=1000,num_ant=128,region_file='',BOX='',cell=0,imsize=[0],scales=[-1],maskfile='', start_sigma=10,phase_snr=3,beyond_intelligence=False,DR_delta1=20,DR_delta2=20,calc_final_sigma=True,intelligence_file='', limit_dyn=1e6, dyn_range_array=np.array([np.nan]), max_pix_array=np.array([np.nan]),bookkeeping_file='',worst_DR_allowed=100,safety_standard=0,final_sigma=10,need_uvsub=True,want_check_dyn=False,wavelength=[1.0]):
### channel_msname is the channel ms
#### returns True when selfcal ends normally
#### code donesn't go below 6 sigma by default
####dyn_range_array and max_pix_array should be supplied in second run.
####Otherwise it will assume that it is the first run.
#### scratch=True means that you want to do full selfcal. During this set ref_time_index to -1.
### anyway it will not be used if scratch=True. Otherwise it should be time_index for which you want to apply the
#### solutions.
#### bookkeeping file is the file in which we have stored the dyn_range_array and max_pix_array. if this is a blank string
####then I will assume that you have not done any imaging before for this dataset. Then I will generate a nan filled array for both
#### of these parameters and then populate them iteratively. But if you have done at least one imaging and want to use them for other
#### timeslices if possible, go ahead and give the dyn_range array. The order will be first the actual numbers and then nan. Don't put
#### nan in between numbers.
#### I am just checking here if the array is completely filled with nan or are there some actual numbers
log_file=open('CASA_imaging.txt','a')
gen_str=scan_timeranges(part_time).split('~')[0]
global in_unknown
sigma=start_sigma
if np.isnan(dyn_range_array[0]):
if bookkeeping_file=='':
max_pix_array,dyn_range_array=generate_new_bookkeeping_array()
else:
bookarray=np.loadtxt(bookkeeping_file)
max_pix_array=bookarray[:,0]
dyn_range_array=bookarray[:,1]
pos=np.where(max_pix_array<0)[0]
max_pix_array[pos]=np.nan
dyn_range_array[pos]=np.nan
del pos
del bookarray
print '####\nScratch to begin: ',scratch,'\n#######'
if (scratch==True):
end_ant = 50
else:
end_ant = 128
data_to_split='data'
#### take care that ref_time_index is non-negative when scratch=False
if (scratch==False):
available_caltables = glob.glob("time*_self_1.cal")
junk_times = np.array([float(i.split('_')[1])*60+float(i.split('_')[2])*60+float(i.split('_')[3]) for i in available_caltables])
current_time_array = np.array(scan_timeranges(part_time).split('~')[0].split(':')).astype(float)
time_difference = np.abs(junk_times-(current_time_array[0]*60+current_time_array[1]*60+current_time_array[2]))
nearest_ref_time = np.where(time_difference==np.min(time_difference))[0]
file_time = '_'.join(available_caltables[nearest_ref_time[0]].split('_')[:-1])
data_to_split = "corrected"
num_caltables=len(glob.glob(file_time+"*.cal"))
num_iteration=num_caltables
phasetable = []
timeslice=scan_timeranges(part_time)
for table_num in range(1,num_iteration):
phasetable.append(file_time+"_"+str(table_num)+".cal") #### the last caltable made is time*_self_(num_iteration).cal"
#### All caltables except the last one will be applied in calonly mode #####
#### The last one will be calflag. All we can apply these at one go on the whole dataset ####
print 'File time: ',file_time
applycal(vis=channel_msname,field="",spw="",intent="",selectdata=True,timerange=timeslice,uvrange="",antenna="",scan="",observation="",msselect="",docallib=False, callib="",gaintable=phasetable,gainfield=[],interp='nearest',spwmap=[],calwt=[True],parang=False,applymode="calonly",flagbackup=False)
phasetable=[file_time+"_"+str(num_iteration)+".cal"]
print 'Phasetable: ',phasetable
log_file.write(gen_str+' Phasetable: '+str(phasetable)+'\n')
applycal(vis=channel_msname,field="",spw="",intent="",selectdata=True,timerange=timeslice,uvrange="",antenna="",scan="",observation="",msselect="",docallib=False, callib="",gaintable=phasetable,gainfield=[],interp='nearest',spwmap=[],calwt=[True],parang=False,applymode="calflag",flagbackup=False)
filename="time_"+'_'.join((scan_timeranges(part_time).split('~')[0]).split(':'))
os.system("rm -rf "+filename+"_self_*") #### this is to delete any folder which has a name same as this
ms_out = filename+"_self_1.ms"
num_split_trials=0
ms_size=0
ms_file_made=False
while (ms_size==0 and ms_file_made==False and num_split_trials<5):
if (os.path.isdir(ms_out)):
os.system("rm -rf "+ms_out)
split(vis=channel_msname,outputvis=ms_out,keepmms=True,field="",spw="",scan="",antenna="",correlation=corr,timerange=scan_timeranges(part_time),intent="",array="",uvrange="",observation="",feed="",datacolumn=data_to_split,keepflags=True,width=1,timebin="0s",combine="")
ms_file_made=os.path.isdir(ms_out)
if ms_file_made==False:
num_split_trials+=1
continue
ms_size=os.stat(ms_out+"/table.f21_TSM0").st_size
num_split_trials+=1
if (num_split_trials==5):
#### if initial split did not work not point in continuing #####
log_file.close()
del gen_str
return 1,False,max_pix_array,dyn_range_array
msname = ms_out
del ms_out
antenna_to_use = '1~'+str(end_ant)
do_bandpass = False
taper = str(0.95*max_baseline/wavelength[0])
clean(vis=msname,imagename=msname[:-3],outlierfile="",field="",spw="",selectdata=True,timerange=scan_timeranges(part_time),uvrange="",antenna=antenna_to_use,scan="",observation="",intent="",mode="mfs",resmooth=False,gridmode="",wprojplanes=-1,facets=1,cfcache="cfcache.dir",rotpainc=5.0,painc=360.0,aterm=True,psterm=False,mterm=True,wbawp=False,conjbeams=True,epjtable="",interpolation="linear",niter=0,gain=0.05,threshold="2mJy",psfmode="hogbom",imagermode="",ftmachine="mosaic",mosweight=False,scaletype="SAULT",multiscale=[],negcomponent=-1,smallscalebias=0.6,interactive=False,mask=[maskfile],nchan=-1,start=0,width=1,outframe="",veltype="radio",imsize=imsize,cell=cell,phasecenter="",restfreq="",stokes="I",weighting="natural",robust=0.0,uvtaper=True,outertaper=[taper+'lambda', taper+'lambda', '0deg'],innertaper=['0deg','0deg','0deg'],modelimage="",restoringbeam=[''],pbcor=False,minpb=0.2,usescratch=False,noise="1.0Jy",npixels=0,npercycle=100,cyclefactor=5,cyclespeedup=-1,nterms=1,reffreq="",chaniter=False,flatnoise=True,allowchunk=False)
if os.path.isdir(msname[:-3]+".image"):
rms = imstat(imagename=msname[:-3]+".image",axes=-1,region=region_file,box=BOX,chans="",stokes="",listit=True,verbose=True,mask=[],stretch=False,logfile="",append=True,algorithm="classic",fence=-1,center="mean",lside=True,zscore=-1,maxiter=-1,clmethod="auto")["rms"][0]
else:
#### if initial clean did not work not point in continuing #####
log_file.close()
del gen_str
return 2,False,max_pix_array,dyn_range_array
max_pix = imstat(imagename=msname[:-3]+".image",axes=-1,region="",box='',chans="",stokes="",listit=True,verbose=True,mask=[],stretch=False,logfile="",append=True,algorithm="classic",fence=-1,center="mean",lside=True,zscore=-1,maxiter=-1,clmethod="auto")["max"][0]
##### Here I will check for a match with the maximum pixel in this image and those stored in the max_pix_array.
#### Unless it is empty, we can always use it. Of course it is better once we populate it fully. So first I see
#### if the first element is nan. If yes than all are nan. This also means nearest_dyn_range is defined only if
#### there is at least one element in the max_pix_array
do_full_selfcal=False
if np.isnan(max_pix_array[0])==False:
ratio=max_pix_array/max_pix
pos1=np.where(ratio>0.1)[0]
pos2=np.where(ratio<10)[0]
pos=np.intersect1d(pos1,pos2)
print 'Ratio array: ',ratio
log_file.write(gen_str+' Ratio array: '+str(ratio)+'\n')