Trace data handling

Traces are implemented as objects of class TRACE that are always accessed via pointers.  The reason for using pointers is in allowing easy shuffling of the traces and passing them from one processing module to another without copying large segments of memory.  In a processing module, therefore, traces are typically defined as something like this:

TRACE *t;

Throughout processing, traces may change in their types, lengths, and other parameters. A TRACE may include several "records" (typically, 1) each of which represents an array of the same type (again, typically the type is DATA_SAMPLE), and a binary "trace header" of arbitrary length consisting of a number of named fields of various formats.  Class TRACE has many methods for accessing the parameters that are important for application programming:

t->num_samples();	// int - the number of samples
t->time_start();	// time of the first sample
t->sample_interval();	// trace sampling interval
t->type();		// TRACE_DATA_FORMAT - the type of the trace
t->num_records();	// the number of data records in the trace
t->data_start();	// DATA_SAMPLE* - pointer to the first data sample
t->data_start( int n );	// DATA_SAMPLE* - pointer to the beginning of the n-th
			// data record, if present 
t->data_length();	// int - the total length of the trace data record, in bytes
t->header;		// byte* - trace header; note that this 
			// is not an accessor method but the header record itself
t->ensemble;		// ENSEMBLE* - pointer to an ensemble to which the trace belongs
t->next, t->pred;	// TRACE* - pointers to the preceding and next traces within the
			// same ensemble
t->next_trace();	// TRACE* - pointer to the next trace, possibly across 
			// the ensemble boundaries
 

In simple processing, there is typically no need to create traces. A processing tool always has an access to the "input" and "output" gathers and pass traces from the input to the output.  Thus, a typical way to access a trace that is being passed to the output looks like this:

 

TRACE *t = SIA_pass_trace(input,output);

The call above transfers the trace to the output and allows its processing while in the output gather.  If we still want to add a trace to the output gather without moving it from the input, we create it like this:

TRACE *t = output->add_ensemble()->add_trace();

Here, we create an ensemble with a single trace in it.  If we want to add trace to the last ensemble in the output, we write:

TRACE *t = output->last_ensemble->add_trace();

Before using this call, however, we need to make sure that this last_ensemble exists (not equal NULL).  

The two calls above create traces that are formatted (have type, length, etc.) as specified by the parameters of the parent GATHER (i.e, output in the examples above).  To create a trace formatted as another trace, use another add_trace() method:

TRACE   *t0 = ...    // assume that we have some trace, e.g., in the input gather
TRACE 	*t = output->last_ensemble->add_trace(t0);

There are methods to create trace of a specified type, numbers of samples and records:

ENSEMBLE	*e = ..		// assume we have some ensemble
TRACE 		*t1 = e->add_trace(type,num_samples);
TRACE 		*t2 = e->add_trace(type,num_records,num_samples);

Note that we normally do not use the simple default constructor to create traces 

TRACE *t = new TRACE;

Although the call above is possible and may seem appealing, it is not easy to tell from it to which ensemble the trace belongs, what is its sample interval, etc. Such initializations are thus discouraged in application programming.

To delete a trace gracefully (to delete all of its links, deallocate its memory and to update the parent ensemble) , use simply:

delete t;

Other useful methods of class TRACE:

TRACE *t, *t1;
 
//	let us assume traces t and t1 are somehow created ...
 
t->copy_data(t1);	// copy data from t1, this may involve data type conversions
t->copy_header(t1);	// copy the header from t1 
t->copy();		// copy everything from t1
t->convert(new_type);   // convert the trace to a new representation, 
			// e.g., into a spectrum or a complex trace