OVERVIEW OF NO_DATA TASK



The "no_data" task was developed at BAS as an adaptive sounding task to reduce dependence on the radar operator selecting the optimum frequency for sounding. When incorporated in the radar control programme (RCP) it monitors the amount of scatter being received (usually placed in the RCP to do this at the end of a full scan). If the amount of scatter falls below a threshold ("nodata_bin_threshold" variable, set in the RCP or specified at task start up) then this triggers a frequency search, using frequencies specified in the RCP. At the end of the frequency search one of two actions can occur.



1) If one of the frequencies scanned has a scatter count that exceeds a threshold value (NODATA_MIN_DATA variable) then the radar moves to this frequency and commences the next scan. As long as the scatter count exceeds the "nodata_bin_threshold" variable the radar will continue at this frequency.



2) If no frequency shows a scatter count that exceeds the NODATA_MIN_DATA variable then the radar moves to a default frequency and commences a scan.



Other variable that can be specified at task start up time are:



The parameter that is to be used for determining the count rate, at Halley this is the pwr_l parameter (e.g. -p p_l).



A threshold value for this parameter, at Halley we normally use 3dB (e.g. -t 3.0). Only pwr_l values exceeding 3dB will contribute to the scatter count.



A minimum range for scatter that is to contribute to the scatter count, at Halley we normally use 600 km (e.g. -d 600). We choose to do this in order to bias the radar operation towards collecting F-region scatter.



The no_data task also accesses the ground scatter flag and does not include ground scatter in the scatter count. Operators who are particularly interested in ground scatter must be aware of this. This condition could easily be removed from the code, ask for details.



The frequency search is only done on a subset of beams (not the full 16). These beams can be set in the RCP. In the RCP at Halley we search five frequencies, each frequency with four beams (2,6, 10 and 14). This allows us to complete the frequency search in less than 2 minutes, so that the next scan can be started on a two minute time boundary. IF YOU CHANGE THE NUMBER OF FREQUENCIES AND/OR BEAMS you may lose this synchronisation with two minute time boundaries.



See the annotated RCP for further details.



GENEALOGY



Original code developed by Rob Barnes whilst working at BAS. Modified in light of operating experience by Duncan Smith and Kevin O'Rourke (Halley radar engineers).





INSTALLATION



1. Access the file no_data.tar.F and put in a temporary directory (/tmp)



2. Type 'install -u nodata.tar.F'



3. It should then unpack itself into

/radops/usr/src/no_data and

/radops/usr/src/normal_scan_nodata.



4. "Readme" files included in above package are copies of the "no_data" and "normal_scan_nodata" sections of this Web page.











NO_DATA



This is the adaptive sounding sampling task, which is used by the

normal_scan_nodata RCP to count the amount of scatter received.





Description

-----------

The task receives fit data from echo_data and uses the sampling routines in

the Radops2000 library to calculate the number of beam/range points which

have more than a specified value of a selected parameter. The minimum

distance at which scatter should be counted can also be specified.



no_data is used by sending a QNX message requesting either that the scatter

count be returned or that the count be reset.





Compiling

---------

The task is compiled by typing 'make' in the no_data directory. This compiles

and links two versions of the file, the normal version and a debugging version

which displays useful information on the console.





Usage

-----

Usage information is available from the QNX 'use' command.















NORMAL_SCAN_NODATA





This is the adaptive sounding RCP which communicates with the no_data task

to find the best frequency for radar operation.





Description

-----------

The program is based on the Radops2000 v4.1 normal_scan RCP (version 2.12)

with the addition of checking the scatter count at the end of each normal

scan. If this count is below a set threshold (nodata_bin_threshold, which

can be specified on the command line) the program searches a set of user-

defined frequencies to find which has the greatest scatter count.



The frequency search uses an integration time of 5s and scans beams 2, 6, 10

and 14 in that order. The frequencies scanned can be altered by editing

normal_scan_nodata.c.



The next normal scan will then be carried out at the frequency with the

greatest count, unless the count is below another threshold (NODATA_MIN_DATA),

in which case a default frequency (NODATA_DEFAULT_FREQ) is used.





Compiling

---------

The RCP is compiled by typing 'make' while in the normal_scan_nodata

directory. This compiles and links three different versions of the file,

