tau2pl-r_user_lib.fil
nr_stc=64;
% Channel one
channel=1;
type=1;
vec_len=64;
data_start=0;
max_lag=2;
end_type
type=1;
% We will do 32 subcycles
vec_len=64;
data_start=0;
max_lag=29;
code_len=16;
res_mult=32;
sub_int=2;
n_frac=3;
ac_file=tau2pl.ac;
end_type
type=1;
vec_len=64;
max_lag=0;
data_start=64;
end_type
type=6;
vec_len=128;
data_start=0;
nr_rep=896;
send_raw=1;
user_lib_name=tau2pl;
user_subr_name=tau2pl_zero_lag;
nr_out_points=128;
% Number of integers in parameter file
dpar_len=2;
% Number of float in parameter file
fpar_len=3;
par_file=tau2pl_par.txt;
end_type
end_chan
% Channel two
% Gain channel
channel=2;
type=1;
vec_len=256;
max_lag=2;
data_start=0;
end_type
type=1;
vec_len=64;
max_lag=0;
data_start=256;
end_type
type=5;
vec_len=256;
fft_len=256;
nr_rep=896;
data_start=0;
end_type
end_chan
tau2pl_par.txt
% Number of cycles 64*14=896 which will be par[0]
896
% Number of data points in each cycle
128
% Now the floats are defined
% Note the integer values comes first in the parameter file
% and after these the floating point values must come
% In this example these coming floating point values are just dummies
% and not used insid our lib.
123.123
234.234
345.345
tau2pl.c
#include
#include
#include types.h>
typedef struct
{
float re;
float im;
} DSPCMPLX;
* To use int16_t sys/types.h is necessey to include for Linux */
typedef struct
{
int16_t re;
int16_t im;
} DSPCMPLXSHORT;
/* dbits Number of integer parameters in dpar
* dpar Vector with user supplied integer parameters
* fbits Number of float parameters in fpar
* fpar Vector with user supplied float parameters
* in In data vector (16 bit + 16 bit signed integers)
* out Out data vector (32 bit + 32 bit floats) will be stored in mat. file
* upar user parameters vector setable from eros like "upar 1 10" (20 double values)
*/
int
tau2pl_zero_lag (unsigned long dbits,
int *dpar, unsigned long fbits, float *fpar, DSPCMPLXSHORT * in,
DSPCMPLX * out, double *upar)
{
/* upar is a value which can be set and read from eros directly
for example "upar 1 10" will set upar 1 to the value of 10
these values are double note if you wnat to use them inside you lib
upar 1 is upar[0] in you lib max 20 values */
int nr_loops, nr_samp, i, j;
nr_loops = dpar[0];
nr_samp = dpar[1];
/* Clear the output vector if this is not done we will continue to
* integrate until decodump is stopped */
bzero (out, sizeof (DSPCMPLX) * nr_samp);
/* Just print out the floating point values */
printf ("fpar0 %f fpar1 %f and fpar2 %f\n",
fpar[0], fpar[1], fpar[2]);
for (i = 0; i < nr_loops; i++)
{
for (j = 0; j < nr_samp; j++) { /* Cast the input values to floats before calculations * as thses are 16 bit signed integers */ (out + j)->re +=
(float) ((in + i * nr_samp + j)->re) * (float) ((in +
i * nr_samp +
j)->re) +
(float) ((in + i * nr_samp + j)->im) * (float) ((in +
i * nr_samp +
j)->im);
}
}
return 0;
}
Makefile
OS_ARCH = $(subst /,_,$(shell uname -s))
OS_RELEASE = $(shell uname -r)
ifeq ($(OS_ARCH),SunOS)
ifneq (,$(filter 4.1.3_U1,$(OS_RELEASE)))
ARCH = sunos
else
ARCH = solaris
CC = cc -xCC -G -xO5 -fast -v
endif
endif
ifeq ($(OS_ARCH),Linux)
ARCH = linux
CC = cc -Wall -g -O4 -shared
endif
tau2pl: tau2pl.c
$(CC) tau2pl.c -o tau2pl.so
arc_dlayer_int_ht-v.fil
% A special version where will use the type=6 to do data integration
% of the time sliced data just for quick look purposes
nr_stc=1;
% Channel two
% Calibration channel
channel=2;
type=1;
vec_len=90;
sub_vec_len=45;
sub_data_start=45;
nr_loops=64;
max_lag=0;
data_start=0;
send_raw=1;
res_save=1;
nr_rep=10;
end_type
% Background channel
type=1;
vec_len=90;
sub_vec_len=45;
nr_loops=64;
max_lag=0;
data_start=0;
send_raw=1;
res_use=1;
nr_rep=10;
end_type
end_chan
% Channel one
channel=1;
%% D layer power profile
type=1;
% We will do 128 subcycles
vec_len=330;
sub_vec_len=330;
nr_loops=128;
max_lag=0;
data_start=0;
send_raw=1;
res_save=1;
nr_rep=10;
res_mult=10;
end_type
%% Dlayer long lags with higher frequency resoulution
type=4;
% We will do 128 subcycles
vec_len=330;
sub_vec_len=330;
nr_loops=128;
% Each subcycle will have 64 baud code
fir_len=64;
fir_file=code1.txt;
data_start=0;
% Do 127 lags 1.56 ms apart
max_lag=33909; % Number of lags will be max_lag/lag_incr
lag_incr=267; % lag_incr is sub_vec_len-fir_len+1
send_raw=1;
res_use=1;
nr_rep=10;
res_mult=10;
end_type
%% Short lags for the E region
type=4;
% We will do 128 subcycles
vec_len=330;
sub_vec_len=330;
nr_loops=128;
% Each subcycle will have 16 baud code
fir_len=16;
fir_file=code3.txt;
nr_fir_passes=4;
data_start=0;
% Do 3 lags 32 us apart
max_lag=801; % Number of lags will be (max_lag/lag_incr)
lag_incr=267; % lag_incr is sub_vec_len-fir_len+1-(fir_passes-1)*code_len
send_raw=1;
res_use=1;
nr_rep=10;
res_mult=10;
end_type
%% Dlayer long lags with higher frequency resoulution
type=0;
% We will do 128 subcycles
vec_len=330;
sub_vec_len=330;
nr_loops=128;
sub_int=128;
% Each subcycle will have 64 baud code
fir_len=64;
fir_file=code1.txt;
data_start=0;
send_raw=1;
res_use=1;
nr_rep=10;
res_mult=10;
end_type
end_chan
% We will not read any data from channel board 3 (vec_len=0), just "go back" in
% output data vector and integrate times slices
% So this channel can be seen as a place holder for integration of data taken
% on channel 1
channel=3;
% Integrate undecoded power profile slices
type=6;
vec_len=0;
data_start=0;
nr_rep=10;
send_raw=1;
user_lib_name=arc_dlayer_ht;
user_subr_name=int_data;
nr_out_points=330;
dpar_len=3;
par_file=arc_dlayer_int_ht_par_P.txt;
end_type
% Integrate the D layer slices
type=6;
vec_len=0;
data_start=0;
nr_rep=10;
send_raw=1;
user_lib_name=arc_dlayer_ht;
user_subr_name=int_data;
nr_out_points=34176;
dpar_len=3;
par_file=arc_dlayer_int_ht_par_D.txt;
end_type
% Integrate the E layer slices
type=6;
vec_len=0;
data_start=0;
nr_rep=10;
send_raw=1;
user_lib_name=arc_dlayer_ht;
user_subr_name=int_data;
nr_out_points=1068;
dpar_len=3;
par_file=arc_dlayer_int_ht_par_E.txt;
end_type
end_chan
arc_dlayer_ht.c
#include /*Needed for bzero */
#include types.h> *Needed for int16_t */
typedef struct /* Make a new internal data type */
{
float re;
float im;
}
DSPCMPLX;
typedef struct /* Make a new internal data type used for input data */
{
int16_t re;
int16_t im;
}
DSPCMPLXSHORT;
int
int_data (unsigned long dbits,
int *dpar, unsigned long fbits, float *fpar, DSPCMPLXSHORT * in, DSPCMPLX * out, double *upar)
{
/* upar is a value which can be set and read from eros directly
for example "upar 1 10" will set upar 1 to the value of 10
these values are double note if you wnat to use them inside you lib
upar 1 is upar[0] in you lib max 20 values */
int nr_loops, nr_points, data_start, i, j;
DSPCMPLX *p_in;
data_start = dpar[0];
nr_points = dpar[1];
nr_loops = dpar[2];
/* A new pointer to the start of the input data where the time sliced data
will be found, as we are dealing with pointers and indeed the calling
function is just passing a pointer to the place where this function should
write its result in the data output vector. It is than possible to move back
in the data vector and use old output data. */
p_in = out + data_start;
/* Clear the output vector if this is not done we will continue to
integrate until decodump is stopped */
bzero (out, sizeof (DSPCMPLX) * nr_points);
for (i = 0; i < nr_loops; i++)
{
for (j = 0; j < nr_points; j++) { (out + j)->re += (p_in + i * nr_points + j)->re;
(out + j)->im += (p_in + i * nr_points + j)->im;
}
}
return 0;
}
parameter file
% Number of transmission and receive cycles in one integration period
4800
% Number of samples taken in each receive cycle
450
% Number of Bauds in each code set
256
% Number of code pair decoded and coherently integrated
4
% Where is the noise injection found in the d_data vector
% This is data will be found at -180 points back at current position
% in d_data
-180
% This is the used complementery code 2*256 Bauds
% Ordinary FIR decoder so the decoder values are reversed
% As an example code transmitted +-+-- decoder values will be --+-+
-1
1
-1
-1
-1
1
1
1
-1
1
-1
-1
1
-1
-1
-1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
-1
1
-1
-1
1
-1
-1
-1
1
-1
1
1
1
-1
-1
-1
-1
1
-1
-1
1
-1
-1
-1
-1
1
-1
-1
-1
1
1
1
-1
1
-1
-1
1
-1
-1
-1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
-1
1
-1
-1
1
-1
-1
-1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
-1
1
-1
-1
1
-1
-1
-1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
-1
1
-1
-1
1
-1
-1
-1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
-1
1
-1
-1
1
-1
-1
-1
-1
1
-1
-1
-1
1
1
1
-1
1
-1
-1
1
-1
-1
-1
1
-1
1
1
1
-1
-1
-1
-1
1
-1
-1
1
-1
-1
-1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
-1
1
-1
-1
1
-1
-1
-1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
-1
1
-1
-1
1
-1
-1
-1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
1
-1
1
1
1
-1
-1
-1
1
-1
1
1
-1
1
1
1
-1
1
-1
-1
-1
1
1
1
1
-1
1
1
-1
1
1
1
jurg3.c
#include
#include
#include
#include
#include
#include
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include
#include
typedef struct
{
float re;
float im;
}
DSPCMPLX; /* output data format */
/* To use int16_t sys/types.h is necessery to include for Linux */
typedef struct
{
int16_t re;
int16_t im;
}
DSPCMPLXSHORT; /* input data format */
struct thread_fir_struct
{
DSPCMPLXSHORT *in;
DSPCMPLX *out;
int code_len;
int nr_samp;
int pre_int;
float *tmp3;
float *tmp4;
int codea_b;
int nr_cycles;
}; /* Send struct for fir decoder */
/* Functions used inside this module. NOTE, use a name that will not be
found some where else in the decodump program, use as here a type6_ as a
pre-amble to the functions name if not very strange and very hard to find
errors will be the result*/
void type6_simulator (DSPCMPLXSHORT * in, int *code, int code_len,
int nr_samp, int cycles);
void type6_remove_clutter_prof (DSPCMPLXSHORT * in, int *mean_re,
int *mean_im, int nr_samp, int cycles);
void type6_fir (struct thread_fir_struct *fir_send);
void type6_lag_profiling (DSPCMPLX * in, DSPCMPLX * out_data, int nr_samp,
int max_lag);
/* dbits Number of integer parameters in dpar
* dpar Vector with user supplied integer parameters
* fbits Number of float parameters in fpar
* fpar Vector with user supplied float parameters
* in In data vector (16 bit + 16 bit signed integers)
* out Out data vector (32 bit + 32 bit floats) will be stored in mat. file
*/
/* The main module defined in the *.fil file */
int
jurg3_complementery_deco (unsigned long dbits,
int *dpar, unsigned long fbits, float *fpar,
DSPCMPLXSHORT * in, DSPCMPLX * out, double *upar)
{
int cycles, nr_samp, i, pre_int, code_len, pre_int_ascii, noise_start;
pthread_t *thread_fir;
pthread_attr_t sched_fir;
int *code, m, ret_code, nr_samp_decoded, cycles_int, cycles_int_asc;
FILE *fidw;
struct tm tt, *tim;
time_t secs;
long seconds0, seconds_start_y;
float *tmp3_1, *tmp3_2, *tmp4;
DSPCMPLX *tmp1, *tmp1_ascii;
int *mean_re, *mean_im, err, *filter_coff;
struct timeval my_timeval1, my_timeval2;
char t_str[128], base_dir[] =
"jurg3_ascii", dir[255], time_sec[32], data_file[255], *dir_to_make,
*path_to_make, *path_mkdir;
struct thread_fir_struct *fir_send;
/* Start to init necessery parts of the pthred functionality */
ret_code = pthread_attr_init (&sched_fir);
if (ret_code != 0)
{
printf ("pthread_attr_init sched_fir error=%d\n", ret_code);
exit (EXIT_FAILURE);
}
/* These threads will inherit the schedule policy from the main decodump */
ret_code = pthread_attr_setinheritsched (&sched_fir, PTHREAD_INHERIT_SCHED);
if (ret_code != 0)
{
printf ("pthread_attr_setinheritsched sched_glob_write_mat error=%d",
ret_code);
exit (EXIT_FAILURE);
}
/* This step can not be forgotten on a SUN system this will tell the
operating system that we want to use multiple CPU if they are availble
default is just the create threads on one CPU */
ret_code = pthread_attr_setscope (&sched_fir, PTHREAD_SCOPE_SYSTEM);
if (ret_code != 0)
{
printf ("pthread_attr_setscope error=%d", ret_code);
exit (EXIT_FAILURE);
}
/* Define how the scheduling on the threads should be Round Robin in this case */
#ifndef __linux__
ret_code = pthread_attr_setschedpolicy (&sched_fir, SCHED_RR);
if (ret_code != 0)
{
printf ("pthread_setschedpolicy sched_fir error =%d", ret_code);
exit (EXIT_FAILURE);
}
#endif
/* Check if we want to save ascii data set also if so make the file and directory name */
if (((int) upar[2]) == 0)
{
time (&secs);
tim = gmtime (&secs);
fir_send =
(struct thread_fir_struct *)
calloc (2, sizeof (struct thread_fir_struct));
err = chdir ("/data2");
if (err == -1)
{
printf ("Cannot chdir to /data2 \n");
}
strftime (t_str, 32, "%Y%m%d_%H", tim);
dir[0] = '\0';
strcpy (dir, base_dir);
strcat (dir, "/");
strcat (dir, t_str);
dir_to_make = malloc (strlen (dir) + 10);
path_to_make = malloc (strlen (dir) + 10);
path_to_make[0] = dir_to_make[0] = '\0';
strcat (dir_to_make, dir);
while ((path_mkdir = strtok (dir_to_make, "/")) != NULL)
{
strcat (path_to_make, path_mkdir);
err = mkdir (path_to_make, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
strcat (path_to_make, "/");
dir_to_make = NULL;
}
free (dir_to_make);
free (path_to_make);
memset (&tt, 0, sizeof (struct tm));
tt.tm_mday = 1;
tt.tm_year = tim->tm_year;
seconds0 = mktime (&tt) - timezone; /* UTC seconds at beginn of year */
seconds_start_y = mktime (tim) - seconds0;
sprintf (time_sec, "%ld", seconds_start_y);
data_file[0] = '\0';
strcat (data_file, dir);
strcat (data_file, "/");
strcat (data_file, time_sec);
strcat (data_file, ".txt");
}
/* Take the supplied variables from the *.fil file and put them in local variables */
cycles = dpar[0];
nr_samp = dpar[1];
code_len = dpar[2];
pre_int = dpar[3];
noise_start = dpar[4];
pre_int_ascii = 1; /* Used for ascii dump will NOT pre integrate */
filter_coff = dpar + 5;
nr_samp_decoded = nr_samp - code_len + 1;
cycles_int = cycles / (2 * pre_int);
cycles_int_asc = cycles / (2 * pre_int_ascii);
/* Allocate the pthread structure used for the fir decoder thread */
/* Two threads will be used, one decoder thread for each code set */
thread_fir = (pthread_t *) malloc (2 * sizeof (*thread_fir));
/* Clear the output vector if this is not done we will continue to
* integrate until decodump is stopped */
memset (out, 0, sizeof (DSPCMPLX) * nr_samp_decoded * cycles_int);
/* Allocate some internal used scrap vectors, do not forget to free them */
/* Allways think twice so you do not have data vectors which are used at
the same time in different threads especially if they are both read and
write to. This can give strange errors which just shows occasionally,
again try and debug your libraries under Linux and use valgrind in
helgrind mode which will find this kind of errors */
tmp1 = calloc (2 * nr_samp_decoded * cycles_int, sizeof (DSPCMPLX));
tmp1_ascii =
calloc (2 * nr_samp_decoded * cycles_int_asc, sizeof (DSPCMPLX));
tmp3_1 = calloc (nr_samp, sizeof (DSPCMPLX));
tmp3_2 = calloc (nr_samp, sizeof (DSPCMPLX));
tmp4 = calloc (2 * code_len, sizeof (float));
/* Read in fir coffs. */
for (i = 0; i < 2 * code_len; i++)
{
tmp4[i] = (float) (filter_coff[i]);
}
/* Internal vectors used in clutter remover */
mean_re = calloc (2 * nr_samp, sizeof (int));
mean_im = calloc (2 * nr_samp, sizeof (int));
/* Start to fill the struct used for sending variable to the fir thread */
fir_send[0].tmp3 = tmp3_1;
fir_send[1].tmp3 = tmp3_2;
fir_send[0].code_len = fir_send[1].code_len = code_len;
fir_send[0].nr_samp = fir_send[1].nr_samp = nr_samp;
fir_send[0].in = fir_send[1].in = in;
fir_send[0].tmp4 = fir_send[1].tmp4 = tmp4;
/* The simulator and the clutter remover are set by the user parameter
from eros "upar 2 1" for enable simulator and "upar 1 1" to not use clutter
subtractor */
/* Just for testing to se that the decoder is OK */
if (((int) upar[1]) == 1)
{
code = calloc (2 * code_len, sizeof (int));
/* Read the code used from the parameter file and used that */
for (i = 0; i < code_len; i++)
{
code[code_len - i - 1] = dpar[i + 5];
}
for (i = 0; i < code_len; i++)
{
code[2 * code_len - i - 1] = dpar[i + 5 + code_len];
}
type6_simulator (in, code, code_len, nr_samp, cycles);
free (code);
}
/* If upar 3 is set to 1 do not make and save ascii data */
if (((int) upar[2]) == 0)
{
gettimeofday (&my_timeval1, NULL);
/* Open a file for write */
printf ("Will open file %s for ASCII data write\n", data_file);
fidw = fopen (data_file, "w");
if (fidw == NULL)
{
printf ("ERROR %s\n", data_file);
perror (data_file);
}
fir_send[0].pre_int = fir_send[1].pre_int = pre_int_ascii;
fir_send[0].nr_cycles = fir_send[1].nr_cycles = cycles_int_asc;
for (m = 0; m < 2; m++) /* Two different codes used */
{
fir_send[m].codea_b = m;
fir_send[m].out = tmp1_ascii + m * nr_samp_decoded * cycles_int_asc;
/* If -D__PTHREAD__ is used when compiling, the threading will kick in */
#ifdef __PTHREAD__
ret_code =
pthread_create (&(thread_fir[m]), &sched_fir,
(void *(*)(void *)) type6_fir,
(void *) (fir_send + m));
if (ret_code != 0)
{
printf ("ret_code is %d\n", ret_code);
exit (EXIT_FAILURE);
}
#else /* Use the non threaded model */
type6_fir (fir_send + m);
#endif
}
#ifdef __PTHREAD__ /* If we are using threading we need to wait for both threads */
for (m = 0; m < 2; m++)
{
ret_code = pthread_join (thread_fir[m], NULL);
if (ret_code != 0)
{
printf ("pthread_join 1 error=%d\n", ret_code);
exit (EXIT_FAILURE);
}
}
#endif
/* Integrate both code sets */
for (i = 0; i < cycles_int_asc * nr_samp_decoded; i++)
{
tmp1_ascii[i].re +=
tmp1_ascii[i + cycles_int_asc * nr_samp_decoded].re;
tmp1_ascii[i].im +=
tmp1_ascii[i + cycles_int_asc * nr_samp_decoded].im;
}
/* Put noise injection and background data in to ascii file */
for (i = 0; i < -noise_start; i++)
{
fprintf (fidw, "%d %d\r\n", (int) (out + noise_start)[i].re,
(int) (out + noise_start)[i].im);
}
/* Put decoded data in to ascii file */
for (i = 0; i < cycles_int_asc * nr_samp_decoded; i++)
{
fprintf (fidw, "%d %d\r\n", (int) tmp1_ascii[i].re,
(int) tmp1_ascii[i].im);
}
fclose (fidw);
gettimeofday (&my_timeval2, NULL);
printf ("It have taken %f sec to do fir/lag and ASCII data save\n",
((double) my_timeval2.tv_sec +
(double) my_timeval2.tv_usec / 1.e6) -
((double) my_timeval1.tv_sec +
(double) my_timeval1.tv_usec / 1.e6));
}
/* Filter data and do preintegration */
gettimeofday (&my_timeval1, NULL);
/* A very simple clutter remover just make two clutter profiles for
* each code for the whole integration and remove this from the data
* before starting to decode and lagging */
if (((int) upar[0]) == 0)
type6_remove_clutter_prof (in, mean_re, mean_im, nr_samp, cycles);
/* Do the decoding and preintegration of data */
fir_send[0].pre_int = fir_send[1].pre_int = pre_int;
fir_send[0].nr_cycles = fir_send[1].nr_cycles = cycles_int;
for (m = 0; m < 2; m++) /* If threaded use two */
{
fir_send[m].codea_b = m; /* code a or code b */
fir_send[m].out = tmp1 + m * cycles_int * nr_samp_decoded;
#ifdef __PTHREAD__ /* If pthread */
ret_code =
pthread_create (&(thread_fir[m]), &sched_fir,
(void *(*)(void *)) type6_fir,
(void *) (fir_send + m));
if (ret_code != 0)
{
printf ("ret_code is %d\n", ret_code);
exit (EXIT_FAILURE);
}
#else /* do it non threaded */
type6_fir (fir_send + m);
#endif
}
#ifdef __PTHREAD__
for (m = 0; m < 2; m++)
{
/* Threaded wait until both threads are ready */
ret_code = pthread_join (thread_fir[m], NULL);
if (ret_code != 0)
{
printf ("pthread_join 1 error=%d\n", ret_code);
exit (EXIT_FAILURE);
}
}
#endif
/* Integrate both code sets */
for (i = 0; i < cycles_int * nr_samp_decoded; i++) { tmp1[i].re += tmp1[i + cycles_int * nr_samp_decoded].re; tmp1[i].im += tmp1[i + cycles_int * nr_samp_decoded].im; } gettimeofday (&my_timeval2, NULL); printf ("It have taken %f sec to do fir\n", ((double) my_timeval2.tv_sec + (double) my_timeval2.tv_usec / 1.e6) - ((double) my_timeval1.tv_sec + (double) my_timeval1.tv_usec / 1.0e6)); gettimeofday (&my_timeval1, NULL); /*Do the lagprofiling of the decoded data */ type6_lag_profiling (tmp1, out, nr_samp_decoded, cycles_int); gettimeofday (&my_timeval2, NULL); printf ("It have taken %f sec to do lagprofiles\n", ((double) my_timeval2.tv_sec + (double) my_timeval2.tv_usec / 1.e6) - ((double) my_timeval1.tv_sec + (double) my_timeval1.tv_usec / 1.0e6)); /* Free all local allocated data segments */ free (tmp1); free (tmp1_ascii); free (tmp3_1); free (tmp3_2); free (tmp4); free (mean_re); free (mean_im); free (fir_send); return 0; } void type6_fir (struct thread_fir_struct *fir_send) { int i, j, k = 0, l, fir_passes = 1, m, ii, code_len, nr_samp_decoded; int nr_cycles, nr_samp, pre_int; float summa_i = 0.0, summa_r = 0.0; float *tmp2, *tmp1, *tmp4, *tmp3; DSPCMPLXSHORT *in_sub, *in, *in_start; DSPCMPLX *out, *out_start; m = fir_send->codea_b; /* Select code_a or code_b (0 or 1) */
code_len = fir_send->code_len;
tmp3 = fir_send->tmp3; /* Local copy of in data as floats */
tmp4 = fir_send->tmp4; /* Fir coffs. */
nr_cycles = fir_send->nr_cycles;
out_start = fir_send->out; /* Data after decoding */
in_start = fir_send->in; /* Raw data */
nr_samp = fir_send->nr_samp;
pre_int = fir_send->pre_int;
nr_samp_decoded = nr_samp - code_len + 1;
for (ii = 0; ii < nr_cycles; ii++)
{
out = out_start + ii * nr_samp_decoded;
in = in_start + 2 * ii * nr_samp * pre_int;
for (l = 0; l < pre_int; l++) /* Sum data from preint code set together */
{
k = 0;
in_sub = in + 2 * l * nr_samp + m * nr_samp; /* Jump to proper IPP */
for (j = 0; j < 2 * nr_samp;) /* Just move data over to floats */ { tmp3[j++] = (float) (in_sub->re);
tmp3[j++] = (float) (in_sub->im);
in_sub++;
}
/* Start the FIR decoding of data */
for (j = 2 * (code_len - 1); j < 2 * nr_samp; j += 2)
{
tmp1 = tmp4 + m * code_len;
tmp2 = tmp3 + j + 1;
for (i = 0; i < code_len; i++)
{
summa_i += (*(tmp1)) * ((*(tmp2--)));
summa_r += (*(tmp1++)) * ((*(tmp2--)));
}
out[k].re += summa_r;
out[k].im += summa_i;
k += fir_passes;
summa_i = summa_r = 0.;
}
}
}
}
void
type6_lag_profiling (DSPCMPLX * in, DSPCMPLX * out, int nr_samp, int max_lag)
{
int j, k, i;
float a, b, c, d;
/* Lag profiling data */
for (i = 0; i < max_lag; i++)
{
for (k = 0; k < max_lag - i; k++)
{
for (j = 0; j < nr_samp; j++)
{
a = in[j + k * nr_samp].re;
b = in[j + k * nr_samp].im;
c = in[j + (k + i) * nr_samp].re;
d = in[j + (k + i) * nr_samp].im;
out[j + nr_samp * i].re += a * c + b * d;
out[j + nr_samp * i].im += a * d - b * c;
}
}
}
}
void
type6_simulator (DSPCMPLXSHORT * in, int *code, int code_len, int nr_samp,
int cycles)
{
int j, i, m;
/* Simulating a hard target at 50 samples */
for (j = 0; j < cycles; j += 2)
{
for (m = 0; m < 2; m++)
{
for (i = 0; i < 50; i++)
{
in[(m + j) * nr_samp + i].re = 0;
in[(m + j) * nr_samp + i].im = 0;
}
for (i = 50; i < 50 + code_len; i++)
{
in[(m + j) * nr_samp + i].re = code[i - 50 + m * code_len];
in[(m + j) * nr_samp + i].im = 0;
}
for (i = 50 + code_len; i < nr_samp; i++)
{
in[(m + j) * nr_samp + i].re = 0;
in[(m + j) * nr_samp + i].im = 0;
}
}
}
}
void
type6_remove_clutter_prof (DSPCMPLXSHORT * in, int *mean_re, int *mean_im,
int nr_samp, int cycles)
{
int j, i, m;
/* A simple clutter remover */
/* Make the clutter profile for code A and B separetly */
for (j = 0; j < cycles; j += 2)
{
for (m = 0; m < 2; m++)
{
for (i = 0; i < nr_samp; i++)
{
mean_re[i + m * nr_samp] +=
in[j * nr_samp + i + m * nr_samp].re;
mean_im[i + m * nr_samp] +=
in[j * nr_samp + i + m * nr_samp].im;
}
}
}
/* Scale the clutter profiles */
for (m = 0; m < 2; m++)
{
for (i = 0; i < nr_samp; i++)
{
mean_re[i + m * nr_samp] /= (cycles / 2);
mean_im[i + m * nr_samp] /= (cycles / 2);
}
}
/* Subtracte clutter profiles on each code set */
for (j = 0; j < cycles; j += 2)
{
for (m = 0; m < 2; m++)
{
for (i = 0; i < nr_samp; i++)
{
in[j * nr_samp + i + m * nr_samp].re -=
mean_re[i + m * nr_samp];
in[j * nr_samp + i + m * nr_samp].im -=
mean_im[i + m * nr_samp];
}
}
}
}
jurg3.elan
########################################################################
# jurg3.elan
#
# EROS4 script for jurg3 experiment.
#
# Data layout: 128 bit
# 0-44 Background + noise injection, CH2
# 45-90 Background, CH2
# 90-76889 Decoded lagprofiles with ground clutter removed by calculate the
# clutter profile on the current data dump and remove that,
# 600 lags with lag increment of 10 ms, 128 decoded ranges range res. 300 m, CH1
# d_raw 0-1223999 16 bit complex data from CH1
#
# Data layout: 256 bit
# 0-89 Background + noise injection, CH2
# 90-179 Background, CH2
# 180-117179 Decoded lagprofiles with ground clutter removed by calculate the
# clutter profile on the current data dump and remove that,
# 600 lags with lag increment of 10 ms, 255 decoded ranges range res. 150 m, CH1
# d_raw 0-2159999 16 bit complex data from CH1
########################################################################
BLOCK jurg3 {{scan any} {owner CP} {height 90.0}} {
set scan [string tolower $scan]
set owner [string toupper $owner]
upar 1 0 ;# If 1 no clutter subtract
upar 2 0 ;# If 1 simulate a hardtarget
upar 3 0 ;# If 1 do NOT save ascii data
set BITS 256 ;# Set the number of bit used for transmission can be 128 or 256
set SCAN_PAT $scan ;# Scan pattern to use
set Owner $owner ;# Who is running the experiment (CP, SW ... so on)
set Height $height ;# Height used
###############
# Definitions #
###############
set XDIR /kst/exp/ge/jurg3 ;# Default directory
set Version 1.20 ;# What version
#Version 1.20 has a bit longer IPP (1.25 ms) to better go with Sousy
set FIR /kst/dsp/fir ;# Where we have fir filters
set Expname "jurg3" ;# experiment name
set Iper_us 6000000 ;# Integration time in us
#set Loopc 500 ;# loops for one integration
set Loopc 480 ;# loops for one integration
set Sync 0 ;# sync time between integrations
set SCANDIR /kst/exp/scans/kst
# On what radar are we?
if {[ISUHF]} {
set RADAR uhf
set Site "u"
set ant u
} elseif {[ISESR]} {
set Site "32m"
set SCANDIR /kst/exp/scans/esr
set ant 32m ;# Antenna used
} elseif {[ISKIR]||[ISSOD]} {
set RADAR uhf
set Site "r"
set ant r
} elseif {[ISVHF]} {
set Site "v"
set RADAR vhf
setpanelpath allB
set ant v
}
set SCAN_FILE $SCANDIR/${SCAN_PAT}_pattern.elan
set PAT_LIST [split $SCAN_PAT /] ;#Split the user supplied scanning path
set SCAN_PAT1 [lindex $PAT_LIST [expr [llength $PAT_LIST]-1]]
set Iper_s [expr double($Iper_us)/double(1000000)]
set SCAN_PAT ${SCAN_PAT1}
# Make a proper experiment ID for the system in use
set Expid "kst0 ${Expname}_${BITS}_${SCAN_PAT1}_${Version}${Site}_${Owner}"
exec cp $XDIR/rtg_def_${BITS}.m $XDIR/rtg_def.m
# Filter to use
if {[ISESR]} {
if {$BITS == 128} {
set Filter1 $FIR/b250d30.fir ;# +-250 kHz filter for 2 usec sampling
} else {
upar 3 1 ;# If 1 do NOT save ascii data
set Filter1 $FIR/b500d15.fir ;# +-500 kHz filter for 1 usec sampling
}
set TXFRQ $XDIR/${Expname}_${BITS}_32m.frq
} else {
set Filter1 $FIR/b170d45.fir ;# +-170 kHz filter for 3 usec sampling
}
# NCO file to load into channels boards
set NCO1 $XDIR/ch1_${Expname}_${BITS}_${Site}.nco
# DSP file to use
set Corrfile $XDIR/${Expname}_${BITS}_${Site}.fil
# Defines what experiment files should be stored
set Expfiles [list $XDIR/$Expname.elan $SCAN_FILE $Corrfile \
$XDIR/${Expname}_${BITS}_${Site}a.par $NCO1 $Filter1 $XDIR/rtg_def_${BITS}.m \
$XDIR/${Expname}_${BITS}_$ant.tlan $XDIR/$Expname.c $XDIR/${Expname}_${BITS}_32m_par.txt ]
if {[ISUHF]||[ISVHF]||[ISESR]} {
append Expfiles " $XDIR/${Expname}_${BITS}_${Site}b.par"
}
if {[ISESR]} {
append Expfiles " $TXFRQ"
}
#############
# Actual work
#############
# Get all different scan patterns online
source ${SCAN_FILE}
# Stop receiver --
SYNC -10
stopradar -rec
if {[ISUHF]||[ISVHF]||[ISESR]} {
stopradar -trans
}
stopdata
# Load radar controller --
if {[ISESR]} {
loadradar rec -loopc $Loopc -sync $Sync -file $XDIR/${Expname}_${BITS}_${ant}_ionesr.rbin -prog1 0
loadradar trans -loopc $Loopc -sync $Sync -file $XDIR/${Expname}_${BITS}_${ant}_esr.tbin -prog1 0
loadexciter $TXFRQ
} else {
loadradar rec -loopc $Loopc -sync $Sync -file $XDIR/${Expname}_${BITS}_${Site}_$RADAR.rbin -prog1 0
if {[ISUHF]||[ISVHF]} {
loadradar trans -loopc $Loopc -sync $Sync -file $XDIR/${Expname}_${BITS}-${Site}_$RADAR.tbin -prog1 0
} }
# mount $DataDisk ;# mount the desired data disk
# Load filters --
loadfilter $Filter1 ch1,2,3
# Set frequencies --
loadfrequency $NCO1 ch1,2,3
# Make initial load of frequencies
setfrequency ch1,ch2,ch3 12.0
# Start radar controllers --
SYNC 2
armradar rec -prog1
if {[ISUHF]||[ISVHF]||[ISESR]} {
armradar trans -prog1
}
startradar EXPSTART $Iper_s
# Start data access --------------------------------------------------------
SYNC 4
if {[ISESR]} {
startdata ion $Corrfile $Expid $Iper_us $ant
} else {
startdata $Corrfile $Expid $Iper_us
}
# Write all experiment related files to the data directory
writeexperimentfile $Expfiles
SYNC 4
disablerecording
# Infinite scanning loop
set ExpStart [timestamp [getstarttime exp]]
if {[ISESR]} {
callblock ${SCAN_PAT}_pattern $Iper_s
} else {
gotoblock ${SCAN_PAT} $ExpStart $Expname $Height
}
# Ensure that we will not fall out of this proc
DO -1 { SYNC 100 }
};#jurg3
eval callblock jurg3 [argv]