You are on page 1of 27

1

VSI PL Forum
k-Omega Beamforming Example
Randal l Judd
SSC- SD
619 553 3086
judd@spawar. navy. mil
2
VSI PL Forum
k-Omega Example
Include
Simple k-Omega beamformer
Simple data generator
A parameter file input method
Methods to output data and to create a simple image
Demonstrates
Early Binding
FFT
Random
FIR Filters
View manipulation using support functions
3
VSI PL Forum
A very brief introduction to k-Omega
beamforming

r
k =
2

( )
cos()

e
x
+sin()

e
y
( )
i = 0LNsens 1
r
r
i
= x
i

e
x
= i Dsens

e
x

p(t,
r
r ) = p
o
exp j
r
k
r
r
( )
exp j 2ft
( )
n = 0LNts 1
t
n
= n Fs
propagating wave
k
r

i
r
r
sensor
Nsens => Number of sensors
Nts => Length of time series sample
Fs => Sample rate
p
i,n
= p
o
exp jx
i
2

cos
( )





exp jt
n
2f
( )
x
e
Dsens => Sensor spacing
k => wave number
p => pressure
DISCLAIMER: This is a brief, probably not entirely
correct, beamforming explanation. For better
information see:
Array Signal Processing
Johnson & Dudgeon
ISBN 0-13-048513-6
4
VSI PL Forum
Some basics
This is an example. Some things would be done
differently in production code.
The program is built around objects with a
parameter object at the top.
In the context of this demonstration an object is
A C structure in a file called somethi ng_obj.h
A header file somethi ng.h
Some functionality in a C file called somethi ng.c
For instance the parameter object consists of
param_obj.h, param.h, and param.c
Other objects are kw (k-omega), ts (time series) ts_sim
(time series simulation) and image (scale and output a
simple image).
5
VSI PL Forum
Some more basics
I designed things so that most functions take the
parameter object as the argument.
A couple functions also take a file name argument.
Every object has an initialization and a
finalization.
This is where VSIPL objects are created and destroyed
Supports early binding
Since everything exists below the parameter object
initializing the parameter object initializes all the
objects.
The main program is called beamformer.
Program beamformer takes a file name (parameter file)
as an argument.
The included parameter file is called param_file
6
VSI PL Forum
Parameter File
*1500 c
*1024 Fs sample rate
*1024 Nts
*1.5 Dsens
*128 Nsens
*8 Data sets to average
*4 nsim_freqs
*450 hertz
*300 hertz
*150 hertz
*50 hertz
*50 degrees
*130 degrees
*130 degrees
*90 degrees
*64 Nnoise
The parameter File contains
environmental parameters,
array information, sampling
information, and data
simulation information.
Nothing about VSIPL here, just
stuff the program needs so it
can do something interesting.
7
VSI PL Forum
Beamformer
Initialize
Init?
Zero Avg
Accumulator
Get Data
k
Done?
Finalize
Output
Image
Calculate
Image
Output
k data
No
Yes
Yes
No
START END
8
VSI PL Forum
Beamformer (main)
#include<stdio . h>
#include<vsi p. h>
#include"beamformer.h
int mai n(int argc, char *argv[]){
param_obj obj;
if(argc < 2){/*complain about an error and exit */}
if(param_obj_init(&obj,argv[1])){
printf("failed to initialize\n"); ffl ush(stdout);
} el se {
int i;
kw_zero(& obj); /* zero gram */
for(i=0; i< obj.Navg; i++){
t s_si m(&obj); /*si mul ate some data */
kw(&obj); /* do the k-omega */
}
image(&obj);/*cal cul ate i mage data */
image_output("image_output",&obj);
kw_output("gram_output",&obj);
}
param_obj_fin(&obj);
return;
}
9
VSI PL Forum
Initialize and Finalize
To support early binding it is handy to use an
initialization phase which initializes VSIPL and
creates all the VSIPL objects and user memory
needed by the program.
It is required to destroy all VSIPL objects before
calling vsip_finalize. Writing a finalize function
which mirrors your initialize function helps to
ensure that everything is destroyed in the proper
order and at the proper time.
Note that it is not a mistake to destroy a NULL
VSIPL object so by careful initialization it is
possible to put in place a simple failure
mechanism which allows a proper vsip_finalize.
10
VSI PL Forum
Parameter Structure
typedef struct{
i nt init;
vsi p_scal ar_f c; /* propagation speed */
vsi p_scal ar_f Fs; /* Sampl e Rate */
vsi p_length Nts ; /*length of time series */
vsi p_scalar_f Dsens ; /* di stance between sensors */
vsi p_length Nsens; /*number of sensors */
vsi p_length Navg; /*date sets to average */
/*Data simulation */
int Nsim_freqs; /*number of tones */
float *sim_freqs; /*array of frequenci es */
float *sim_beari ngs; /* array of bearings */
int Nsim_noi se /*number of noi se di recti ons */
t s_obj ts; /*ti me seri es object */
kw_obj kw; /*k-omega object */
i mage_obj i mage; /* image object */
} param_obj;
11
VSI PL Forum
Parameter init and fin
int
param_obj_init(
param_obj *obj,
char *param_file)
{ i nt retval = 0;
/*read parameters in */
param_read(param_file,obj);
/*initialize VSIPL */
retval = vsi p_init((void*)0);
if(retval == 0){
/* vsi p_init was succesf ul l */
obj->init = 1;
retval += ts _obj_init(obj);
retval += kw_obj_init(obj);
retval += image_obj_init(obj);
} el se {/* vsi p init failed */
obj->init=0;
}
return retval;
}
voi d
param_obj_fin(param_obj *obj)
{
if(obj->init){
/*if vsi p_init was succesf ul l */
if(obj->si m_freqs != NULL)
free(obj->si m_freqs);
t s_obj_fin(obj);
kw_obj_fin(obj);
i mage_obj_fin(obj);
}
obj->init = 0; /* set the object un-init */
vsi p_finalize((void*)0);
}
12
VSI PL Forum
Basics of K-Omega Calculation
Window the data in time and space
Do a 2 D FFT
Generally the input data is real so real to complex out of
place in the time dimension and then complex to
complex in place along the space dimension.
Calculate the power
Average
13
VSI PL Forum
K-Omega Calculation
void kw( param_obj *obj)
{
kw_obj *kw = &(obj->kw);
t s_obj *ts = &(obj->ts);
/*data tapers */
vsi p_vmmul_f(kw->ts_taper,ts->m_data,VSIP_ROW,ts->m_data);
vsi p_vmmul_f(kw->array_taper,ts->m_data,VSIP_COL,ts->m_data);
/*do 2-d FFT; first in time, then in space */
vsi p_rcfftmop_f(kw->rcfftm,ts->m_data,kw->cm_freq);
vsi p_ccfftmip_f(kw->ccfftm,kw->cm_freq);
vsi p_mcmagsq_f(kw->cm_freq,kw->rm_freq); /* power */
/*Scal e for averagi ng and add to previ ous data */
vsi p_smmul_f(1.0/obj->Navg,kw->rm_freq,kw->rm_freq);
vsi p_bl ockadmi t_f(vsi p_mgetbl ock_f(kw->m_gram),VSIP_TRUE);
vsi p_madd_f(kw->rm_freq,kw->m_gram,kw->m_gram);
vsi p_bl ockrel ease_f(vsi p_mgetbl ock_f(kw->m_gram),VSIP_TRUE);
return;
}
14
VSI PL Forum
K-Omega Structure
typedef struct{
vsi p_length Nfreq; /* Nts /2 + 1 */
vsi p_cmvi ew_f *cm_freq; /* (Nsens , Nfreq) col maj */
vsi p_mvi ew_f *rm_freq; /*(Nsens , Nts ) rwo maj */

vsi p_scalar_f *data_gram; /*si ze Nsens * Nfreq */
vsi p_mvi ew_f *m_gram; /* (Nsens , Nfreq) col maj */
vsi p_fftm_f *rcfftm; /* by row Nsens by Nts */
vsi p_fftm_f *ccfftm; /*by col Nsens by Nfreq */
vsi p_vvi ew_f *ts_taper; /* of length Nts */
vsi p_vvi ew_f *array_taper; /* of length Nsens */
} kw_obj;
15
VSI PL Forum
Initialization of a Block and Its Views
Create Block
NULL?
Set all Views of
Block to NULL
Set Failure
Flag
Create View
NULL?
Set Failure
Flag
Done?
ENTER
EXIT
You want to ensure all
views are either NULL
or valid.
If you find a failure flag
when you are done then
it is safe to finalize.
Yes
Yes
Yes
No
No
No
16
VSI PL Forum
K-Omega initialize
int
kw_obj_init(param_obj *obj)
{
kw_obj *kw = &(obj->kw);
int retval = 0;
vsip_length Nsens = obj->Nsens;
vsip_length Nts = obj->Nts ;
vsip_length Nfreq;
if(obj->Nts %2){
printf("data length must be even");
retval++;
}
kw->Nfreq =Nts /2 + 1;
Nfreq = kw->Nfreq;
kw->cm_freq = vsip_cmcreate_f(Nsens,Nfreq,VSIP_COL, VSIP_MEM_NONE);
if(kw->cm_freq == NULL){
retval++;
}else {
kw->rm_freq = vsip_mrealview_f(kw->cm_freq);
if(kw->rm_freq == NULL) retval++;
}
17
VSI PL Forum
K-Omega initialize (cont)
{ /*create data space and block for gram */
vsip_block_f *block;
vsip_length L = Nsens * Nfreq;
kw->data_gram = (vsip_scalar_f*)malloc( L * sizeof(vsip_scalar_f));
if(kw->data_gram == NULL) retval++;
block = vsip_blockbind_f(kw->data_gram,L,VSIP_MEM_NONE);
if(block != NULL){
kw->m_gram = vsip_mbind_f(block,0,1,Nsens, Nsens, Nfreq);
if(kw->m_gram == NULL){ retval++;
vsip_blockdestroy_f(block); /*On failure clean up the block since it is local */
}
} else { retval++;
kw->m_gram = NULL;
}
}
kw->rcfftm = vsip_rcfftmop_create_f(Nsens,Nts ,1,VSIP_ROW,0,0);
if(kw->rcfftm == NULL) retval++;
kw->ccfftm = vsip_ccfftmip_create_f(Nsens,Nfreq,VSIP_FFT_FWD,1, VSIP_COL,0,0);
if(kw->ccfftm == NULL) retval++;
kw->ts_taper =vsip_vcreate_hanning_f(Nts,0);
if(kw->ts_taper == NULL) retval++;
kw->array_taper = vsip_vcreate_hanning_f(Nsens,0);
if(kw->array_taper == NULL) retval++;
return retval;
}
18
VSI PL Forum
K-Omega finalize
voi d
kw_obj_fin( param_obj *obj)
{
kw_obj *kw = &(obj->kw);
vsi p_mal l destroy_f(kw->m_gram);
if(kw->data_gram != NULL) free(kw->data_gram);
vsi p_fftm_destroy_f(kw->rcfftm);
vsi p_fftm_destroy_f(kw->ccfftm);
vsi p_val l destroy_f(kw->ts_taper);
vsi p_val l destroy_f(kw->array_taper);
vsi p_mdestroy_f(kw->rm_freq);
vsi p_cmal l destroy_f(kw->cm_freq);
return;
}
19
VSI PL Forum
K-Omega Zero & Output
voi d
kw_zero(param_obj *obj){
kw_obj *kw = &(obj->kw);
vsi p_bl ockadmi t_f(vsi p_mgetbl ock_f(kw->m_gram),VSIP_FALSE);
vsi p_mfill_f(0.0,kw->m_gram);
vsi p_bl ockrel ease_f(vsi p_mgetbl ock_f(kw->m_gram),VSIP_TRUE);
}
voi d
kw_output( /*output gram to a file */
char *output,
param_obj *obj){
F ILE *fptr = fopen(output,"w");
fwrite(obj->kw.data_gram,obj->Nsens * obj->kw.Nfreq,
si zeof(vsi p_scalar_f), fptr );
f cl ose(fptr );
}
20
VSI PL Forum
Final Output
( )

