function qwritetriggers(triggers, fileNames, fieldNames, formatType) % QWRITETRIGGERS Write significant tiles properties to a trigger files % % QWRITETRIGGERS writes the specified properties of significant tiles to the % specified trigger files. Subsequent calls to QWRITETRIGGERS can be used to % append new tile properties to an existing files. QWRITETRIGGERS can write % results in both TXT and XML formats. % % usage: qwritetriggers(triggers, fileNames, fieldNames, formatType); % % triggers cell array of significant tile properties % fileNames cell array of file names to append triggers to % fieldNames cell array of strings of field names to include % formatType format type ('txt' or 'xml') of trigger file % % QWRITETRIGGERS expects a cell array of trigger structures with one cell per % channel as returned by qthreshold or qselect. The triggers structure must % contain the following fields, which describe the properties of statistically % significant tiles. Additional optional fields such as amplitude, phase, or % coherent transform properties may also be specified. % % time center time of tile [gps seconds] % frequency center frequency of tile [Hz] % duration duration of tile [seconds] % bandwidth bandwidth of tile [Hz] % normalizedEnergy normalized energy of tile [] % % The field names argument is a cell array of property field names to write % to the file. A field name that does not exist in the trigger structure % will be recorded as zeros in the resulting file. % % See also QPIPELINE, QEVENT, QTRANSFORM, QTHREHSOLD, and QSELECT. % Leo C. Stein % lstein@ligo.caltech.edu % Shourov K. Chatterji % shourov@ligo.caltech.edu % $Id: qwritetriggers.m,v 1.7 2007/05/01 20:33:52 shourov Exp $ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % process command line arguments % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % verify correct number of input arguments error(nargchk(3, 5, nargin)); % apply default arguments if (nargin < 4) || isempty(fieldNames), fieldNames = {'time', 'frequency', 'duration', 'bandwidth', ... 'normalizedEnergy'}; end if (nargin < 5) || isempty(formatType), formatType = 'unspecified'; end % force cell arrays if ~iscell(triggers), triggers = mat2cell(triggers, size(triggers, 1), size(triggers, 2)); end if ~iscell(fileNames), fileNames = mat2cell(fileNames, size(fileNames, 1), size(fileNames, 2)); end % force one dimensional cell arrays triggers = triggers(:); fileNames = fileNames(:); % determine number of channels numberOfChannels = length(triggers); % determine number of field names numberOfFields = length(fieldNames); % force lower case format type formatType = lower(formatType); % default format type if strcmp(formatType, 'unspecified'), if strcmp(fileNames{1}(end - 3 : end), '.xml') formatType = 'xml'; else formatType = 'txt'; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % validate command line arguments % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % validate number of file names if length(fileNames) ~= numberOfChannels, error('number of fileNames is inconsistent with number of channels'); end % validate triggers structures for channelNumber = 1 : numberOfChannels, if ~strcmp(triggers{channelNumber}.id, ... 'Discrete Q-transform event structure'), error('input argument is not a discrete Q transform event structure'); end end % validate format type if ~ismember(formatType, {'txt', 'xml'}), error(['unknown format type "' formatType '"']); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % file format details % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % string for invalid fields invalidFieldString = '0'; % define field separator character switch formatType, case 'txt', fieldDelimiter = ' '; case 'xml', fieldDelimiter = ','; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % begin loop over channels % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % begin loop over channels for channelNumber = 1 : numberOfChannels, %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % open file % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % extract file name fileName = fileNames{channelNumber}; % check if the file already exists writeHeaderFlag = ~exist(fileName, 'file'); % open file for appending fileDescriptor = fopen(fileName, 'a'); % check for error opening file if fileDescriptor == -1, error(['cannot open file "' fileName '" for appending']); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % write header information % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % if file is newly created if writeHeaderFlag, % switch on format type switch formatType % handle txt format case 'txt', % write field names for fieldNumber = 1 : numberOfFields, fprintf(fileDescriptor,'%% %s\n', fieldNames{fieldNumber}); end % handle xml format case 'xml', % write beginning of header fprintf(fileDescriptor, ... '\n'); fprintf(fileDescriptor, ... '\n'); fprintf(fileDescriptor, ... '\n'); % write field names for fieldNumber = 1 : numberOfFields, fprintf(fileDescriptor, ... '\n', ... fieldNames{fieldNumber}); end % write end of header fprintf(fileDescriptor, ... '\n'); % end switch of format type end % end test for newly created file end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % construct format string % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % initialize format string formatString = ''; % begin loop over field names for fieldNumber = 1 : numberOfFields, % extract field name fieldName = fieldNames{fieldNumber}; % test for availability of field if ~isfield(triggers{channelNumber}, fieldName), formatString = [formatString invalidFieldString fieldDelimiter]; continue; end % set field format based on field name switch fieldName, case 'time', formatString = [formatString '%#019.9f' fieldDelimiter]; otherwise, formatString = [formatString '%#09.3e' fieldDelimiter]; end % end loop over field names end % remove trailing delimiter and end newline formatString = [formatString(1 : end - 1) '\n']; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % construct data matrix % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % determine number of triggers numberOfTriggers = length(triggers{channelNumber}.time); % initialize data matrix data = []; % begin loop over field names for fieldNumber = 1 : numberOfFields, % extract field name fieldName = fieldNames{fieldNumber}; % test for field availability if ~isfield(triggers{channelNumber}, fieldName), continue; end % add field to data matrix data = [data; ... reshape(triggers{channelNumber}.(fieldName), 1, numberOfTriggers);]; % end loop over field names end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % write triggers to file % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % write triggers to file fprintf(fileDescriptor, formatString, data); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % close file % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % close file fclose(fileDescriptor); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % end loop over channels % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % end loop over channels end