Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

histogram.f

Go to the documentation of this file.
00001 
00002 c
00003 c       Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993,
00004 c       by Steve McMillan, Drexel University, Philadelphia, PA.
00005 c
00006 c       All rights reserved.
00007 c
00008 c       Redistribution and use in source and binary forms are permitted
00009 c       provided that the above copyright notice and this paragraph are
00010 c       duplicated in all such forms and that any documentation,
00011 c       advertising materials, and other materials related to such
00012 c       distribution and use acknowledge that the software was developed
00013 c       by the author named above.
00014 c
00015 c       THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
00016 c       IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
00017 c       WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00018 c
00019 
00020 c------------------------------------------------------------------------
00021 c
00022 c       Histogram-plotting routines:  histogram
00023 c                                     histo (used by histogram)
00024 c
00025 c------------------------------------------------------------------------
00026 
00027         subroutine histogram(input,istart,nin,x,y,z,nx,ny,nz,
00028      &                       iherr,ihmode,ihsave,iprompt,*)
00029         save
00030 c       
00031 c       Draw a histogram from z or y(x).
00032 c       
00033         character*(*) input
00034         dimension x(*),y(*),z(*)
00035 c       
00036         common/scales/xl,xr,dinchx,ybot,ytop,dinchy,rlen,slen
00037 c       
00038         common/draw params/roff,soff,aspect1,xlen,ylen,hs,hn,hp,
00039      &                     idevset,jbox,iorig
00040 c       
00041         common/frame params 1/xmin,xmax,ymin,ymax,modex,modey
00042         character*80 xttl,yttl
00043         common/frame params 2/xttl,yttl
00044 c       
00045         parameter (NHISTOMAX=200)
00046         dimension xh(0:NHISTOMAX),yh(0:NHISTOMAX),xp(19)
00047         logical normal
00048 c
00049         common/weights/wt(NHISTOMAX),nw
00050 c       
00051         if (input(3:3).eq.'x') then
00052 c           
00053             if (nx.le.1) go to 1001
00054 c           
00055 c           Already have the data in x, y, and the box is drawn.
00056 c           
00057             dx2 = .5*(x(2) - x(1))
00058             yh(0) = 0.
00059             xh(0) = max(xl,min(xr,x(1)-1.5*dx2))
00060             do 10180 i=1,nx
00061                 xh(i) = max(xl,min(xr,x(i)-dx2))
00062                 yh(i) = y(i)
00063 10180       continue
00064 c
00065             if (.not.normal) then
00066                 ier = 1
00067             else
00068                 ier = nz
00069             end if
00070 c
00071             call histo(xh,yh,nx+1,ihmode,ier*iherr)
00072             return
00073 c           
00074         end if
00075 c       
00076         if (nz.le.1) go to 1001
00077 c       
00078 c       Must make the histogram from scratch.
00079 c       
00080         call minmax(z,nz,z1,z2)
00081         xmin0 = z1
00082         xmax0 = z2
00083 c       
00084 c       Determine binning to use:
00085 c       
00086         if (input(3:3).ne.'2') then
00087             if (input(3:3).eq.'n'.or.input(4:4).eq.'n') then
00088                 normal = .true.
00089             else
00090                 normal = .false.
00091             end if
00092 c           
00093             ref = -1.e35
00094             io = 1
00095             call readrq(input(istart:nin),2,
00096      &                  del,ref,dum,dum,*100)
00097             io = 0
00098 c
00099 100         if (io.ne.0.or.ref.lt.-9.e34) then
00100                 read(input(istart:nin),*,err=1001,end=1001)del
00101                 ref = z1
00102             end if
00103             if (del.le.0.) go to 1001
00104 c
00105             xmin = z1
00106             xmax = z2
00107 c           
00108             if (modex.lt.0) then
00109                 if (z1.le.0..or.ref.le.0.) go to 1001
00110                 z1 = log10(z1)
00111                 z2 = log10(z2)
00112                 ref = log10(ref)
00113             end if
00114 c           
00115             iref = 0.9999*(ref-z1)/del
00116             nh = 0
00117             xh(0) = ref - (iref+1)*del
00118             iref = iref + 2
00119 c           
00120 c           Notes:  xh(i) is the TOP of bin #i.
00121 c           ref will be at the BOTTOM of bin #iref
00122 c           
00123 180         nh = nh+1
00124             if (nh.gt.NHISTOMAX) then
00125                 if (iprompt.eq.1) write(6,'(''Too many bins.'')')
00126                 go to 1001
00127             end if
00128             xh(nh) = xh(nh-1) + del
00129             if (xh(nh).le.z2) go to 180
00130         else
00131             if (del.le.0..or.nh.le.0..or.nh.gt.nhmax) go to 1001
00132         end if
00133 c       
00134 c       Bin the data.
00135 c       
00136         do 182 j=0,nh
00137             yh(j) = 0.
00138 182     continue
00139         zbar=0.
00140         var=0.
00141         do 184 i=1,nz
00142             zz = z(i)
00143             if (modex.lt.0) zz = log10(zz)
00144             zbar = zbar + z(i)
00145             var = var + z(i)**2
00146             j = iref + (zz-ref)/del
00147             j = max(1,min(nh,j))
00148             yh(j) = yh(j) + 1.
00149 184     continue
00150 c       
00151         if (normal) then
00152             do 185 j = 0,nh
00153                 yh(j) = yh(j)/nz
00154 185         continue
00155         end if
00156 c       
00157 c       Get statistics (percentiles from the binned data)...
00158 c       
00159         zbar = zbar/nz
00160         var = var/nz - zbar**2
00161 c       
00162         ix=0
00163         sum=0.
00164         do 190 ip=1,19
00165             sp = .05*ip*nz
00166             if (normal) sp = sp/nz
00167 188         ix = ix + 1
00168             if (ix.gt.nh) go to 191
00169             sum = sum + yh(ix)
00170             if (sum.lt.sp) go to 188
00171             xp(ip) = xh(ix) - del*(sum-sp)/yh(ix)
00172             sum = sum - yh(ix)
00173             ix = ix - 1
00174 190     continue
00175 c       
00176 c       ...and (clip and) draw the histogram.
00177 c       
00178 191     call minmax(yh(1),nh,y1,y2)
00179 c       
00180         if (modey.gt.0) then
00181             ymin = 0.
00182         else
00183             if (.not.normal) then
00184                 ymin = 1.
00185             else
00186                 ymin = 1./nz
00187             end if
00188             ymin1 = log10(ymin) - 10.
00189             do 192 j = 0,nh
00190                 if (yh(j).lt.ymin) then
00191                     yh(j) = ymin1
00192                 else
00193                     yh(j) = log10(max(ymin,yh(j)))
00194                 end if
00195 192         continue
00196         end if
00197 c       
00198         if (input(3:3).ne.'1'.and.input(3:3).ne.'2') then
00199 c           
00200             ymax = min(10.+y2,1.1*y2)
00201 c           
00202             delz = xp(19) - xp(1)
00203 c           
00204             if (xp(1)-z1.gt.delz) then
00205 c               
00206 c               Bottom 5% too spread out:
00207 c               
00208                 xmin = xp(19) - sqrt(delz*(xp(19)-z1))
00209                 ix = abs(xmin - ref)/del
00210                 if (xmin.lt.ref) then
00211                     xmin = ref - (ix+1)*del
00212                 else
00213                     xmin = ref + ix * del
00214                 end if
00215                 if (modex.lt.0) xmin = 10.**z1
00216             end if
00217 c           
00218             if (z2-xp(19).gt.delz) then
00219 c               
00220 c               Top 5% too spread out:
00221 c               
00222                 xmax = xp(1) + sqrt(delz*(z2-xp(1)))
00223                 ix = abs(xmax - ref)/del
00224                 if (xmax.lt.ref) then
00225                     xmax = ref - ix*del
00226                 else
00227                     xmax = ref + (ix+1) * del
00228                 end if
00229                 if (modex.lt.0) xmax = 10.**z2
00230             end if
00231 c
00232 c           Expand the range slightly (linear case only):
00233 c
00234             if (modex.gt.0) then
00235                 xav = .5*(xmin+xmax)
00236                 xmin = xmin - .1*(xav-xmin)
00237                 xmax = xmax + .1*(xav-xmin)
00238             end if
00239 c           
00240             if (idevset.eq.0) call setup(' ','histogram')
00241             call devon
00242             call clear
00243 c           
00244             if (.not.normal) then
00245                 yttl = '@H'
00246             else
00247                 yttl = ' fraction'
00248             end if
00249 c           
00250             call eframe(xmin,xmax,xlen,modex,xttl,
00251      &                  ymin,ymax,ylen,modey,yttl)
00252             ibox=1
00253 c           
00254 c           More clipping...
00255 c           
00256             do 193 j=0,nh
00257                 if (xh(j).lt.xl) xh(j)=xl
00258                 if (xh(j).gt.xr) xh(j)=xr
00259 193         continue
00260         end if
00261 c       
00262         if (.not.normal) then
00263             ier = 1
00264         else
00265             ier = nz
00266         end if
00267 c
00268         call histo(xh,yh,nh+1,ihmode,ier*iherr)
00269         call devoff
00270 c
00271         if (ihsave.ne.0) then
00272 c
00273 c           Save the histogram data (top center of each bar) in y(x).
00274 c
00275             do 200 j=2,nh
00276                 x(j-1) = .5*(xh(j-1)+xh(j))
00277                 y(j-1) = yh(j)
00278                 if (ihsave.eq.2.and.nw.gt.0) z(j-1) = wt(j)
00279 200         continue
00280             nx = nh-1
00281             ny = nx
00282         end if
00283         if (ihsave.eq.2.and.nw.gt.0) nz = nx
00284 c       
00285         if (iprompt.eq.1) then
00286             if (modex.lt.0) then
00287                 do 194 ip=1,19
00288                     xp(ip) = 10.**xp(ip)
00289 194             continue
00290             end if
00291             write(6,195)nz,xmin0,xmax0,zbar,
00292      &              sqrt(var),(xp(ip),ip=2,18,2)
00293 195         format(i6,' points: ',
00294      &              ' xmin = ',1pe10.3,',  xmax = ',e10.3/
00295      &              15x,' mean = ',e10.3,',  s.d. = ',e10.3/
00296      &              ' %tiles:',5e12.3/8x,4e12.3)
00297         end if
00298 c       
00299         return
00300 1001    return 1
00301 c       
00302         end
00303 
00304         
00305         subroutine histo(x,y,n,ihmode,iherr)
00306         save
00307 c       
00308 c       Draw y(x) as a histogram or as data points with error bars.
00309 c       
00310         dimension x(*),y(*)
00311 c
00312         common/frame params 1/xmin,xmax,ymin,ymax,modex,modey
00313         common/scales/xl,xr,dinchx,ybot,ytop,dinchy,rlen,slen
00314         common/draw params/roff,soff,aspect1,xlen,ylen,hs,hn,hp,
00315      &                     idevset,jbox,iorig
00316 c
00317         parameter (NHISTOMAX=200)
00318         common/weights/wt(NHISTOMAX),nw
00319 c       
00320         nw = 0
00321 c
00322         if (iherr.le.0) then
00323             r = (x(1)-xl)*dinchx
00324             so = 0.
00325             do 100 i=2,n
00326                 s = max(y(i)-ybot,0.)*dinchy
00327                 if (ihmode.eq.0) then
00328                     call plot(r,0.,3)
00329                 else
00330                     call plot(r,min(s,so),3)
00331                 end if
00332                 call plot(r,max(s,so),2)
00333                 call plot(r,s,3)
00334                 r = (x(i)-xl)*dinchx
00335                 call plot(r,s,2)
00336                 so = s
00337                 if (r.ge.rlen) go to 101
00338 100         continue
00339 101         if (r.lt.rlen) call plot(r,0.,2)
00340         else
00341             dx = .5*(x(3)-x(2))
00342             if (hp.le.0.) then
00343                 nn = 4
00344                 hh = .025
00345             else
00346                 nn = 10
00347                 hh = .5*hp
00348             end if
00349 c
00350             do 250 i = 2,n
00351                 if (x(i).ge.xr.or.y(i).lt.ybot) go to 250
00352                 r = (x(i)-dx-xl)*dinchx
00353                 s = (y(i)-ybot)*dinchy
00354                 call ngon(r,s,hh,nn,0.)
00355 c
00356 c               Find the actual number of points in the bin, zbin.
00357 c
00358                 zbin = y(i)
00359                 if (modey.lt.0) zbin = 10.**zbin
00360                 zbin = zbin*iherr
00361 c
00362 c               Determine the standard error.
00363 c
00364                 nw = nw + 1
00365                 wt(i-1) = sqrt(zbin)
00366 c
00367 c               (Note that wt(1) corresponds to x(2)!)
00368 c
00369                 zfac = 1./wt(i-1)
00370                 if (zbin.le.1.) zfac = .999
00371 c
00372                 if (modey.gt.0) then
00373                     su = (y(i)*(1.+zfac) - ybot)*dinchy
00374 208                 sl = (y(i)*(1.-zfac) - ybot)*dinchy
00375                 else
00376                     su = (y(i) + log10(1.+zfac) - ybot)*dinchy
00377                     sl = (y(i) + log10(1.-zfac) - ybot)*dinchy
00378                 end if
00379 c
00380 c               Plot the error bars.
00381 c
00382                 call plotin(r-hh,sl,3)
00383                 call plotin(r+hh,sl,2)
00384                 call plotin(r,sl,3)
00385                 call plotin(r,su,2)
00386                 call plotin(r-hh,su,3)
00387                 call plotin(r+hh,su,2)
00388 c
00389 250         continue
00390 c
00391         end if
00392 c       
00393         end

Generated at Sun Feb 24 09:57:04 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001