cos
60
120
21
VSI PL Forum
So whats next?
That concludes the basics of the example.
In the remaining time we will touch on some
additional information by looking at some of the
code not covered yet. In particular we will look at:
Some details of admit and release.
User written support functions.
Talk about
Random number generation
FIR Filter functionality.
And other things, feel free to ask Questions?
22
VSI PL Forum
Admit and Release
Doing I/O from the library involves allocating user
memory, associating the memory with a block,
and admitting and releasing the block from
VSIPL.
The TASP VSIPL implementation is very forgiving
of admit release errors. Other implementations
may not be.
So lets look at the image.c code to examine a
characteristics of admit release that may not be
well understood.
23
VSI PL Forum
The library Owns the user data
when the block is admitted
In image.c we have the code
vsi p_bl ockadmi t_f(vsi p_mgetbl ock_f(m_gram),VSIP_TRUE);
vsi p_mcopy_f_f(m_gram, mi nput);
vsi p_bl ockrel ease_f(vsi p_mgetbl ock_f(m_gram),VSIP_TRUE);
Even though we dont do anything to the data during
the copy to ensure that user data associated with
m_gram remains the same we must release with a
VSIP_TRUE flag.
Use VSIP_F AL S E only if plan to overwrite the data and
really dont care what it is.
24
VSI PL Forum
Dont Reassign User Data Pointers
Release functions return a convenience pointer to the
user data array.
Store it in a new pointer created for that purpose. Dont
reassign the original user data array pointer.
Note that VSIPL does not assign new memory for user data.
The pointer returned is the one initially bound.
Reassigning the pointer risks loosing a pointer to allocated
memory from the heap and serves no purpose.
For complex block release you must supply pointers to
two data array pointers even if the user data is
interleaved. In the interleaved case the second pointer
will be returned pointing to NULL.
{
vsip_scalar_f *ptr1,*ptr2;
vsip_cbl ockrel ease_f(block,VSIP_TRUE,&ptr1,&ptr2)
}
25
VSI PL Forum
Data Simulation
The data is created in a simple simulator.
First zero the data array
Fill the data array with directional noise
VSIPL random functionality is used to produce some
random noise.
The noise is low pass filtered.
A simple time delay mechanism is used to simulate noise
from many directions (defined in the parameter file).
We need this step to give the k-omega its characteristic
cone shape.
Simulate narrow band data and add it to the noise data
for some defined set of frequencies and directions.
26
VSI PL Forum
Plotting The Output
A simple Matlab script called plt.m is included for
plotting the output of the K-omega.
An image routine is included which outputs a
simple unsigned char bitmap for use in some
other plotting packages.
A simple script for the open source GRI plotting
package is included to convert the image bitmap to a
postscript output.
GRI is available for many platforms. It resides at
gri.sourceforge.net
A simple routine to convert the image bitmap to
PNG format is available but not included.
It needs two libraries libgd.a and libpng.a
27
VSI PL Forum
Finish
I plan to make and run the example.
Plot the output.
Answer any remaining Questions.

You might also like