the normal version, the debug version and the discretionary time version.



While compiling some compiler warnings will appear, these are due to using

the maximum warning level on the compiler. The warnings are due to missing

information in some of the Radops library header files.





Usage

-----

Usage information is available with the QNX 'use' command.





If you have any problems with the software please contact me via Mike Pinnock.



Also, if you have made any useful modifications to the program it would be

useful if you could send them as RCS files, to make merging them into the

master copy easier.



Kevin O'Rourke, SHARE radar engineer, Halley























ANNOTATED COPY of NORMAL_SCAN_NODATA



Red highligths are code relating to no_data task.



This radar control program uses the nodata task to count the amount of scatter picked up in each scan. If the scatter count is below a specified threshold the program then searches over several frequencies to find more scatter.



/* normal_scan_nodata

================== */



/*

$Log: normal_scan_nodata.c,v $

* Revision 1.8 1998/09/28 05:42:23 root

* Previous version had output frequency search results even if no search had

* been performed. This has now been fixed.

*

* Revision 1.7 1998/08/17 15:49:07 root

* Corrected a bug which meant that the scatter count from the 15MHz scan

* was never requested. Also added a threshold value and default frequency

* so that if there is no scatter about the radar will run at 12300kHz and

* so not cause riometer noise.

*

* Revision 1.6 1998/08/12 11:16:46 root

* Modified so that frequency search displays a table of scatter found at

* each frequency and displays the correct selected frequency.

*

* Revision 1.5 1998/06/29 12:13:42 root

* Minor changes (mostly bad spelling in messages) after testing.

*

* Revision 1.4 1998/06/10 12:35:26 root

* Corrected time errors on frequency search beams - set_time() was not

* being called.

* Added user_interrupt() call in frequency search, allows variables to be

* altered/examined and the program to be stopped by the scheduler.

* Fixed problem with using the wrong value of intt.

* Moved post normal scan wait_boundary() call to within frequency search

* section, will now only be called if the scatter count is below the

* threshold.

*

* Revision 1.3 1998/04/29 18:27:18 root

* Altered to include the normal_scan_nodata.h header file, corrected a few

* compiler warnings.

*

* Revision 1.2 1998/04/29 17:37:05 root

* Almost working version, still under development. Changes required to add

* header files, function prototypes, etc.

*

* Revision 1.1 1998/03/20 12:26:26 root

* Initial revision

*

** This is a modified version of the Radops2000 v4.1 normal_scan.c **

** version 2.12 **

*/

The RCP starts with the RCS log, detailing the changes made between versions.



#ifdef __USAGE

%C[-dt day_time] [-nt night_time] [-df day_start_freq]

[-nf night_start_freq] [-dr day_frang] [-nr night_frang]

[-xcf xcount] [-dm day_mpinc] [-nm night_mpinc]

[-sb start_beam] [-eb end_beam] [-th nodata_bin_threshold]

[option file]

#endif

This section provides the information used by the QNX use command. This should always be present to give the end user an easy way of getting usage information.



#define SIM_FILE "/radops/demo.dat"

The SIM_FILE is used in debug mode as a source of dummy data, any .DAT file will work.



#define CP_ID 150

The CP_ID is the control program number recorded in the data files.



#define NODATA_MIN_DATA 5 /* threshold for frequency search */

#define NODATA_DEFAULT_FREQ 12300 /* default frequency if the threshold is

* not met */

If none of the frequencies in the nodata frequency search have more than NODATA_MIN_DATA bins of scatter then NODATA_DEFAULT_FREQ will be used as the frequency.



#include <stdlib.h>

#include <stdio.h>

#include <signal.h>

#include <string.h>

Include the standard C headers required by this program.



/* Headers for the control library

* ===============================

*

* The control library contains the functions for communicating with

* the other radar tasks.

*/



#include "message.h"

#include "radops.h"

#include "task_msg.h"

#include "fitdata.h"



#include "task_write.h"

#include "user_int.h"

#include "get_status.h"

#include "log_error.h"

#include "sample.h"

#include "read_raw.h"



#include "get_fit.h"

#include "read_clock.h"



/* Header for the support library

* ===============================

*

* The support library contains the functions for performing a clear

* frequency search and an integration. The routine also contains

* all the code for calculating the ACF's.

*/





