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

Home » Public Forums » archive » How to create a 2D mask that automatically half’s an irregularly shaped 2D array from top to bottom?
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Return to the default flat view Create a new topic Submit Reply
Re: How to create a 2D mask that automatically half’s an irregularly shaped 2D array from top to bottom? [message #78637 is a reply to message #78472] Sat, 03 December 2011 22:15 Go to previous message
Jeremy Bailin is currently offline  Jeremy Bailin
Messages: 618
Registered: April 2008
Senior Member
> When you say the output is a little strange, what exactly does the input
> mask do? My solution assumes that each row has only one string of 1s in
> it - if it has more, then it won't break up each individual string, but
> will just cut out the last half of them.... a correct solution would
> require some fancy footwork with label_region.

Here's a solution that should work for any arbitrary mask. I'm sure it's
not as fast as the original, but it should be pretty efficient... there
is a for loop, but it is at most a loop through the columns rather than
the rows (and depending on the mask, could be much shorter).

For reference, it's inspired by part of JD's double-histogram solution
to the chunk indexing problem, although it doesn't actually use a double
histogram.


masksize = size(inmask, /dimen)

; expand the mask with a column of 0s on each side
; so that shift will not cycle 1s around
mask_expand = bytarr(masksize[0]+2, masksize[1])
mask_expand[1:masksize[0],*] = inmask

; find the left and right ends of each string of 1s
; by checking to see if it changes when shifted left
; or right by one column
leftends = where(mask_expand and not shift(mask_expand,1), nstring)
rightends = where(mask_expand and not shift(mask_expand,-1))
; find the midpoints by averaging
midpts = rebin([[leftends],[rightends]], nstring)
; and how long is each string?
lengths = midpts - leftends + 1

; clear mask_expand so we can fill it up again
mask_expand[*] = 0

; histogram the lengths so we can loop through them and use
; reverse indices to know which string has which length
hlen = histogram(lengths, min=1, reverse_indices=lenri)

; single indices are easy
if hlen[0] gt 0 then mask_expand[leftends[lenri[lenri[0]:lenri[1]-1]]]=1

; loop through length counts
for j=1, n_elements(hlen)-1 do if hlen[j] gt 0 then begin
; which ones have this length?
vec_inds = lenri[lenri[j]:lenri[j+1]-1]
; make a 2D array of numbers starting at each left end of this length
; and incrementing along the second dimension. This array contains
; all of the indices into mask_expand that we want to set
vec_inds = rebin(leftends[vec_inds], hlen[j], j+1, /sample) + $
rebin(lindgen(1,j+1), hlen[j], j+1, /sample)
; and set them
mask_expand[vec_inds] = 1
endif

; finally get rid of those extra columns of 0s we added at the beginning
outmask = temporary(mask_expand[1:masksize[0],*])


-Jeremy.
[Message index]
 
Read Message
Read Message
Read Message
Previous Topic: Re: Pointers and Structures and Loops - oh my!
Next Topic: Fast computation of pairwise array element differences

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

Current Time: Fri Oct 10 14:19:31 PDT 2025

Total time taken to generate the page: 0.31637 seconds