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;

}