comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: Matching Lats and Lons from two arrays
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: Matching Lats and Lons from two arrays [message #62126] Wed, 27 August 2008 05:49 Go to next message
Jeremy Bailin is currently offline  Jeremy Bailin
Messages: 618
Registered: April 2008
Senior Member
On Aug 26, 11:47 am, wilsona <awils...@bigred.unl.edu> wrote:
> I have 2 seperate arrays of Latittudes and Longitudes.
> CS_LATLON(0,4607) is one latitude array and dlat(192,139) is the
> other
> CS_LATLON(1,4607) is one longitude array and dlon(192,139) is the
> other.
> I want to index through each element in both CS_LATLON arrays and
> find
> which point(s) in the dlat and dlong arrays are closest.
> I tried using nested loops but that gave me 12 million+ loops which
> is
> too many for my liking.  I now am trying search2d
> NUM_PNTS  = N_ELEMENTS(CS_LATLON(0, *)) - 1
>
>   FOR J = 0, NUM_PNTS DO BEGIN
>       CLOSE_LATS = SEARCH2D(dlat, 0, 0, CS_LATLON(0,J),
> CS_LATLON(0,J), INCREASE=0.5,    $
>                             DECREASE=0.5)
>       lat1   = CS_LATLON(0,J) * PI / 180.0
>       FOR K = 0, CLOSE_LATS DO BEGIN
>               lat2   = dlat(K) * PI / 180.0
>               d_long = CS_LATLON(1,J) - dlon(K)) * PI / 180.0
>               DISTANCE   = 10800.0 / PI * acos(sin(lat1) * sin(lat2)
> +
> cos(lat1) *       $
>                                      cos(lat2) * cos(d_long))
>        ENDFOR ; K
>   ENDFOR ; J
> This is not working they way I would like.  Any suggestions on this
> would be greatly appreciated.

You might find WITHINSPHRAD in JBIU useful:

http://astroconst.org/jbiu/jbiu-doc/astro/withinsphrad.html

