OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
find_islands.f
Go to the documentation of this file.
1  subroutine find_islands(prod_ID,npix,west,numi,xlon,xlat,
2  * wlon,wlat,nump,nill,nilp)
3 
4  save
5  real*4 xlon(1000),xlat(1000),wlon(1000),wlat(1000)
6  real*4 nav_orb_vec(3), nav_sun_ref(3), nav_sen_mat(3,3),
7  1 nav_scan_ell(6)
8  real*4 plat(1285),plon(1285),sena(1285),senz(1285)
9  real*4 sola(1285),solz(1285)
10  real*4 b2(1285),b8(1285),b2p(1285),b82p(1285)
11  integer*2 dat(8,1285)
12  integer*4 ill(30000),ilp(2,30000),ilf(30000)
13  integer*4 jll(1000),jlp(2,1000)
14  integer*4 irec,prod_ID(2)
15  integer*4 nump(1000),nill(1000),nilp(1000)
16  byte lflag(1285,16000)
17  logical land,end,first,west
18  data b82_ice_min/20.0/
19  data b2_cloud_min/18./
20 c data b2_cloud_stray_min/25./
21 c data b82_cloud_stray_max/-13./
22  data b2_valid_min/6.0/
23  data b82_valid_min/-20.0/
24  data b82_valid_max/8.0/
25  data b82_water_max/-3.0/
26  data b82_fac/0.7/
27  data a2/0.02/,a8/0.15/,tc/1400./
28  data lp_maxg/15/,lp_maxl/40/
29  data first/.true./
30 
31  logical(4) water
32  real*8 pi,radeg,re,rem,f,omf2,omegae
33  common /gconst/pi,radeg,re,rem,f,omf2,omegae
34 
35 #include "navblk_s.fin"
36 
37  type(navblk_struct) :: navblk(16000)
38 
39  lp_max = lp_maxl
40  ip = 1
41  jp = 1
42  ipst = 147
43  ipen = 1135
44  if (npix.eq.248) then
45  lp_max = lp_maxg
46  ip = 147
47  jp = 4
48  ipst = 1
49  ipen = 248
50  end if
51 
52  tr2 = a2*exp(-prod_id(2)/tc) + (1. - a2)
53  tr8 = a8*exp(-prod_id(2)/tc) + (1. - a8)
54 
55  iline = 0
56  nsegs = 0
57  irec = 0
58  ntpix = 0
59  ncpix = 0
60  nipix = 0
61  nwpix = 0
62  nlpix = 0
63  nbpix = 0
64  numi = 0
65 
66 c First read in data and find scan line land segments using Bands 1 and 6
67  dowhile(.true.)
68  lw = -1
69  land = .false.
70  call get_l1a_record( prod_id, npix, irec, dat, nav_orb_vec,
71  1 nav_sun_ref, nav_sen_mat, nav_scan_ell, iret)
72 
73 c write(6, 500 ) iret, ((rec_arr(i,j),i=1,8 ),j=71,72),
74 c 1 (nav_orb_vec(i),i=1,3), (nav_sun_ref(i),i=1,3),
75 c 1 (nav_sen_mat(i),i=1,9), (nav_scan_ell(i),i=1,6)
76 c 500 format( ' test, read: iret = ', i7,' 8 bands for 2 pixels:',/,
77 c 1 2(8(2x,i5),/),' nav_orb_vec: ',3e12.5,/,
78 c 1 ' nav_sun_ref: ',3e12.5,/,' nav_sen_mat: ',/,
79 c 1 3(3(2x,e12.5),/),' nav_scan_ell: ',/,
80 c 1 2(3(2x,e12.5),/) )
81 
82  if (iret.ne.0) go to 990
83 
84  iline = iline + 1
85 
86 c Store navigation data
87  do i=1,3
88  navblk(iline)%orb_vec(i) = nav_orb_vec(i)
89  navblk(iline)%sun_ref(i) = nav_sun_ref(i)
90  navblk(iline)%scan_ell(i) = nav_scan_ell(i)
91  navblk(iline)%scan_ell(i+3) = nav_scan_ell(i+3)
92  navblk(iline)%sen_mat(i,1) = nav_sen_mat(i,1)
93  navblk(iline)%sen_mat(i,2) = nav_sen_mat(i,2)
94  navblk(iline)%sen_mat(i,3) = nav_sen_mat(i,3)
95  end do
96 
97 c Check if scene starts in Western hemisphere
98  if (first) then
99  first = .false.
100  west = .false.
101  ik = ip + jp*(npix-1)
102  call geonav(navblk(iline)%orb_vec,navblk(iline)%sen_mat,
103  * navblk(iline)%scan_ell,navblk(iline)%sun_ref,ik,1,1,
104  * plat,plon,solz,sola,senz,sena)
105  if (plon(1).lt.0.0) west = .true.
106  end if
107 
108 c Get solar and sensor zenith angles
109  call geonav(navblk(iline)%orb_vec,navblk(iline)%sen_mat,
110  * navblk(iline)%scan_ell,navblk(iline)%sun_ref,ip,jp,npix,
111  * plat,plon,solz,sola,senz,sena)
112 
113 c csz = cos(solz(1)/radeg)
114 
115 c Linearize counts
116  call b28_lin(dat,npix,b2,b8)
117 
118 c write (71) (b2(i),i=1,npix),(b8(i),i=1,npix)
119 
120  do i=ipst,ipen
121 
122  csz = cos(solz(i)/radeg)
123  cnz = cos(senz(i)/radeg)
124  ssz = sin(solz(i)/radeg)
125  snz = sin(senz(i)/radeg)
126  ca = cos((sena(i)-sola(i))/radeg)
127 
128  fac2 = 2./(1.+csz/cnz)
129 c fac8 = (csz*cnz + ssz*snz*ca)/csz
130  b2(i)=b2(i)/tr2
131  b8(i)=b8(i)/tr8
132  b2p(i) = b2(i)/csz
133 c b82p(i) = b8(i)*fac8-b82_fac*b2(i)*fac2
134  b82p(i) = b8(i)*fac2-b82_fac*b2(i)*fac2
135  ntpix = ntpix + 1
136 
137 c First check for invalid (corrupted) radiances
138  if ((b2p(i).lt.b2_valid_min).or.
139  * (b82p(i).lt.b82_valid_min).or.
140  * (b82p(i).gt.b82_valid_max)) then
141  land = .false.
142  lw = -1
143  lflag(i,iline) = 2
144  nbpix = nbpix + 1
145 
146 c If ice, reset flags
147 c if (b82p(i).gt.b82_ice_min) then
148 c land = .false.
149 c lw = -1
150 c lflag(i,iline) = 2
151 c nipix = nipix + 1
152 
153 c If clouds, reset flags
154  else if (b2p(i).gt.b2_cloud_min) then
155  land = .false.
156  lw = -1
157  lflag(i,iline) = 3
158  ncpix = ncpix + 1
159 
160 c Check for stray light from clouds
161 c else if ((b1p(i).gt.b1_cloud_stray_min).and.
162 c * (b61p(i).lt.b61_cloud_stray_max)) then
163 c land = .false.
164 c lw = -1
165 c lflag(i,iline) = 3
166 c ncpix = ncpix + 1
167 
168 c If water
169  else if (b82p(i).lt.b82_water_max) then
170  water = .true.
171  lflag(i,iline) = 0
172  nwpix = nwpix + 1
173 
174 c If previous pixel is land
175  if (land) then
176 
177 c If land is preceded by water within maximum number of pixels
178  if ((lw.gt.0).and.((i-lw).lt.lp_max)) then
179 c write(*,*)'Land at line, pixels',iline,lw,i
180 
181 c Store segment indices in table
182  nsegs = nsegs + 1
183  ill(nsegs) = iline
184  ilp(1,nsegs) = lw + 1
185  ilp(2,nsegs) = i - 1
186  ilf(nsegs) = 0
187  end if
188 
189  land = .false.
190  end if
191  lw = i
192 
193 c Else if land
194  else
195  land = .true.
196  lflag(i,iline) = 1
197  nlpix = nlpix + 1
198 
199  end if
200  end do
201 c write (61) (lflag(i,iline),i=1,npix)
202 c write (81) (b2p(i),i=1,npix),(b82p(i),i=1,npix)
203  end do
204  990 continue
205 
206  nipix = 100*nipix/ntpix
207  ncpix = 100*ncpix/ntpix
208  nwpix = 100*nwpix/ntpix
209  nlpix = 100*nlpix/ntpix
210  nbpix = 100*nbpix/ntpix
211 c write(*,*)'Ice pixels ',nipix,'%'
212  write(*,*)'Cloud pixels',ncpix,'%'
213  write(*,*)'Water pixels',nwpix,'%'
214  write(*,*)'Land pixels ',nlpix,'%'
215  write(*,*)'Corrupted pixels ',nbpix,'%'
216 
217  if (nsegs.lt.1) go to 998
218 
219 
220 c Now try to identify islands in land segments by
221 c chaining segments if necessary
222 
223  il = 1
224 
225 c Check if segments are in first or last scan line
226  dowhile(ill(il).lt.2)
227  il = il + 1
228  if (il.gt.nsegs) go to 998
229  end do
230 
231  dowhile(ill(nsegs).ge.iline)
232  nsegs = nsegs - 1
233  if (nsegs.lt.il) go to 998
234  end do
235 
236  dowhile(il.le.nsegs)
237 
238  js = 0
239 c Check next segment in table
240 
241  if (ilf(il).ne.0) then
242  go to 997
243  end if
244  ilf(il) = 1
245 
246 c First check previous line for land or cloud pixels
247  do j=ilp(1,il)-1,ilp(2,il)+1
248  if (lflag(j,ill(il)-1).ge.1) then
249  go to 997
250  end if
251  end do
252 
253 c Assume for the moment this is the first segment of a chain
254  i1 = il
255  jll(1) = ill(il)
256  jlp(1,1) = ilp(1,il)
257  jlp(2,1) = ilp(2,il)
258  end = .false.
259 
260 c Look for contiguous land segments
261  call find_all_segs(ill,ilp,ilf,i1,nsegs,jll(1),jlp(1,1),nj)
262 
263  if (nj.gt.1000) go to 997
264 c If contiguous segments are found then
265  if (nj.gt.1) then
266 
267 c Consolidate segment table
268  nl = 1
269  do i=2,nj
270  jl = jll(i) - jll(1) + 1
271  if (jl.gt.nl) then
272  nl = jl
273  jll(nl) = jll(i)
274  jlp(1,nl) = jlp(1,i)
275  jlp(2,nl) = jlp(2,i)
276  else
277  if (jlp(1,i).lt.jlp(1,jl)) jlp(1,jl) = jlp(1,i)
278  if (jlp(2,i).gt.jlp(2,jl)) jlp(2,jl) = jlp(2,i)
279  end if
280  end do
281 
282 c Check previous line for land or cloud pixels
283  do j=jlp(1,1)-1,jlp(2,1)+1
284  if (lflag(j,jll(1)-1).ge.1) go to 997
285  end do
286 
287 c Check for other contiguous land pixels
288  do j=1,nl-1
289  call check_segs(jll,jlp,j,j+1,lflag(1,jll(j)),
290  * lflag(1,jll(j)+1),igood)
291  if (igood.ne.0) go to 997
292  enddo
293 
294  else
295  nl = 1
296  end if
297 
298 c Check after last line for land or cloud pixels
299  do j=jlp(1,nl)-1,jlp(2,nl)+1
300  if (lflag(j,jll(nl)+1).ge.1) go to 997
301  end do
302 
303 c write(*,*)'Land segment chain'
304  numi = numi + 1
305 
306 c Compute centroid of land pixels
307  ni = 0
308  xlati = 0.0
309  xloni = 0.0
310  xlomin = 999.
311  xlomax = -999.
312  xlamin = 999.
313  xlamax = -999.
314  do i=1,nl
315 c write(*,*)jll(i),jlp(1,i),jlp(2,i)
316  k = jll(i)
317  ik = ip + jp*(jlp(1,i)-1)
318  np = jlp(2,i) - jlp(1,i) + 1
319  call geonav(navblk(k)%orb_vec,navblk(k)%sen_mat,
320  * navblk(k)%scan_ell,navblk(k)%sun_ref,ik,jp,np,
321  * plat,plon,solz,sola,senz,sena)
322  do j=1,np
323  if (lflag((j+jlp(1,i)-1),k).eq.1) then
324  xlati = xlati + plat(j)
325  if (west.and.(plon(j).lt.0.0)) plon(j) = plon(j) + 360.0
326  xloni = xloni + plon(j)
327  ni = ni + 1
328  if (plon(j).lt.xlomin) xlomin = plon(j)
329  if (plon(j).gt.xlomax) xlomax = plon(j)
330  if (plat(j).lt.xlamin) xlamin = plat(j)
331  if (plat(j).gt.xlamax) xlamax = plat(j)
332  end if
333  end do
334  end do
335  nump(numi) = ni
336  nill(numi) = jll(1)
337  nilp(numi) = jlp(1,1)
338  xlat(numi) = xlati/ni
339  xlon(numi) = xloni/ni
340  wlat(numi) = xlamax - xlamin
341  wlon(numi) = xlomax - xlomin
342  write(*,*)ni,xlat(numi),xlon(numi),wlat(numi),wlon(numi)
343  write (51,1100) ni,xlat(numi),xlon(numi),jll(1),jlp(1,1),
344  * wlat(numi),wlon(numi)
345  1100 format (i10,2f12.5,2i10,2f10.5)
346 
347  997 il = il + 1
348 
349  if (numi.ge.1000) go to 998
350 
351  end do
352 
353  998 return
354  end
subroutine find_islands(prod_ID, npix, west, numi, xlon, xlat, wlon, wlat, nump, nill, nilp)
Definition: find_islands.f:3
subroutine get_l1a_record(prod_ID, npix, irec, dat, nav_orb_vec, nav_sun_ref, nav_sen_mat, nav_scan_ell, iret)
Definition: get_l1a_record.f:3
subroutine find_all_segs(ill, ilp, ilf, ist, nsegs, jll, jlp, nj)
Definition: find_all_segs.f:2
#define real
Definition: DbAlgOcean.cpp:26
#define re
Definition: l1_czcs_hdf.c:701
subroutine check_segs(ill, ilp, i1, i2, lflag1, lflag2, igood)
Definition: check_segs.f:2
#define pi
Definition: vincenty.c:23
#define omf2
Definition: l1_czcs_hdf.c:703
subroutine b28_lin(scan, npix, b2, b8)
Definition: b28_lin.f:2
#define f
Definition: l1_czcs_hdf.c:702