#include "support.h"

#include "sync.h"

#include "summary_control.h"

#include "option.h"

Include all the normal Radops2000 header files.



/* the normal_scan headers */



#include "radar_id.h"

#include "default.h"

default.h contains the default parameters for each of the SuperDARN radars.



#include "site.h"

site.h contains constants and function prototypes for site.c, the site-specific code file.



#include "normal_scan_nodata.h"

normal_scan_nodata.h contains constants and function prototypes for this file.



/* headers for no_data */

#include "/radops/usr/src/no_data/no_data.h"

no_data.h contains constants and function prototypes required to use the nodata task.



/* registered names of the tasks to receive data */

#include "task_names.h"

/* task_names.h doesn't define the name for no_data */

#define NODATA "no_data"

Define the default name for the nodata task.



char prg_name[32]; /* this is the program name displayed by display */

char cmd_line[256];

char errbuf[256];

Some string buffers are created, these are used later in the RCP.



/* The command line options */



struct option opt[] = {

{"dt", 's', 0, NULL},

{"nt", 's', 0, NULL},

{"df", 's', 0, NULL},

{"nf", 's', 0, NULL},

{"dr", 's', 0, NULL},

{"nr", 's', 0, NULL},

{"xcf",'s', 0, NULL},

{"dm", 's', 0, NULL},

{"nm", 's', 0, NULL},

{"sb", 's', 0, NULL},

{"eb", 's', 0, NULL},

{"th", 'l', 0, NULL},

0};

This structure defines the command-line options accepted by normal_scan_nodata, it is used by the function set_option in site.c to set default parameters and by the Radops2000 library function process_option.



/* The main program */



int start_freq,end_freq,freq_range;

int start_beam,end_beam,skip_beam=0;

int count=0,xcount;



long int nodata_bin_threshold;

These are global variables used within normal_scan_nodata and also in site.c.



void nodata_task_put(int *status);

void nodata_task_get(long int *task_get_count, int *status);

Function prototypes for functions in this file.