-Jeremy.
Re: Matching Lats and Lons from two arrays [message #62129 is a reply to message #62126] Tue, 26 August 2008 22:52 Go to previous messageGo to next message
Gaurav is currently offline  Gaurav
Messages: 50
Registered: January 2007
Member
Forgive my trespass but why is nobody suggesting the use of the
DISTANCE_MEASURE or MAP_2POINTS functions of IDL? Or is the problem
only with the length of the loop?

Or did I not get the problem right?

Gaurav
Re: Matching Lats and Lons from two arrays [message #62136 is a reply to message #62129] Tue, 26 August 2008 15:46 Go to previous messageGo to next message
Brian Larsen is currently offline  Brian Larsen
Messages: 270
Registered: June 2006
Senior Member
Paolo,

thanks you were spot on. That bought me another x10 speed improvemnt
in that routine.

Thanks,

Brian

------------------------------------------------------------ --------------
Brian Larsen
Boston University
Center for Space Physics
http://people.bu.edu/balarsen/Home/IDL
Re: Matching Lats and Lons from two arrays [message #62139 is a reply to message #62136] Tue, 26 August 2008 12:15 Go to previous messageGo to next message
wilsona is currently offline  wilsona
Messages: 2
Registered: August 2008
Junior Member
Thanks for the responses! Very appreciated
Re: Matching Lats and Lons from two arrays [message #62140 is a reply to message #62139] Tue, 26 August 2008 11:42 Go to previous messageGo to next message
Conor is currently offline  Conor
Messages: 138
Registered: February 2007
Senior Member
On Aug 26, 2:41 pm, Conor <cmanc...@gmail.com> wrote:
> On Aug 26, 11:47 am, wilsona <awils...@bigred.unl.edu> wrote:
>
>
>
>> I have 2 seperate arrays of Latittudes and Longitudes.
>> CS_LATLON(0,4607) is one latitude array and dlat(192,139) is the
>> other
>> CS_LATLON(1,4607) is one longitude array and dlon(192,139) is the
>> other.
>> I want to index through each element in both CS_LATLON arrays and
>> find
>> which point(s) in the dlat and dlong arrays are closest.
>> I tried using nested loops but that gave me 12 million+ loops which
>> is
>> too many for my liking. I now am trying search2d
>> NUM_PNTS = N_ELEMENTS(CS_LATLON(0, *)) - 1
>
>> FOR J = 0, NUM_PNTS DO BEGIN
>> CLOSE_LATS = SEARCH2D(dlat, 0, 0, CS_LATLON(0,J),
>> CS_LATLON(0,J), INCREASE=0.5, $
>> DECREASE=0.5)
>> lat1 = CS_LATLON(0,J) * PI / 180.0
>> FOR K = 0, CLOSE_LATS DO BEGIN
>> lat2 = dlat(K) * PI / 180.0
>> d_long = CS_LATLON(1,J) - dlon(K)) * PI / 180.0
>> DISTANCE = 10800.0 / PI * acos(sin(lat1) * sin(lat2)
>> +
>> cos(lat1) * $
>> cos(lat2) * cos(d_long))
>> ENDFOR ; K
>> ENDFOR ; J
>> This is not working they way I would like. Any suggestions on this
>> would be greatly appreciated.
>
> I often have to match up two star fields, which is pretty much the
> same thing. You can download the routine I use here:
>
> astro.ufl.edu/~cmancone/pros/qfind.pro
>
> Here's the source. It basically just uses histogram to bin everyhing
> and then searches one bin left and right:
>
> function qfind,x1,y1,x2,y2,posshift=posshift
>
> if n_elements(posshift) eq 0 then posshift = 1
>
> n1 = n_elements(x1)
> n2 = n_elements(x2)
>
> ; this is where I'll store the result
> res = lonarr(2,n1)
>
> ; this mask list will tell us if an entry is from list one or list two
> allinds = lindgen(n2)
>
> ; the histogram will tell us how many stars left and right we have to
> check
> hist = histogram(x2,binsize=posshift,omin=minx,reverse_indices=ri)
>
> ; calculate which bin each x went into
> bins = floor((x1-minx)/posshift)>0
> nbins=n_elements(hist)
>
> f = 0L
> for i=0L,n1-1 do begin
> ; figure out which bin this star is in
> bin = bins[i]
>
> ; adjust the indexes accordingly
> inds = ri[ri[(bin-1)>0]:ri[((bin+2)<nbins)]-1]
>
> ; calculate the distance from this star to its neighbors
> dist = sqrt( (x2[inds]-x1[i])^2 + (y2[inds]-y1[i])^2 )
>
> ; get the closest star within posshift that is from the second list
> mindist = min( dist, wm )
>
> ; no stars found
> if mindist gt posshift then continue
>
> ; record result
> res[*,f] = [i,inds[wm]]
> ++f
> endfor
>
> if f eq 0 then return,-1
>
> ; get rid of any blank entries
> res = res[*,0:f-1]
>
> return,res
>
> end

I asked this same question before. You might find the discussion
useful.

http://groups.google.com/group/comp.lang.idl-pvwave/browse_t hread/thread/629cbb2a852c5371/b568d74f6d539b79?hl=en&lnk =gst&q=That+works+well+enough%2C+but+is+certainly+not+op timal.++It+uses+the#b568d74f6d539b79
Re: Matching Lats and Lons from two arrays [message #62141 is a reply to message #62140] Tue, 26 August 2008 11:41 Go to previous messageGo to next message
Conor is currently offline  Conor
Messages: 138
Registered: February 2007
Senior Member
On Aug 26, 11:47 am, wilsona <awils...@bigred.unl.edu> wrote:
> I have 2 seperate arrays of Latittudes and Longitudes.
> CS_LATLON(0,4607) is one latitude array and dlat(192,139) is the
> other
> CS_LATLON(1,4607) is one longitude array and dlon(192,139) is the
> other.
> I want to index through each element in both CS_LATLON arrays and
> find
> which point(s) in the dlat and dlong arrays are closest.
> I tried using nested loops but that gave me 12 million+ loops which
> is
> too many for my liking. I now am trying search2d
> NUM_PNTS = N_ELEMENTS(CS_LATLON(0, *)) - 1
>
> FOR J = 0, NUM_PNTS DO BEGIN
> CLOSE_LATS = SEARCH2D(dlat, 0, 0, CS_LATLON(0,J),
> CS_LATLON(0,J), INCREASE=0.5, $
> DECREASE=0.5)
> lat1 = CS_LATLON(0,J) * PI / 180.0
> FOR K = 0, CLOSE_LATS DO BEGIN
> lat2 = dlat(K) * PI / 180.0
> d_long = CS_LATLON(1,J) - dlon(K)) * PI / 180.0
> DISTANCE = 10800.0 / PI * acos(sin(lat1) * sin(lat2)
> +
> cos(lat1) * $
> cos(lat2) * cos(d_long))
> ENDFOR ; K
> ENDFOR ; J
> This is not working they way I would like. Any suggestions on this
> would be greatly appreciated.

I often have to match up two star fields, which is pretty much the
same thing. You can download the routine I use here:

astro.ufl.edu/~cmancone/pros/qfind.pro

Here's the source. It basically just uses histogram to bin everyhing
and then searches one bin left and right:

function qfind,x1,y1,x2,y2,posshift=posshift

if n_elements(posshift) eq 0 then posshift = 1

n1 = n_elements(x1)
n2 = n_elements(x2)

; this is where I'll store the result
res = lonarr(2,n1)

; this mask list will tell us if an entry is from list one or list two
allinds = lindgen(n2)

; the histogram will tell us how many stars left and right we have to
check
hist = histogram(x2,binsize=posshift,omin=minx,reverse_indices=ri)

; calculate which bin each x went into
bins = floor((x1-minx)/posshift)>0
nbins=n_elements(hist)

f = 0L
for i=0L,n1-1 do begin
; figure out which bin this star is in
bin = bins[i]

; adjust the indexes accordingly
inds = ri[ri[(bin-1)>0]:ri[((bin+2)<nbins)]-1]

; calculate the distance from this star to its neighbors
dist = sqrt( (x2[inds]-x1[i])^2 + (y2[inds]-y1[i])^2 )

; get the closest star within posshift that is from the second list
mindist = min( dist, wm )

; no stars found
if mindist gt posshift then continue

; record result
res[*,f] = [i,inds[wm]]
++f
endfor

if f eq 0 then return,-1

; get rid of any blank entries
res = res[*,0:f-1]


return,res

end
Re: Matching Lats and Lons from two arrays [message #62142 is a reply to message #62141] Tue, 26 August 2008 10:54 Go to previous messageGo to next message
pgrigis is currently offline  pgrigis
Messages: 436
Registered: September 2007
Senior Member
Jean H wrote:
> pgrigis@gmail.com wrote:
>> Would something like this work for sorted x (plus some fix for first
>> and last element)?
>> There's going to be an overhead for sorting x if not already sorted
>> however.
>>
>> x=[3,3.5,4,6.5,7]
>> y=[3.4, 3.0, 6.8, 6.3]
>>
>> a=value_locate(x,y)
>> result=a+( (y-x[a]) GT (x[a+1]-y))
>> print,result
>>
>>
>> Ciao,
>> Paolo
>
> this would work if you only have 1 coordinate (latitude), not with 2
> (lat,long)...
> Jean

Yes, this is not going to help the original poster.
But I think Brian's routine below is 1-dimensional.

Ciao,
Paolo


>
>>
>> Brian Larsen wrote:
>>> I have tried this on several occasions (for a little different
>>> application but I think its the same) and have had no luck eliminating
>>> the for loop, so I just wrote it in a function to hide it from
>>> myself. This is my try at this based on value locate:
>>> http://people.bu.edu/balarsen/Home/IDL/Entries/2008/1/7_roun d2array_(updated_7Jan2008).html
>>>
>>> If others know how to eliminate the for loop that would be fantastic.
>>>
>>>
>>> Cheers,
>>>
>>> Brian
>>>
>>> ------------------------------------------------------------ --------------
>>> Brian Larsen
>>> Boston University
>>> Center for Space Physics
>>> http://people.bu.edu/balarsen/Home/IDL
Re: Matching Lats and Lons from two arrays [message #62143 is a reply to message #62142] Tue, 26 August 2008 10:29 Go to previous messageGo to next message
Juggernaut is currently offline  Juggernaut
Messages: 83
Registered: June 2008
Member
On Aug 26, 1:07 pm, Jean H <jghas...@DELTHIS.ucalgary.ANDTHIS.ca>
wrote:
> pgri...@gmail.com wrote:
>> Would something like this work for sorted x (plus some fix for first
>> and last element)?
>> There's going to be an overhead for sorting x if not already sorted
>> however.
>
>> x=[3,3.5,4,6.5,7]
>> y=[3.4, 3.0, 6.8, 6.3]
>
>> a=value_locate(x,y)
>> result=a+( (y-x[a]) GT (x[a+1]-y))
>> print,result
>
>> Ciao,
>> Paolo
>
> this would work if you only have 1 coordinate (latitude), not with 2
> (lat,long)...
> Jean
>
>
>
>> Brian Larsen wrote:
>>> I have tried this on several occasions (for a little different
>>> application but I think its the same) and have had no luck eliminating
>>> the for loop, so I just wrote it in a function to hide it from
>>> myself.  This is my try at this based on value locate:
>>> http://people.bu.edu/balarsen/Home/IDL/Entries/2008/1/7_roun d2array_(...
>
>>> If others know how to eliminate the for loop that would be fantastic.
>
>>> Cheers,
>
>>> Brian
>
>>> ------------------------------------------------------------ --------------
>>> Brian Larsen
>>> Boston University
>>> Center for Space Physics
>>> http://people.bu.edu/balarsen/Home/IDL

You could just do them simultaneously and only take the intersection
of the values....
for i = 0, ncols-1 do begin
x2 = rebin(reform(dlat[i,*],nrows),nrows,nels)
x3 = rebin(reform(CS_LATLON,1,nels), nrows,nels)
indices = where(abs(x3-x2) LT 1e-4)
vals = x2[indices]
x2 = rebin(reform(dlon[i,*],nrows),nrows,nels)
x3 = rebin(reform(CS_LATLON,1,nels), nrows,nels)
indices2 = where(abs(x3-x2) LT 1e-4)
vals = x2[indices2]
intersecting = setintersection(indices,indices2)
endfor

Couldn't you?
Re: Matching Lats and Lons from two arrays [message #62144 is a reply to message #62143] Tue, 26 August 2008 10:07 Go to previous messageGo to next message
Jean H. is currently offline  Jean H.
Messages: 472
Registered: July 2006
Senior Member
pgrigis@gmail.com wrote:
> Would something like this work for sorted x (plus some fix for first
> and last element)?
> There's going to be an overhead for sorting x if not already sorted
> however.
>
> x=[3,3.5,4,6.5,7]
> y=[3.4, 3.0, 6.8, 6.3]
>
> a=value_locate(x,y)
> result=a+( (y-x[a]) GT (x[a+1]-y))
> print,result
>
>
> Ciao,
> Paolo

this would work if you only have 1 coordinate (latitude), not with 2
(lat,long)...
Jean

>
> Brian Larsen wrote:
>> I have tried this on several occasions (for a little different
>> application but I think its the same) and have had no luck eliminating
>> the for loop, so I just wrote it in a function to hide it from
>> myself. This is my try at this based on value locate:
>> http://people.bu.edu/balarsen/Home/IDL/Entries/2008/1/7_roun d2array_(updated_7Jan2008).html
>>
>> If others know how to eliminate the for loop that would be fantastic.
>>
>>
>> Cheers,
>>
>> Brian
>>
>> ------------------------------------------------------------ --------------
>> Brian Larsen
>> Boston University
>> Center for Space Physics
>> http://people.bu.edu/balarsen/Home/IDL
Re: Matching Lats and Lons from two arrays [message #62145 is a reply to message #62144] Tue, 26 August 2008 09:58 Go to previous messageGo to next message
Juggernaut is currently offline  Juggernaut
Messages: 83
Registered: June 2008
Member
On Aug 26, 12:11 pm, Brian Larsen <balar...@gmail.com> wrote:
> I have tried this on several occasions (for a little different
> application but I think its the same) and have had no luck eliminating
> the for loop, so I just wrote it in a function to hide it from
> myself.  This is my try at this based on value locate:http://people.bu.edu/balarsen/Home/IDL/Entries/2008/1 /7_round2array_(...
>
> If others know how to eliminate the for loop that would be fantastic.
>
> Cheers,
>
> Brian
>
> ------------------------------------------------------------ --------------
> Brian Larsen
> Boston University
> Center for Space Physicshttp://people.bu.edu/balarsen/Home/IDL

Not sure if the following is what you're looking for but first off you
have in your one line
FOR K = 0, CLOSE_LATS DO BEGIN
which doesn't make sense based upon what search2d returns (an array)
maybe it was really n_elements(CLOSE_LATS)?...I don't know
But maybe the following will lead you to the promise land or far far
away from it

Well I'd say if you're dlat(192,139) means that you have 139 lats for
each of the 192 columns then you could do something like
CS_LATLON(0,4607)
dlat(192,139)
x2 = rebin(reform(dlat[0,*],139),139,4607)
x3 = rebin(reform(CS_LATLON,1,4607), 139,4607)
indices = where(abs(x3-x2) LT 1e-4)
x2[indices] gives the matching lats to within 1e-4
In the end something like
ncols = n_elements(dlat[*,0])
nrows = n_elements(dlat[0,*])
nels = n_elements(CS_LATLON)
for i = 0, ncols-1 do begin
x2 = rebin(reform(dlat[i,*],nrows),nrows,nels)
x3 = rebin(reform(CS_LATLON,1,nels), nrows,nels)
indices = where(abs(x3-x2) LT 1e-4)
vals = x2[indices]
;- Now you can print these vals or store them to an array or
whatever
endfor
Just repeat for the lons...still has for loops but I'm pretty sure
that works. I did a simple test on a 5x5 compared to a 1x25.
If it doesn't....I never did this.
Hope this helps eliminate some loops anyway....and actually is
relevant.
Re: Matching Lats and Lons from two arrays [message #62147 is a reply to message #62145] Tue, 26 August 2008 09:50 Go to previous messageGo to next message
pgrigis is currently offline  pgrigis
Messages: 436
Registered: September 2007
Senior Member
Would something like this work for sorted x (plus some fix for first
and last element)?
There's going to be an overhead for sorting x if not already sorted
however.

x=[3,3.5,4,6.5,7]
y=[3.4, 3.0, 6.8, 6.3]

a=value_locate(x,y)
result=a+( (y-x[a]) GT (x[a+1]-y))
print,result


Ciao,
Paolo

Brian Larsen wrote:
> I have tried this on several occasions (for a little different
> application but I think its the same) and have had no luck eliminating
> the for loop, so I just wrote it in a function to hide it from
> myself. This is my try at this based on value locate:
> http://people.bu.edu/balarsen/Home/IDL/Entries/2008/1/7_roun d2array_(updated_7Jan2008).html
>
> If others know how to eliminate the for loop that would be fantastic.
>
>
> Cheers,
>
> Brian
>
> ------------------------------------------------------------ --------------
> Brian Larsen
> Boston University
> Center for Space Physics
> http://people.bu.edu/balarsen/Home/IDL
Re: Matching Lats and Lons from two arrays [message #62148 is a reply to message #62147] Tue, 26 August 2008 09:11 Go to previous messageGo to next message
Brian Larsen is currently offline  Brian Larsen
Messages: 270
Registered: June 2006
Senior Member
I have tried this on several occasions (for a little different
application but I think its the same) and have had no luck eliminating
the for loop, so I just wrote it in a function to hide it from
myself. This is my try at this based on value locate:
http://people.bu.edu/balarsen/Home/IDL/Entries/2008/1/7_roun d2array_(updated_7Jan2008).html

If others know how to eliminate the for loop that would be fantastic.


Cheers,

Brian

------------------------------------------------------------ --------------
Brian Larsen
Boston University
Center for Space Physics
http://people.bu.edu/balarsen/Home/IDL
Re: Matching Lats and Lons from two arrays [message #62419 is a reply to message #62136] Fri, 05 September 2008 15:53 Go to previous message
JD Smith is currently offline  JD Smith
Messages: 850
Registered: December 1999
Senior Member
I should point out that the MATCH_2D routine mentioned in the above
thread and at:

http://www.dfanning.com/code_tips/matchlists.html

assumes euclidean distance measures apply, which of course is *not*
strictly correct on a sphere. For points of latitude and longitude
(or ra/dec), this will work for small patches of earth (or sky), but
if you are near either pole, or cover appreciable areas, the 2D
distance measure will falter.

You can "fake" a "pretty good" euclidean distance measure by pre-
multiplying all longitudes by the cos of latitude. This works if the
latitude range is not overly large, and if you don't cross any poles.
Do do this correctly would require replacing the d=dx^2 + dy^2 with:

d = 2 asin( sqrt( sin(ddec/2)^2 + cos(dec1)cos(dec2)sin(dra/2)^2 ) )

which is obviously much costlier to evaluate. More importantly,
you'll need to think a bit about whether the stock "platte carre"
projection (i.e. (ra, dec) -> (x,y)) is wasteful or not for your
distribution of points on the sphere, or adversely affects your
matching radius criterion. Adopting another projection prior to
binning and running the histogram might offer gains in efficiency and
more "uniform" distance performance (the issue being that square bins
in a projected sphere do not have constant area). It should be
straightforward to "wrap-around" the poles.

JD
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Re: Get rid of unwanted lines.
Next Topic: map plotting

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 13:45:50 PDT 2025

Total time taken to generate the page: 0.00754 seconds