OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
etbpsub.f
Go to the documentation of this file.
1 C
2 C@***s* PROJECT_PFSST/l2gen_both/etbpsub.f
3 C
4 C This header contains documentation required by the NOAA Climate Data Record
5 C Program (CDRP), which is managed at the NOAA National Climatic Data Center (NCDC).
6 C Only the code that applies to AVHRR SST data is documented in this header.
7 C
8 C The AVHRR Pathfinder Sea Surface Temperature (PFSST) processing code was originally
9 C developed at the University of Miami. In 2010, the code was integrated into
10 C the multi-sensor SeaWiFS Data Analysis System (SeaDAS) obtained from NASA GSFC.
11 C SeaDAS was used for processing the PFSST beginning with the Pathfinder Version
12 C 5.2 (PFV5.2) dataset, produced jointly by the University of Miami and the NOAA
13 C National Oceanographic Data Center (NODC). These data are provided to the
14 C public and archived at NODC, and have been transitioned along with the production
15 C code and documentation to the CDRP at NCDC.
16 C
17 C This NOAA required header is specifically written for Pathfinder SST and may
18 C not be relevant to other sensors or products processed by SeaDAS. Please
19 C review the SEADAS software distribution policy for public domain software
20 C located at http://seadas.gsfc.nasa.gov/copying.html for more information and
21 C documentation
22 C
23 C NAME
24 C etbsub.f
25 C
26 C LOCATION
27 C $OCSSWROOT
28 C
29 C PURPOSE
30 C etbsub.f contains a collection of functions and subroutines
31 C relating to emissivity and temperature conversions, and calibration
32 C of both infrared and visible AVHRR channels.
33 C
34 C DESCRIPTION
35 C
36 C ETINVERT(ICH,RADI) - Convert radiance to temperature
37 C ETINTEGRATE(ICH,ETEMP) - Convert temperature to radiance
38 C ETLOADRESP(LIN,CAL) - Initialize temperature conversion routines,
39 C load and normalize sensor response factors
40 C ETGETRSP(LIN,ICHN,NPTS,RESP,NU0,DELNU,IOS)-Get infrared channel response
41 C ETGETVIS(LIN,CAL,SLOPE,INTCP,IOS)- Get visible channel calibration
42 C
43 C see additional details in file
44 C
45 C
46 C
47 C NOAA PFSST-SEADAS BUILD VERSION
48 C Pathfinder SST V5.2 code built with SEADAS version 6.3 64 bit l2gen_both for
49 C CDR processed at University of Miami/RSMAS
50 C http://seadas.gsfc.nasa.gov/seadas/doc/l2gen/l2gen.html
51 C
52 C PRIMARY SEADAS CODE DOCUMENTATION NASA
53 C For complete documentation of multi sensor SEADAS code see
54 C http://seadas.gsfc.nasa.gov/seadas/doc/toplevel/sds_program.html
55 C
56 C AUTHOR
57 C
58 C
59 C PFSST project embedded code
60 C Susan Walsh
61 C University of Miami/RSMAS
62 C
63 C CREATION DATE
64 C 2010
65 C
66 C COPYRIGHT
67 C THIS SOFTWARE AND ITS DOCUMENTATION ARE CONSIDERED TO BE IN THE PUBLIC DOMAIN AND
68 C THUS ARE AVAILABLE FOR UNRESTRICTED PUBLIC USE. THEY ARE FURNISHED "AS IS." THE
69 C AUTHORS, THE UNITED STATES GOVERNMENT, ITS INSTRUMENTALITIES, OFFICERS, EMPLOYEES,
70 C AND AGENTS MAKE NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE USEFULNESS OF THE
71 C SOFTWARE AND DOCUMENTATION FOR ANY PURPOSE. THEY ASSUME NO RESPONSIBILITY (1) FOR
72 C THE USE OF THE SOFTWARE AND DOCUMENTATION; OR (2) TO PROVIDE TECHNICAL SUPPORT
73 C TO USERS.
74 C
75 C MODIFICATION HISTORY
76 C
77 C See CVS revision control history embedded in actual file.
78 C
79 C
80 C LANGUAGE
81 C Fortran
82 C
83 C*****
84 C########################################################
85 C
86 C !F90
87 C
88 C !Description:
89 C etbsub routine contains a collection of functions and subroutines
90 C relating to emissivity and temperature conversions, and calibration
91 C of both infrared and visible channels.
92 C
93 C Subroutines and Functions:
94 C function ETINVERT(ICH,RADI)
95 C !Description:
96 C Convert radiance to temperature
97 C !Input Parameters:
98 C ICHI(integer) - infrared channel number
99 C RADI(single) - radiance
100 C !Output Parameters:
101 C None
102 C !Return(single)- temperature
103 C
104 C function ETINTEGRATE(ICH,ETEMP)
105 C !Description:
106 C Convert temperature to radiance
107 C !Input Parameters:
108 C ICH(integer) - Infrared channel number
109 C ETEMP(single) - emissivity temperature
110 C !Output Parameters:
111 C None
112 C !Return(single) - radiance
113 C
114 C subroutine ETLOADRESP(LIN,CAL)
115 C !Description:
116 C Initialize temperature conversion routines,
117 C load and normalize sensor response factors
118 C !Input Parameters:
119 C LIN(integer) - logical unit of input file
120 C CAL(char,12) - name satellite specific sensor calibration file
121 C !Output Parameters:
122 C
123 C subroutine ETGETRSP(LIN,ICHN,NPTS,RESP,NU0,DELNU,IOS)
124 C !Description:
125 C Get infrared channel response
126 C !Input Parameters:
127 C LIN(integer) - logical unit for file access
128 C ICHN(integer) - infrared channel
129 C !Output Parameters:
130 C NPTS(integer) - number of points in the response vector
131 C RESP(single array size, MAX_RSP) - response factor for channel
132 C NU0(single) - base wave number
133 C DELNU(double) - delta wavenumber
134 C IOS(integer) - status error code
135 C
136 C
137 C subroutine ETGETVIS(LIN,CAL,SLOPE,INTCP,IOS)
138 C !Description:
139 C Get visible channel calibration
140 C !Input Parameters:
141 C LIN(integer) - logical unit for input file
142 C CAL(char,12) - name of satellite specific sensor calibration file
143 C !Output Parameters:
144 C SLOPE(single array size, 2) - calibration slope
145 C INTCP(single array size, 2) - calibration intercept
146 C IOS(integer) - error code
147 C !Revision History:
148 C
149 C
150 C !Team-Unique Header:
151 C
152 C Copyright 1988-2000 by Rosenstiel School of Marine and Atmospheric Science,
153 C University of Miami, Miami, Florida.
154 C
155 C All Rights Reserved
156 C
157 C Permission to use, copy, modify, and distribute this software and its
158 C documentation for non-commercial purposes and without fee is hereby granted,
159 C provided that the above copyright notice appear in all copies and that both
160 C that copyright notice and this permission notice appear in supporting
161 C documentation, and that the names of University of Miami and/or RSMAS not be
162 C used in advertising or publicity pertaining to distribution of the software
163 C without specific, written prior permission.
164 C
165 C UNIVERSITY OF MIAMI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
166 C INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
167 
168 C SHALL UNIVERSITY OF MIAMI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
169 C DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
170 C WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
171 C OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
172 C
173 C !References and Credits:
174 C Written BY:
175 C University Of Miami
176 C Rosenstiel School for Marine and Atmospheric Science
177 C Division of Meteorology and Physical Oceanography
178 C 4600 Rickenbacker CSWY
179 C Miami, Florida
180 C 33149
181 C Contact:SWalsh@rsmas.miami.edu
182 C
183 C !Design Notes:
184 C
185 C !End###################################################################
186 
187  function etinvert(ich,radi)
188  implicit none
189 
190  integer*4 ich;
191  real*4 etinvert;
192  real*4 radi;
193 
194  real*4 gues;
195  real*4 etintegrate;
196  real*4 step;
197  real*4 temp;
198  real*4 tnew, radg;
199 
200  if (ich < 3 .or. ich > 5) then
201  write(*,*)
202  . '-E- : ETINVERT: ICH must be [3,5]. Is ', ich
203  call exit(1)
204  end if
205 
206  if (radi <= 0.) then
207  etinvert=(100.) ! Bad input value
208  return
209  end if
210 
211  step = 10.;
212  temp = 280.;
213  radg = etintegrate(ich,temp);
214  if (radg > radi) then
215  step = -step;
216  end if
217 
218  do while (abs(radi-radg)/abs(radi+radg) >= 1e-5)
219  gues = etintegrate(ich,temp+step);
220  if (radg >= radi .and. gues <= radi) then
221  tnew = temp+step*abs(radi-radg)/abs(radg-gues)
222  temp = tnew;
223  radg = etintegrate(ich,temp);
224  step = step/10.;
225 
226  else if (radg <= radi .and. gues >= radi) then
227  tnew = temp+step*abs(radi-radg)/abs(radg-gues)
228  temp = tnew;
229  radg = etintegrate(ich,temp);
230  step = step/10.;
231 
232  else
233  temp = temp+step;
234  radg = gues;
235  end if
236 
237  if (temp < 100.) then
238 C write(*, *)'ETINVERT: ',RADI,RADG,TEMP,STEP
239  etinvert=(100.); ! Too small, quit now
240  return
241 
242  else if (temp > 375.) then
243 C write(*, *)'ETINVERT: ',RADI,RADG,TEMP,STEP
244  etinvert=(375.); ! Too large, quit now
245  return
246  end if
247 
248  if (radg < radi) then
249  step = abs(step);
250  else
251  step = -abs(step);
252  end if
253 
254  end do
255 
256  etinvert=(temp);
257  return
258 
259  end
260 
261 
262  function etintegrate(ich,etemp)
263  implicit none
264 
265 
266 C size of sensor response table
267  integer, parameter :: MAX_RSP = 250
268 
269  integer*4 ich;
270  real*4 etintegrate;
271  real*4 etemp;
272 
273  integer*4 npts(3:5)
274  integer*4 jj, ierr;
275  real*4 nu0(3:5);
276  real*8 delnu(3:5);
277  real*4 resp(max_rsp,3:5);
278  common /resp/ npts, nu0, delnu, resp;
279 
280  real*4 temp;
281  real*4 y(max_rsp);
282  real*4 simpsn, energy;
283  real*4 v;
284  real*8 c1,c2,nu,lam,t,w
285  real*8 tt,nnu
286 
287 C data C1/3.74125d-9/
288 C data C2/14.380d-4/
289 
290  data c1 /1.1910659d-5/
291  data c2 /1.438833d0/
292 
293 C The function
294 C (units are: milliWatts per sq meter sterradian inverse-cm)
295 
296 C Large T
297  w(tt,nnu) = (c1*nnu*nnu*nnu)/((exp(c2*nnu/tt)-1.d0))
298 C Small T
299  v(tt,nnu)=sngl((c1*nnu*nnu*nnu*exp(-c2*nnu/tt))/
300  . (1.d0-(exp(-c2*nnu/tt))))
301 
302  if (ich < 3 .or. ich > 5) then
303  write(*,*)
304  . '-E- : ETINTEGRATE: ICH must be [3,5]. Is ', ich
305  call exit(1)
306  end if
307 
308  if (npts(ich) > max_rsp) then
309  write(*,*) '-E- : ETINTEGRATE: NPTS > MAX_RSP'
310  call exit(1)
311 
312  else if (npts(ich) <= 0) then
313  write(*,*) '-E- : ETINTEGEMIS: NPTS <= 0'
314  call exit(1)
315  end if
316 
317  temp = etemp;
318  if (temp < 100.) then
319 C write(*,*)'ETINTEGRATE: ',ICH,TEMP
320  temp = 100.;
321 
322  else if (temp > 375.) then
323 C write(*,*) 'ETINTEGRATE: ',ICH,TEMP
324  temp = 375.;
325  end if
326 
327  if (nu0(ich) > 100.) then
328  nu = dble(nu0(ich)); ! From left to right
329  if (c2*nu/dble(temp) > 20.0d0) then
330  do jj=1,npts(ich)
331 
332  y(jj) = v(dble(temp),nu) * resp(jj,ich);
333  nu = nu + delnu(ich);
334  end do
335 
336  else
337  do jj=1,npts(ich)
338 
339  y(jj) = sngl(w(dble(temp),nu)) * resp(jj,ich);
340  nu = nu + delnu(ich);
341  end do
342 
343  end if
344 
345  else
346  lam = dble(nu0(ich)); ! From left to right
347  nu = 10000.0d0/lam;
348  if (c2*nu/dble(temp) > 20.0d0) then
349  do jj=1,npts(ich)
350 
351  nu = 10000.0d0/lam;
352  y(jj) = v(dble(temp),nu) * resp(jj,ich);
353  lam = lam + delnu(ich);
354  end do
355 
356  else
357  do jj=1,npts(ich)
358 
359  nu = 10000.0d0/lam;
360  y(jj) = sngl(w(dble(temp),nu)) * resp(jj,ich);
361  lam = lam + delnu(ich);
362  end do
363 
364  end if
365 
366  end if
367 
368 C Integrate over this interval [NU0,NUN] or [LAM0,LAMN]
369 
370  energy = simpsn(sngl(delnu(ich)),y,npts(ich),ierr);
371  if (ierr .ne. 0) then
372  write(*,*) '-E- : SIMPSN: Integration error..'
373  call exit(1)
374  end if
375 
376  etintegrate=(energy);
377  return
378 
379  end
380 
381  subroutine etloadresp(lin, cal)
382  implicit none
383 
384 C size of sensor response table
385  integer, parameter :: MAX_RSP = 250
386 
387  integer*4 lin
388  character cal*12;
389 
390  integer*4 npts(3:5)
391  real*4 nu0(3:5);
392  real*8 delnu(3:5);
393  real*4 resp(max_rsp,3:5);
394  common /resp/ npts, nu0, delnu, resp;
395 
396  logical loaded;
397  character filepath*255;
398  integer*4 ii, jj, ios, ier;
399  integer*4 lenstr;
400  integer*4 trname
401  integer slen, flen
402  real*4 factor;
403  real*4 simpsn;
404  character filedir*255
405 
406  data loaded /.false./;
407 
408  ! Read in response function
409 
410  if (loaded) then
411  return
412 
413  end if
414 
415  call getenv('OCDATAROOT', filedir)
416  flen = lenstr(filedir)
417  if (flen .eq. 0) then
418  write(*,*)
419  . '-E- ETLOADRESP:Environment variable OCDATAROOT undefined'
420  call exit(1)
421  end if
422 
423  slen = lenstr(cal)
424  filepath = filedir(1:flen)//'/avhrr/cal/'//cal(1:slen)//'.cal'
425  write(*,*) 'Loading '//filepath(1:lenstr(filepath))
426  open(unit=lin,file=filepath, status='OLD');
427  do ii=3,5
428 
429  call etgetrsp(lin,ii,npts(ii),resp(1,ii),nu0(ii),
430  . delnu(ii),ios);
431  if (ios .ne. 0) then
432  call exit(1);
433  end if
434 
435  ! Calculate normalizing factor re-scale response function
436 
437  factor = simpsn(sngl(delnu(ii)),resp(1,ii),npts(ii),ier);
438  if (ier .ne. 0) then
439  write(*,*) '-E- : SIMPSN: Normalizing factor.'
440  call exit(1);
441  end if
442 
443  ! Re-scale response function
444 
445  do jj=1,npts(ii)
446 
447  resp(jj,ii) = resp(jj,ii) / factor;
448  end do
449 
450  end do
451 
452  close(unit=lin);
453 
454  loaded = .true.;
455 
456  end
457 
458  subroutine etgetrsp(lin,ichn,npts,resp,nu0,delnu,ios)
459  implicit none
460 
461 
462 C size of sensor response table
463  integer, parameter :: MAX_RSP = 250
464 
465  integer*4 lin
466  integer*4 ichn
467  integer*4 npts
468  integer*4 ios
469  real*4 resp(max_rsp)
470  real*4 nu0
471  real*8 delnu
472 
473  character*(128) name
474  integer*4 iostat;
475  integer*4 ftrim;
476  integer*4 ln, ic, i;
477 
478 C Find appropriate channel
479 
480  rewind lin;
481  do while (.true.)
482  read(lin, '(a)', end=1044) name
483  ln = ftrim(name, 128);
484  if (ln .eq. 0) then
485  cycle
486 
487  else if (name(1:3) == "CHN") then
488  read(name(1:5), 44, iostat=iostat) ic
489 44 format(3x,i2)
490  if (ic .eq. ichn) then
491 C# write(0, *)'Found response data for channel ',ic
492  exit
493 
494  end if
495 
496  end if
497 
498  end do
499 
500 C Input NU range
501 
502 C write(0, 51) (NAME(I:I),I=1,LN)
503 C 51 format('Decoding: ',80a1)
504  read(name(1:ln), 45, iostat=iostat) nu0, delnu, npts
505  if (npts > max_rsp) then
506  write(*,*)
507  . '-E- : ETGETRSP: Too many points required (',npts,
508  . '), maximum is ', max_rsp
509  call exit(1)
510  end if
511 
512 C Input response function
513 
514  read(lin, '(x)') ! Skip a line
515  read(lin,47) (resp(i),i=1,npts)
516  ios = 0;
517  return
518 
519 C No such channel
520 
521 1044 continue
522  write(*,*) '-E- : ETGETRSP: No such channel = ',ichn
523  ios = -26
524  return
525 
526 45 format(11x,f14.0,4x,f10.0,5x,i3)
527 47 format(5(e11.5,4x))
528 
529  end
530 
531 
532  subroutine etgetvis(lin,cal,slope,intcp,ios)
533  implicit none
534 
535  integer*4 lin;
536  character cal*12;
537  real*4 slope(2), intcp(2);
538  integer*4 ios;
539 
540  character*(128) name;
541  character filepath*255;
542  character filedir*255;
543  integer*4 ic;
544  integer*4 ftrim;
545  integer*4 lenstr;
546  integer*4 trname
547  integer*4 ln;
548  integer slen, flen;
549 
550 C Find appropriate channel
551 
552  call getenv('OCDATAROOT', filedir)
553  flen = lenstr(filedir)
554  if (flen .eq. 0) then
555  write(*,*)
556  . '-E- : ETGETVIS: Environment variable OCDATAROOT undefined'
557  call exit(1)
558  end if
559 
560  slen = lenstr(cal)
561  filepath = filedir(1:flen)//'/avhrr/cal/'//cal(1:slen)//'.cal'
562  write(*,*) 'Loading '//filepath(1:lenstr(filepath))
563  open(unit=lin,file=filepath, status='OLD');
564  do while (.true.)
565  read(lin, '(a)',end=1044) name
566  ln = ftrim(name, 128);
567  if (ln .eq. 0) then
568  cycle;
569  else if (name(1:8) == "VISIBLE") then
570 C# write(0, *)'Found visible calibration data';
571  exit;
572  end if
573 
574  end do
575 
576 C Input space radiance data
577 
578 C write(0, 51) (NAME(I:I),I=1,LN)
579 C 51 format('Decoding: ',80a1)
580  ios = 0;
581  read(lin,42);
582  read(lin,42);
583  read(lin,42);
584 42 format()
585  read(lin,43) ic,slope(1),intcp(1);
586  if (ic .ne. 1) then
587  write(*,*)
588  . '-E- : ETGETVIS: Invalid visible entry for channel 1'
589  ios = -1;
590  go to 1043;
591  end if
592 
593  read(lin,43) ic,slope(2),intcp(2);
594 43 format(i3,2f16.0)
595  if (ic .ne. 2) then
596  write(*,*)
597  . '-E- : ETGETVIS: Invalid visible entry for channel 2'
598  ios = -2;
599  go to 1043;
600  end if
601 
602 1043 continue
603  close(unit=lin);
604  return
605 
606 C No such channel
607 
608 1044 continue
609  write(*,*) '"Visible calibration data not found!'
610  ios = -26;
611  close(unit=lin);
612  return
613 
614  end
#define real
Definition: DbAlgOcean.cpp:26
real function simpsn(X, Y, NUM, IER)
Definition: simpsn.f:199
subroutine tt(NMAX, NCHECK)
Definition: ampld.lp.f:1852
#define abs(a)
Definition: misc.h:90