void main(int argc,char *argv[]) {



int f=0;

int exit_poll=0;

int frame_counter=0;

int argnum=0;

int status,c;

These are variables used purely within normal_scan_nodata



FILE *sim_file=NULL;

FILE *opt_file=NULL;

These lines create file pointers which will be used later to access the dummy data file (for debug mode) and the options file (if used).

/* define the pulse sequence and the lag table */



short int ptab[7] = {0,9,12,20,22,26,27};

short int lags[2][18] ={

{0,26,20,9,22,22,20,20,12,0,12,9,0,9,12,12,9,9},

{0,27,22,12,26,27,26,27,20,9,22,20,12,22,26,27,26,27}};

These two arrays specify the pulse sequence that will be used by the radar, they are not usually altered.



/* nodata variables */

/* nodata_bin_threshold is global */

/* long int nodata_count;

* long int nodata_dummy; - these two don't seem to be required */

int selectf;

int nodata_flag;

long int nodata_count_max;

long int scatter_count;

int do_once;

int loop;

These variables are used by the nodata frequency search section of the RCP, to keep track of frequencies and scatter counts.



int nodata_freq[] = {11350, 12350, 13350, 14350, 15350};

These are the frequencies which will be searched.

int number_freq = sizeof(nodata_freq)/sizeof(int);

To avoid hard-coding the number of search frequencies this line calculates the number by dividing the number of bytes used by the frequency array by the number of bytes used by each entry.

int nodata_scatter_count[sizeof(nodata_freq)/sizeof(int)];

This line creates an array to store the scatter count found at each frequency.



/* build the command line string */

sprintf(errbuf,"Station:%s",SD_RADAR_NAME);

log_error(ERRLOG_NAME,"control",errbuf);

Put the radar station name into a buffer and write it to the console and the error log file.



log_error(ERRLOG_NAME,"control","Control Program started.");



/* do any site specific set up */



start_program();

This is a function declared in site.c which sets up site-specific defaults parameters for the RCP.



strcpy(cmd_line,argv[0]);

for (c=1;c<argc;c++) {

strcat(cmd_line," ");

strcat(cmd_line,argv[c]);

}

This loop builds up a copy of the command line used to start the program, in a buffer.

sprintf(errbuf,"Command Line:%s",cmd_line);

log_error(ERRLOG_NAME,"control",errbuf);

The buffer is then sent to the error logging task which writes it to the error log file and to the console.



/* set up the option structure */



set_option(opt);

This site.c function fills the option structure defined above with the default radar parameters set in start_program.



/* decode the command line parameters */

argnum=process_option(argc,argv,opt,NULL);

This Radops2000 library function takes the option structure and uses it to process the command-line options. See the Radops2000 v4.10 manual for details.



if (argnum<argc) {

opt_file=fopen(argv[argnum],"r");

if (opt_file !=NULL) {

process_file(opt_file,opt,NULL);

fclose(opt_file);

} else log_error(ERRLOG_NAME,"control","Failed to read option file");

}

If there are more command-line arguments than options then the last one is assumed to be the name of a file containing more options. This is processed by the Radops2000 library function process_file.



log_error(ERRLOG_NAME,"control","Registering control Program.");

register_program(SCHEDULE_NAME,OUR_NAME);

The RCP is registered with Radops under the name specified, with the scheduler SCHEDULE_NAME. See the Radops2000 v4.10 manual for further details.



/* setup communication with the other tasks */

log_error(ERRLOG_NAME,"Control","Starting drivers.");

start_up(DRIVER_NAME,RADOPS_DIO_NAME,ERRLOG_NAME);

The Radops2000 library function start_up sets up communication with the hardware driver tasks radops_dio and a_d_drive. More information is given in the manual.



/* set the pulse and lag tables in the parameter block */

log_error(ERRLOG_NAME,"Control","Setting pulse table.");

set_pulse(&raw_dt_buf,ptab,7);

set_lag_table(&raw_dt_buf,lags,18);

These two library functions copy the pulse sequence and lag tables defined above into the Radops parameter block. See the manual for further information.



/* close any raw or fit data files that may still be open */



log_error(ERRLOG_NAME,"Control","Closing any existing files.");

read_clock(&yr,&mon,&day,&hr,&min,&sec,&msec,&usec);

task_close(RAWWRITE,yr,mon,day,hr,min,sec);

task_close(FITACF,yr,mon,day,hr,min,sec);

task_close(ECHO_DATA,yr,mon,day,hr,min,sec);

Before starting to write data to files, first close any data files which are still open. This is done using the library function task_close, which asks the rawwrite and fitacf tasks to close their files and the echo_data task to send file close messages to its clients.



/* open new raw and fit data files */

log_error(ERRLOG_NAME,"control","Opening first set of data files.");

task_open(RAWWRITE,cmd_line,yr,mon,day,hr,min,sec);

task_open(FITACF,cmd_line,yr,mon,day,hr,min,sec);

task_open(ECHO_DATA,cmd_line,yr,mon,day,hr,min,sec);

New files are opened in the same way.

/* set up the default parameters */

strcpy(combf,"$Id: normal_scan_nodata.c,v 1.8 1998/09/28 05:42:23 root Exp $");

The RCS ID string is used as an identifier in the Radops parameter block, stored in the comment buffer string.

/* set up the nodata default parameters */

selectf = day_start_freq;

scatter_count = nodata_bin_threshold;

Before starting the first scan we set a default frequency and initialise the scatter count variable.



#ifdef DISCRETIONARY

cp =-CP_ID;

#else

cp=CP_ID;

#endif

If we are running this program in discretionary time then the CP_ID should be negative.



#ifdef BACKWARDS

usr_resS1 = -1; /* backwards scan */

#else

usr_resS1 = 1; /* forward scan */

#endif

This uses the user-defined short integer usr_resS1 in the Radops parameter block to indicate whether the radar is forward or backward scanning.



#ifdef DEBUG

log_error(ERRLOG_NAME,"control","Opening Simulated data file.");

sim_file=fopen(SIM_FILE,"r");

#endif

If running in debug mode open the dummy data file.



/* set the program name on the display */

strcpy(prg_name,"normal_scan_nodata");

The program name is copied into a string and sent to the display task later in the RCP.

log_error(ERRLOG_NAME,"control","Entering main loop.");

do {

read_clock(&yr,&mon,&day,&hr,&min,&sec,&msec,&usec);

Make sure the time variables are updated.



/* check if we need to open new files */



if (start_scan()==0) continue;

The site.c function start_scan checks whether time-dependent parameters need to be changed and returns 1. The test above allows the start of the scan to be delayed until start_scan thinks it is time to begin and is present for future expansion only.



if (test_hour(2) !=0) {

log_error(ERRLOG_NAME,"control","Opening new set of data files.");

task_close(RAWWRITE,yr,mon,day,hr,min,sec);

task_close(FITACF,yr,mon,day,hr,min,sec);

task_close(ECHO_DATA,yr,mon,day,hr,min,sec);

task_open(RAWWRITE,cmd_line,yr,mon,day,hr,min,sec);

task_open(FITACF,cmd_line,yr,mon,day,hr,min,sec);

task_open(ECHO_DATA,cmd_line,yr,mon,day,hr,min,sec);

}

Every two hours the old data files are closed and new ones opened.



/* record beam numbers if not usual */

if ((start_beam != START_BEAM) || (end_beam != END_BEAM)) {

usr_resS2=start_beam;

usr_resS3=end_beam;

}

The start and end beams being used are stored in user-defined short integers usr_resS2 and usr_resS3 in the Radops parameter block, unless they have not been changed from the defaults.



/* test whether we should perform xcf */



if (xcount > 0) {

++count;

if(count == xcount) {

xcf = 1;

count = 0;

} else xcf= 0;

} else xcf = 0;

If this radar has an interferometer array we set the xcf variable to indicate when cross-correlation should be carried out.



skip_beam=calc_skip(2);

The Radops library function calc_skip works out what beam we should start the scan on to make sure that we will finish before the next two minute boundary.



scan=1;

The scan variable is used to indicate the first beam in a scan, for later use by processing and display software (such as Pacemap).



intt=7;

start_freq=selectf;

Set the integration time and the start_frequency for the clear frequency search.



#ifdef BACKWARDS

if ((start_beam-skip_beam) < end_beam) skip_beam=0;

for (bmnum = start_beam-skip_beam; bmnum >= end_beam; --bmnum) {

#else

if ((start_beam+skip_beam) > end_beam) skip_beam=1;

for (bmnum = start_beam+skip_beam; bmnum <= end_beam; ++bmnum) {

#endif

This sets up the correct for loop for either a forward or backward scanning radar.



sprintf(errbuf,"Integrating beam:%d",bmnum);

report(errbuf);



end_freq=start_freq+freq_range;

Calculate the end frequency for the clear frequency search.



/* set the radar parameter block up */

set_block(&raw_dt_buf);

set_time(&raw_dt_buf);

Copy the local parameter variables into the Radops parameter block, which is used by all the library functions.

report("Performing clear frequency search.");

status=fclr(&raw_dt_buf,start_freq,end_freq,5);

Search from start_freq to end_freq, looking for the frequency with least interference.



integrate();

This site.c function performs any further site-dependent set-up and then performs an integration.



get_status(RADOPS_DIO_NAME,&raw_dt_buf,0);

The library function get_status asks radops_dio for the status and low power information which is returned from the transmitters at some radar sites.



#ifdef DEBUG

if (sim_file !=NULL) {

report("Loading simulated data.");

if (read_raw_data(sim_file,&raw_dt_buf) !=0) {

fclose(sim_file);

sim_file=fopen(SIM_FILE,"r");

}

}

#endif

In debug mode this code reads the raw data in from the dummy data file into the Radops data block.



/* send the raw data to the other tasks */

report("Sending raw data to tasks.");

task_write_raw(RAWWRITE,&raw_dt_buf,1);

task_write_raw(FITACF,&raw_dt_buf,1);

task_write_raw(ECHO_DATA,&raw_dt_buf,1);

task_write_aux(ECHO_DATA,prg_name,strlen(prg_name)+1);

Sends the raw data to the other tasks. The auxiliary data (the RCP name) is usually only used by the display task.



report("Checking for fit data.");

if ((f=get_fit(FITBUFFER_NAME,&fit_dt_buf)) !=frame_counter) {

sprintf(errbuf,"Received fit data block %d",f);

report(errbuf);

task_write_fit(ECHO_DATA,&fit_dt_buf,1);

frame_counter=f;

} else report("No fit data waiting.");

Check whether any fitted data has arrived from the fitacf task, if it has then it is passed on to echo_data to be forwarded to its clients.

report("Checking for user interrupt.");

exit_poll=user_interrupt();

The site.c function user interrupt calls the library function user_int to check whether the scheduler has requested that the RCP stop or the user has changed any parameters using the alter task.

set_vars(&raw_dt_buf);

Update the Radops parameter block with any altered parameters.



if (exit_poll !=0) break;

If the scheduler has requested that the RCP stop then exit the main loop and shutdown.



scan=0; /* not the start of the scan anymore */



/* Check to see if we are on END_BEAM and if we are

then set to END_BEAM-1 (unless SKIP_BEAM != ??? )

and do another scan with intt set to 2.

This should flush out the echo_data task of all

the data we want. */

if ((bmnum == end_beam) && (do_once == 0))

{

bmnum = end_beam -1; /* only from forward radars */

intt = 2;

do_once = 1;

scan = -32367;

}

If we have reached the end of the scan then do a dummy integration to flush the data for the last beam of the scan through fitacf. The value of -32367 in scan indicates that this is not a valid scan and should be ignored by processing and display software.



/* Zero the no_data array now that the first block of data

(which is not from this scan) have passed through

echo_data. */

if ((bmnum == start_beam+skip_beam) && (start_beam+skip_beam < 15))

{

nodata_task_put(&nodata_flag);

This function tells no_data to reset its scatter count. Here is it is used after the first beam of a scan, in order to clear out the scatter count from the last scan.

/* Zero the no_data arrays */

if (nodata_flag == 0)

fprintf(stderr,"Zeroed no_data task_put Status: %d\n",nodata_flag);

else

fprintf(stderr,"Error: no_data task_put Status: %d\n",nodata_flag);

}

} /* end of main scan loop */

report("End of scan.\n");



/* Call the no_data task to calculate the scatter count for the

above scan */

nodata_task_get(&scatter_count,&nodata_flag);

This function asks no_data for the scatter count. Here it gets the count for the full scan which has just been completed.

if (nodata_flag == 0)

{

fprintf(stderr,"Scan completed at frequency %d kHz\n",selectf);

fprintf(stderr,"With %d bins of data\n",scatter_count);

nodata_flag = -1;

}

else

fprintf(stderr,"Error no_data fault task_get Status: %d", nodata_flag);



/* Frequency search section */

/* Check the data from that last scan */

/* This always happens at the start of a two minute scan period */

/* get the time at the end of the scan */

If the scatter count is less than nodata_bin_threshold, which can be set by the user as a command line option, then the radar do a frequency search. If not then go on to the next scan.

if (scatter_count < nodata_bin_threshold)

{

/* make sure we're on a two minute boundary */

read_clock(&yr,&mon,&day,&hr,&min,&sec,&msec,&usec);

report("Waiting on two minute boundary.");

wait_boundary(2);



/* Zero the no_data arrays */

report("Starting no_data frequency search.");

nodata_count_max = 0;

intt = 5;

do_once = 0;



for (loop = 0; loop < number_freq; loop++)

Go through each of the frequencies defined in nodata_freq, integrating on beams 2, 6,10 and 14 and counting the scatter picked up.

{

for (bmnum = 2; bmnum <= 14; bmnum = bmnum + 4)

{

start_freq = nodata_freq[loop];

end_freq = start_freq+freq_range;

Set the start and end frequencies for the clear frequency search.



if (bmnum == 2)

scan = 1;

else

scan = 0;

Set the scan variable to indicate whether this is the start of a scan or not.



/* Set the radar parameter block up */

set_block(&raw_dt_buf);

set_time(&raw_dt_buf);

Copy the local parameter variables into the Radops parameter block.



sprintf(errbuf,"Frequency %d and Beam %d\n",start_freq,bmnum);

report(errbuf);

report("Performing fclr");

status=fclr(&raw_dt_buf,start_freq,end_freq,5);

Do the clear frequency search, as for a normal scan.



report("Performing integration");

if (status==0) status=radar(&raw_dt_buf);

The integration is carried out by calling the Radops library function radar directly, without using the site.c function integrate. This may be changed in future to make the RCP site-independent.



get_status(NULL,&raw_dt_buf,0);

#ifdef DEBUG

if (sim_file !=NULL) {

report("Loading simulated data.");

if (read_raw_data(sim_file,&raw_dt_buf) !=0) {

fclose(sim_file);

sim_file=fopen(SIM_FILE,"r");

}

}

#endif

Load the dummy data if in DEBUG mode.



/* send the raw data to the other tasks */

report("Sending raw data to tasks.");

task_write_raw(RAWWRITE,&raw_dt_buf,1);

task_write_raw(FITACF,&raw_dt_buf,1);

task_write_raw(ECHO_DATA,&raw_dt_buf,1);

task_write_aux(ECHO_DATA,prg_name,strlen(prg_name)+1);

Sends the raw data to the other tasks, as in the normal scan above.



report("Checking for fit data.");

if ((f=get_fit(FITBUFFER_NAME,&fit_dt_buf)) !=frame_counter) {

sprintf(errbuf,"Received fit data block %d",f);

report(errbuf);

task_write_fit(ECHO_DATA,&fit_dt_buf,1);

frame_counter=f;

} else report("No fit data waiting.");

Check whether there is any fitted data returned from fitacf. If there is then pass it on to echo_data for forwarding to its clients.



report("Checking for user interrupt.");

exit_poll=user_interrupt();

Check whether the user or scheduler has requested that the RCP stop. This function is in site.c and also takes care of passing relevant variables so that the alter task can access them.

/* there is a one beam lag on the scatter counts from no_data

* so wait until we've done this scan's beam 2 before asking for

* the count. */

if ((bmnum == 2) && (loop != 0))

{

If we have done the first beam of this frequency then the scatter count from the last beam of the previous frequency will be ready, ask for it and show the user the results. This is not carried out for the first beam of the first frequency, which is handled specially below.

/* Call the no_data task to calculate scatter */

nodata_task_get(&scatter_count,&nodata_flag);

if (nodata_flag == 0)

nodata_scatter_count[loop-1] = scatter_count;

else

fprintf(stderr,"Error: no_data fault task_get Status: %d\n",nodata_flag);

fprintf(stderr,"Searched frequency %d kHz ",nodata_freq[loop-1]);

fprintf(stderr,"and detected %d bins of data\n",nodata_scatter_count[loop-1]);

}

/* the last scan is a special case, it does an extra scan on

* beam 14 to flush through no_data. */

if ((bmnum == 14) && (loop == number_freq-1) && (do_once == 1))

{

If we have just done the last beam of the last frequency then we need to flush the scatter count out of no_data. This is done by performing an extra 2 second dummy integration on beam 14 (see below), here we pick up the count which has been flushed through by this dummy integration.

/* Call the no_data task to calculate scatter */

nodata_task_get(&scatter_count,&nodata_flag);

if (nodata_flag == 0)

nodata_scatter_count[loop] = scatter_count;

else

fprintf(stderr,"Error: no_data fault task_get Status: %d\n",nodata_flag);

fprintf(stderr,"Searched frequency %d kHz ",nodata_freq[loop]);

fprintf(stderr,"and detected %d bins of data\n",nodata_scatter_count[loop]);

}

if ((bmnum == 2) && (loop == 0))

{

This is the first beam of the first frequency, clear the no_data scatter count.

nodata_task_put(&nodata_flag);

/* Zero the nodata arrays */

if (nodata_flag == 0)

fprintf(stderr,"Zeroed the no_data task_put Status: %d\n",nodata_flag);

else

fprintf(stderr,"Error: no_data task_put Status: %d\n",nodata_flag);

}



if ((bmnum == 14) && (loop == number_freq-1) && (do_once == 0))

{

This is the code which causes the dummy scan to flush out the last of the frequency scan scatter counts. scan is set to -32367 to indicate that this scan should be ignored by data processing tasks.

intt = 2;

bmnum = 10;

do_once = 1;

scan = -32367;

}

} /* end of beam scan for loop */

} /* end of freq scan for loop */



/* scan through the array of frequencies and data counts looking for

* the largest count bigger than NODATA_MIN_DATA. If no frequency

* has enough data then we default to NODATA_DEFAULT_FREQ (chosen to

* minimise riometer noise when there is nothing happening anyway). */

nodata_count_max = NODATA_MIN_DATA;

We start by setting the nodata_count_max variable to NODATA_MIN_DATA the threshold below which the radar will stay on its default frequency. This means that the following code will look for frequencies with scatter counts higher than this value.

selectf=-1;

selectf is set to -1 to indicate whether a non-default frequency has been chosen.

for (loop = 0; loop < number_freq; loop++)

{

fprintf(stderr,"freq=%d kHz, data=%d bins.\n", nodata_freq[loop], nodata_scatter_count[loop]);

if(nodata_scatter_count[loop] > nodata_count_max)

{

If we find a frequency with a scatter count greater than nodata_count_max then set nodata_count_max to this new value and store the frequency in selectf.

nodata_count_max =nodata_scatter_count[loop];

selectf = nodata_freq[loop];

}

} /* end of loop for loop */



if (selectf==-1)

If selectf is -1 then there were no frequencies with more than NODATA_MIN_DATA bins of scatter. In this case we use the default frequency.

{

fprintf(stderr,"No frequency had more than %d bins of data.\n",NODATA_MIN_DATA);

fprintf(stderr,"Defaulting to %d kHz.\n",NODATA_DEFAULT_FREQ);

selectf=NODATA_DEFAULT_FREQ;

}

else

{

fprintf(stderr,"Selected frequency from search is %d kHz\n",selectf);

fprintf(stderr,"With %d bins of data\n",nodata_count_max);

}

} /* end of frequency search section */

report("Waiting on two minute boundary.");



exit_poll=user_interrupt();

if (exit_poll==0) {

read_clock(&yr,&mon,&day,&hr,&min,&sec,&msec,&usec);

wait_boundary(2);

}



} while (exit_poll==0);

If the variable exit_poll (the return value from the user_interrupt) is non-zero then the scheduler or user has requested that the RCP stop. It should now exit gracefully.



log_error(ERRLOG_NAME,"control","Shutdown detected.");

/* get the last outstanding record from fitacf*/



if ((f=get_fit(FITBUFFER_NAME,&fit_dt_buf)) !=frame_counter) {

There may still be fit data waiting to be collected from fitacf, if so then pick it up and pass it on to echo_data and its clients.

sprintf(errbuf,"Received fit data block %d",f);

report(errbuf);

task_write_fit(ECHO_DATA,&fit_dt_buf,1);

frame_counter=f;

} else report("No fit data waiting.");



/* close files and exit */

log_error(ERRLOG_NAME,"control","Closing data files.");

task_close(RAWWRITE,yr,mon,day,hr,min,sec);

task_close(FITACF,yr,mon,day,hr,min,sec);

task_close(ECHO_DATA,yr,mon,day,hr,min,sec);

Close all the data files.



log_error(ERRLOG_NAME,"control","Exiting control program.");

exit(0);

}





void nodata_task_put(int *status)

{

This function sends a message to no_data asking it to clear the scatter count. It returns a status value indicating whether the message was sent to no_data successfully.

void *smsg[2];

void *rmsg[2];

unsigned int sbytes;

unsigned int rbytes;

int dummy_status;

char msg;

msg = TASK_PUT;

smsg[0] = &msg;

smsg[1] = NULL;

rmsg[0] = &msg;

rmsg[1] = NULL;

sbytes = sizeof(char);

rbytes = sizeof(char);



//fprintf(stderr,"About to reset nodata array with message %c\n",msg);

dummy_status = message_array(NODATA,1.0,smsg,rmsg,&sbytes,&rbytes);

*status = dummy_status;

//fprintf(stderr,"Finished reseting the nodata array and got message %i\n",msg);

}



void nodata_task_get(long int *task_get_count, int *status)

{

This function sends a message to no_data requesting the scatter count. There is no return value.

void *smsg[2];

void *rmsg[3];

unsigned int sbytes[1];

unsigned int rbytes[2];

int dummy_status;

char msg;

long int dummy_count;

msg = TASK_GET;



smsg[0] = &msg;

smsg[1] = NULL;

rmsg[0] = &msg;

rmsg[1] = &dummy_count;

rmsg[2] = NULL;

sbytes[0] = sizeof(char);

rbytes[0] = sizeof(char);

rbytes[1] = sizeof(long int);



dummy_status = message_array(NODATA,1.0,smsg,rmsg,&sbytes,&rbytes);

*task_get_count = dummy_count;

*status = dummy_status;

}