Use of channel ("SNC" or "SNCL") structures and classes in Trinet Codes All paths are relative to the Trinet rt directory, as in /data/cvs01/lombard/Trinet/rt. There is one main channel class: Channel, in common/Channel.h, and one main channel structure: channel_definition_type, in gcda/chan.h. The Channel class is used in the `TriNet' codes. The channel_definition_type structure is used with some applications that connect to one or more gcda's. class Channel { private: public: char network[MAX_CHARS_IN_NETWORK_STRING]; char station[MAX_CHARS_IN_STATION_STRING]; char channel[MAX_CHARS_IN_CHANNEL_STRING]; char location[MAX_CHARS_IN_LOCATION_STRING]; // Added 6/9/03 char teltype; double samprate; double latitude; double longitude; double elevation; double gain; double mlcor; double mecor; ... } Several classes in common/ have Channel as a member object; there are no classes derived from Channel. The struct channel_definition_type is used with some of the gcda templates. It is NOT the key to the gcda, but a member of the Defined_Data_Channel_Reader template class. Thus it an application-local class member for programs that use the Defined_Data_Channel_Reader class for reading the gcda. struct channel_definition_type { char network[MAX_CHARS_IN_NETWORK_STRING]; char station[MAX_CHARS_IN_STATION_STRING]; char seed_channel[MAX_CHARS_IN_CHANNEL_STRING]; char telemetry_type[MAX_CHARS_IN_STATION_STRING]; /* Types are A or D */ float latitude; float longitude; float elevation; float sample_period; int instrument_type; // 0 = Broad band 1 = Strong Motion int valid_corrections; // 0 = False 1 = TRUE; float gain_factor; float ml_correction; float me_correction; }; Another structure is used as the key to the gcda: struct Channel_Header { char station[CHARS_IN_CHANNEL_HEADER_STRING]; char channel[CHARS_IN_CHANNEL_HEADER_STRING]; float samples_per_second; unsigned int seconds_in_memory; unsigned int channel_samples_in_memory; unsigned int offset_to_first_sample; unsigned int offset_to_last_sample; unsigned int position_of_newest_sample; unsigned int position_of_oldest_sample; timeval time_of_newest_sample; timeval time_of_oldest_sample; unsigned int offset_to_first_validity_flag; }; Within this structure, station and channel are the strings searched by gcda clients to fined the desired segment of the gcda. Note that both network and location codes are missing from thei structure. Template Classes used in the gcda's: dchan.h: template class Data_Channel Semaphores channel_sem; char config_file_name[MAX_CHARS_IN_FILE_NAME]; char* start_of_memmap; Channel_Header* this_channel_header; int p_debug; dwriter.h: template class Data_Channel_Writer: public Data_Channel int p_debug; dreader.h: template class Data_Channel_Reader: public Data_Channel int p_first_time_through_get_next_sample; timeval p_timeval_of_last_processed_sample; timeval p_timeval_of_last_new_sample_read; unsigned int p_position_of_last_sample_for_channel(); int p_debug; ddcr.h: template class Defined_Data_Channel_Reader: public Data_Channel_Reader struct channel_definition_type p_channel_def; unsigned int p_usec_per_sample; int p_debug; Connection between channel_definition_type structure and Channel class The gcda's form a barrier for SNCL data between gcda writers and readers. The gcda creator programs set the station and channel fields in the Channel_Header structures of the gcda. Gcda writers attach to segments of the gcda by searching for the desired station and channel when the application starts up. The segment location is cached in the application, so the station and channel fields do not have to be touched again during the life of the writer. Gcda readers attach to gcda segments in the same manner, by searching for station and channel in the Channel_Header structures of the gcda. Those gcda readers that use the Defined_Data_Channel_Reader class will fill in the channel_definition_type structure at startup. Since this structure is a member of the Defined_Data_Channel_Reader object, the structure fields are available to hte application during its lifetime. Most gcda applications are part of the TriNet codes. Exceptions include rad, evtdetect and rtr, which were written before TriNet by Phil Maechling. These three are gcda `bridge' programs: they read from one gcda and write to another gcda, but otherwise theu don't communicate with otehr programs. The TriNet codes that access the gcda's using the Defined_Data_Channel_Reader class need to map information from channel_definition_type structures to Channel objects. Trimag provides an example of how this is done. In Trimag.C, the method _LoadChannels fills in a ChannelConfigList from the database. // Definition of a list of a configured channels typedef std::map, std::allocator > > ChannelConfigList; (Ignore the ChannelConfig part of this map for this discussion; it isn't used here.) Then _LoadChannels has: // Create ADA for each channel for (clp = configchans.begin(); clp != configchans.end(); clp++) { chan = (*clp).first; retval = ar.Initialize_Defined_Channel(ada->Start_of_Memory_Area(), chan.station, chan.channel, tridefsfile); chan.samprate = (1.0 / ar.get_sample_period()); if (retval != TN_SUCCESS) { sm.ErrorMessage(Compat::Form("(Trimag::_LoadChannels): Unable to initializ e channel reader for %s %s %s", chan.network, chan.station, chan.channel)); } else { chans.insert(ChanReaderMap::value_type(chan, ar)); } } Here we iterate through the ChannelConfigList, using Channel.station and Channel.chanel to find the gcda segment. The channel_definition_type structure is filled in by reading the tridefsfile passed to Initialize_Defined_Channel. The Channel.samprate must be taken from the AmpReader `ar', because the samplerate of the ada is different than the CHannel samplerate stored in the database. Then the AmpReader `ar' is mapped to the Channel in the ChanReaderMap `chans'. Thus with the exception of samplerate, the channel_definition_type structure is not used in trimag. Ampgen handles this structure in a similar way. But I don't think this can be generalized to all gcda clients.