Re: Help with Histogram... [message #45738 is a reply to message #45734] |
Wed, 28 September 2005 05:34   |
btt
Messages: 345 Registered: December 2000
|
Senior Member |
|
|
MA wrote:
> Sorry, some people here are surely starting to get sick of Histogram by
> now...
> I've been reading the tutorial a couple of times in the last few weeks,
> and I've actually managed to get rid of a lot of unneccessary loops and
> stuff. I have a problem here, and I'm almost sure there must be a way
> to do it with histogram, but can't figure out how.
> I have an (as yet empty) array (profile=IntArr(60)), each index
> corresponding to a height level (e.g. surface to 20km, unevenly
> spaced), and two arrays (base, top, each FltArr(8)) containing the
> height of eight cloud bases and cloud tops. I want to set the value of
> the levels in 'profile' that fall between a cloud base and a cloud top
> (i.e. are "inside" a cloud) with a 1. Here's an attempt at an
> illustration:
>
> profile value of
> levels profile
> .
> .
> .
> - 0
> - 0
> - ------ top[1]=8000m 1
> - 1
> - 1
> - ------base[1]=7300m 1
> - 0
> - 0
> - 0
> - ------top[0]=500m 1
> - 1
> - ------base[0]=370m 1
> - 0
> - 0
> ------------------------------
> /////////surface/////////////////
>
> How can I do that without looping? If I could specify the histogram
> bins by hand, I'd set them to the cloud base and top levels, and let
> histogram sort 'profile' into those bin. At fist I thought the keyword
> 'Locations' would let me do that, but I guess I got that wrong.
> The only thing I can think of is something along the lines of
>
> index=Where((profile GE base[0] AND profile LE top[0]) OR $
> (profile GE base[1] AND profile LE top[1]) OR $
> ...
> (profile GE base[7] AND profile LE top[7]))
> profile[index]=1
>
> Any ideas? As an aside, I got a couple of thousand profiles like that,
> and 'profile' is really an array of (number_of_profiles x 60). If
> there's any way to do this problem without looping over the individual
> profiles, that would be even better.
>
> Thanks!
>
Hi,
Would the follwoing work? It mixes the base and top values - then
searched for each level within using VALUE_LOCATE. A binary flag is
used to mark the 0/1 of the profile. I think it should be pretty fast.
Cheers,
ben
****START
PRO cloudlevel
n = 8
top = findgen(n) * 100.0 + 30.0
base = top - 28.0
all = [base, top]
s= SORT(all)
all = all[s]
bProfile = BytArr(n*2)
bProfile[0:*:2] = 1B
nLevel = 10
Level = findgen(nLevel)/(nLevel-1) * (MAX(top)-1)
index = VALUE_LOCATE(all, level)
iProfile = bProfile[index]
plot, top, psym = 6, /noclip
oplot, base, psym = 5, /noclip
for i = 0, nLevel-1 Do Plots, [0,8], [level[i], level[i]], linestyle =
2, thick = 2
for i = 0, nLevel-1 Do XYOUTS, 7.5, level[i] + 10, STRTRIM(i,2), /DATA
for i = 0, nLevel-1 Do $
if iProfile[i] EQ 1 Then XYOUTS, 7.6, level[i]+10, '*' , /DATA
end
***FINI
|
|
|