[27-FEB-25] The Neuroplayer Tool is a component in our LWDAQ program that manages display, processing, analysis, and translation of telemetry archives. Here we provide a complete list of the routines defined by the tool's TclTk script, along with comments extracted automatically from the script. These commands are all available to processing scripts, so they may be used for custom signal conditioning and export processors.
proc Neuroclassifier_add {{index ""} {event ""}}
Neuroclassifier_add adds an event to the event list. If the event is empty, the routine composes the event from the displayed play interval, and so adds the displayed interval to the event list. In doing so, the routine also jumps to the interval so as to set the characteristics of the event. The index we pass to the routine tells it how to tag the buttons in the event line.
proc Neuroclassifier_back {}
No description available.
proc Neuroclassifier_batch_classification {{state "Start"}}
Neuroclassifier_batch_classification selects one or more characteristics files and goes through them comparing each interval to the classifier events. It does this for the channels specified in the channel select string in the main Neuroplayer window. The result is a text window containing a list of events that we can cut and paste into a file.
proc Neuroclassifier_change {event}
Neuroclassifier_change finds an event in the text window and changes its event type. It then re-plots the event in the map.
proc Neuroclassifier_classify {metrics setup}
Neuroclassifier_classify finds the event in a classifier library that is the best match to one with the metrics provided. The routine assumes the existence of a list of classifier events called classifier_library in the scope of the calling routine. It returns the closest event in a string. It also sets the global classifier match parameter, which gives the distance of the closest library point. With setup set to 1, the routine sets up the lwdaq nearest neighbor routine by passing the classifier library metrics into the routine. Subsequent calls to the routine will use the previously established library.
proc Neuroclassifier_compare {}
Neuroclassifier_compare goes through the event list and measures the distance between every pair of events of differing types, and compares this distance to the match limit. If the distance is less, the Classifier prints the pair of events to the Neuroplayer text window as a pair of potentially-contradictory events.
proc Neuroclassifier_continue {}
No description available.
proc Neuroclassifier_display {event_list}
Neuroclassifier_display writes an entire event list to the classifier text window and plots the events on the map.
proc Neuroclassifier_event {event}
Neuroclassifier_event takes the file name, file time, and channel number of an event and looks for it in the Classifier text window. It returns the event as it appears in the text window, or returns the event it was passed otherwise.
proc Neuroclassifier_event_list {}
Neuroclassifier_event_list extracts an event list from the text window.
proc Neuroclassifier_jump {event}
Neuroclassifier_jump jumps to an event. It selects the event in the Classifier window, then calls the Neuroplayer's jump routine to navigate to the event.
proc Neuroclassifier_load {{name ""}}
Neuroclassifier_load reads an event list from a text file into the Classifier's text window. If no file is passed to the routine, it opens a file browser.
proc Neuroclassifier_metric_display {}
Neuroclassifier_metric_display sets up the x-y plot menus so they each contain all the metrics in the classifier_metrics list, and makes a checkbutton for each metric to enable or disable the metric for classification.
proc Neuroclassifier_open {}
No description available.
proc Neuroclassifier_plot {tag event}
Neuroclassifier_plot takes an event and plots it at a point in the map given by the x and y metrics selected by the user. These metrics come from the characteristics provided with the event string. The color of the point on the map is given by the list of event types and colors in the Classifier types parameter. The relationship between the names of metrics and their location in the characteristics is given by the Classifier metrics parameters. Point (0,0) is the lower-left corner of the map. Point (1,1) is the upper-right corner. The tag allows the routine to tag the point it plots. If the tag is "displayed", we plot the point as a white square with tag "displayed" and "event". Otherwise, the routine deletes all points with tag $tag and plots the new point with the event type color.
proc Neuroclassifier_processing {characteristics}
Neuroclassifier_processing accepts a characteristics line as input. If there are mutliple channels recorded in this line, the routine separates the characteristics of each channel and forms a list of events, one for each channel. It searches the event library for each event, in case the event is a repeat of one that already exists in the library. If so, it hilites the event in the library and makes it visible in the text window. Otherwise, the routine checks to see if the event qualifies as unusual. The first metric should be greater than the classifier threshold. If the event is unusual, the routine finds the closest match to the event in the library and classifies the event as being of the same type. In either case, the routine plots the characteristics of the event upon the map. In the special case where we are re-processing the event libarary to obtain new metrics, the routine replaces the existing baseline power and metrics for each library event with the newly-calculated values from the processor.
proc Neuroclassifier_refresh {}
Neuroclassifier_refresh extracts the event list from the text window, then calls the list command to re-write the text window and re-plot the map.
proc Neuroclassifier_reprocess {{index 0}}
Neuroclassifier_reprocess goes through the events in the text window and re-processes each of them so as to replace the old characteristics with those generated by the Neuroplayer's current processor script. Before reprocessing, the routine sorts the events by event type, so that in the new library, all events of the same type will be grouped together.
proc Neuroclassifier_save {{name ""}}
Neuroclassifier_save saves the events listed in the Classifier test window to a file, and refreshes the text window and map. If no file is passed to the routine, it opens a file browser.
proc Neuroclassifier_select {event}
Neuroclassifier_select hilites and event in the text window.
proc Neuroclassifier_sigmoidal {x center exponent}
Neuroclassifier_sigmoidal takes a value greater than zero and returns a value between zero and one. It takes as parameters a center and an exponent for its sigmoidal function. The result is formatted to three decimal places.
proc Neuroclassifier_step {}
No description available.
proc Neuroclassifier_stop {}
Neuroclassifier_stop puts a stop to all reprocessing events by unsetting the event list, and stops playback as well.
proc Neuroexporter_edf_read {}
Neuroexporter_edf_read reads the header of an EDF file and fills the EDF setup array and composes a new channel selector string from the channels and sample rates in the EDF file. It does not read any data from the file.
proc Neuroexporter_edf_rewrite {}
Neuroexporter_edf_rewrite rewrites the EDF headers of one or more EDF files. All entries in the EDF files will be re-written except for the date, time, and the signal names. We use this routine to select one or more files and re-write the description of the signals.
proc Neuroexporter_edf_setup {}
No description available.
proc Neuroexporter_export {{cmd "Start"}}
Neuroexporter_export manages the exporting of recorded signals to files, tracker signals to files, and the creation of simultaneous video to concatinated video files that match the export intervals. It takes one of the commands "Start", "Abort", "Play", "Video", and "Repeat". The default is "Start".
proc Neuroexporter_open {}
Neuroexporter_open creates the Export Panel, or raises it to the top for viewing if it already exists. Once an export has started, we can close the export window, so this routine might be re-opening the panel while the Exporter is open. If the Exporter is Idle, this routine, reloads the current archive file, so that it can set the export start time to equal the archive start time. This graphical routine calls exporter routines that are defined below it.
proc Neuroexporter_set_start {where {report 1}}
Neuroexporter_set_start sets the start time of the export to the beginning of the current interval or the beginning of the current archive, depending upon whether we pass the keyword "Interval", "Archive", or "Step".
proc Neuroexporter_txt_save {w}
Neuroexporter_txt_save transfers the contents of the exporter's TXT setup window into the TXT header variable. White space is removed by the routine before storing in the variable. The header will be written to to export files only if it is not empty. If it is written, it will be written with a carriage return at the end.
proc Neuroexporter_txt_setup {}
Neuroexporter_txt_setup opens a panel in which we can create a text header that will be written to the start of a text export file.
proc Neuroplayer_activity {}
No description available.
proc Neuroplayer_autofill {}
Neuroplayer_autofill fills the channel select field with the Neuroplayer's best guess as to all the channels that are active in the most recently-played interval. We report the outcome of the autofill to the export panel and the main Neuroplayer window.
proc Neuroplayer_band_amplitude {band_lo band_hi {show 0} {replace 0}}
Neuroplayer_band_amplitude calls Neuroplayer_band_power and converts the power into a standard deviation of the signal, which is the root mean square amplitude.
proc Neuroplayer_band_power {band_lo band_hi {show 0} {replace 0}}
Neuroplayer_band_power is for use in processor scripts as a means of detecting events in a signal. The routine selects the frequency components in info(spectrum) that lie between band_lo and band_hi Hertz (inclusive), adds the power of all components in this band, and returns the total. If show is set, the routine plots the filtered signal on the screen by taking the inverse transform of the selected frequency components. If replace is set, the routine calculates the inverse transform of the filtered signal, making it available to the calling routine in the info(values) variable. Note that the routine does not change info(signal), which contains the reconstructed signal values and their timestamps, nor the spectrum of the signal. By default, the routine does not plot nor does it perform the inverse transform, both of which take time and slow down processing. The show parameter, if not zero, is used to scale the signal for display.
proc Neuroplayer_baseline_reset {}
Neuroplayer_baseline_reset sets all the baseline power values to the reset value, which is supposed to be so high that no channel will have a baseline power exceeding it.
proc Neuroplayer_baselines_read {name}
Neuroplayer_baselines_read looks at the metadata of the current playback archive and looks for a baseline power string with the name given by the config(bp_name) string. It reads any such baseline powers it finds into the baseline power array.
proc Neuroplayer_baselines_set {}
Neuroplayer_baselines_set sets all the baseline power values to the bp_set value.
proc Neuroplayer_baselines_write {name}
Neuroplayer_baselines_write takes the existing baseline power values and saves them as baseline power string in the metadata of the current playback file, with the name specified in the config(bp_name) parameter. The routine does not write baseline powers that meet or exceed the reset value, because these are not valid.
proc Neuroplayer_calibration {{name ""}}
Neuroplayer_calibration allows us to view and edit the global baseline power values used by some processors to produce interval characteristics that are independent of the sensitivity of the sensor. The processor can use these global variables to keep track of a "baseline" power value by which other power measurements may be divided to obtain a normalised power measurement. We can save the baseline power values to the metadata of an NDF file, or load them from the metadata.
proc Neuroplayer_clock {}
Neuroplayer_clock opens the Clock Panel, or raises it to the top for viewing if it already exists.
proc Neuroplayer_clock_convert {datetime}
Neuroplayer_clock_convert converts between integer seconds and the datetime format given in the configuration array. If the input is in integer seconds, it gets converted into our datetime format. If the input is in the datetime format, it gets converted into integer seconds. If the format is incorrect, we return the value zero.
proc Neuroplayer_clock_jump {}
Neuroplayer_clock_jump constructs a datetime event string and instructs the Neuroplayer to jump to an archive containing the datetime specified by the user in the datetime window. If such an archive does not exist, the jump routine will issue an error.
proc Neuroplayer_clock_update {}
Neuroplayer_clock_update always updates the playback datetime, and if necessary updates the archive start datetime.
proc Neuroplayer_close {}
Neuroplayer_close closes the Neuroplayer and deletes its configuration and info arrays.
proc Neuroplayer_color {id}
Neuroplayer_color returns a color code that is equal to the identifier it is passed, unless there is a color switch value in the color table.
proc Neuroplayer_color_swap {id w e x y}
Neuroplayer_color_swap uses mouse events to switch the display colors.
proc Neuroplayer_command {action}
Neuroplayer_command handles the various control commands generated by the play buttons. It refers to the LWDAQ event queue with the global queue_events variable. The routine is designed to execute immediately and instantly, so it does not do anything other than set up futuer actions on the queue.
proc Neuroplayer_configure {}
Neuroplayer_configure calls the standard LWDAQ tool configuration routine to produce a window with an array of configuration parameters that the user can edit.
proc Neuroplayer_contiguous_band_power {flo fhi num}
Neuroplayer_contiguous_band_power accepts a low and high frequency to define a range of frequencies to be analyzed, and then a number of contiguous bands into which to divide that range. It returns the power of the signal in each band in units of square counts.
proc Neuroplayer_draw_graphs {}
Neuroplayer_draw_graphs draws the vt and af graphs in the two view windows in the Neuroplayer, and in the separate view windows, if they exist.
proc Neuroplayer_end_time {fn payload {ref_time 0} {ref_index 0}}
Neuroplayer_end_time determines the time interval spanned by a file. It calls Neuroplayer_seek_time with value -1 to obtain the length of the archive. We curtail the end time to two decimal places in order to avoid display problems for archives that have unusual end times as a result of data loss during recording.
proc Neuroplayer_filter {band_lo_end band_lo_center band_hi_center band_hi_end {show 0} {replace 0} {bandpass 1}}
Neuroplayer_filter is for use in processor scripts as a means of detecting events in a signal. The routine scales the amplitude of the discrete transform components according to four numbers, which specify the central region of the pass-band and the two extremes of the pass-band. The scaling is linear, which is not something we can do easily with recursive filters, or with analog filters, but is simple in software. The four numbers are band_lo_end, band_lo_center, band_hi_center, and band_hi_end. They are in units of frequency. Components below band_lo_end and above band_hi_end are multiplied by zero. Components between band_lo_end and band_lo_center are scaled by zero to one from the lower to the upper frequency. Components from band_lo_center to band_hi_center are added as they are. Components from band_hi_center to band_hi_end are scaled from one to zero from the lower to the upper frequency. Thus we have a pass-band that might be sharp or gentle. We can implement a high-pass filter by setting band_lo_end and band_lo_center to zero. The routine returns the total power of the remaining components, which is the sum of their squares. We do not multiply the combined power by any scaling factor because there are several variants of the discrete fourier transform with different scaling factors, and we want to avoid hiding such multiplications in our code. If "show" is set, the routine plots the filtered signal on the screen by taking the inverse transform of the selected frequency components. If "replace" is set, the routine calculates the inverse transform of the filtered signal, making it available to the calling routine in the info(values) variable. Note that the routine does not replace the info(signal) string, which contains the reconstructed signal values and their timestamps. Only the info(values) string is replaced. By default, the routine does not plot nor does it perform the inverse transform, both of which take time and slow down processing. The show parameter, if not zero, is used to scale the signal for display. By default the filter is band-pass. But if we set "bandpass" to 0, the filter is a band-stop filter.
proc Neuroplayer_frequency_reset {}
Neuroplayer_frequency_reset sets all the frequency and frequency alerts to zero and N.
proc Neuroplayer_fresh_graphs {{clear_screen 0}}
Neuroplayer_fresh_graphs clears the graph images in memory. If you pass it a "1" as a parameter, it will clear the graphs from the screen as well. It calls lwdaq_graph to create an empty graph in the overlay area of the graph images, and lwdaq_draw to draw the empty graph on the screen.
proc Neuroplayer_init {}
Neuroplayer_init creates the info and config arrays and the images the Neuroplayer uses to hold data in memory. The config array is available through the Config button but the info array is private.
proc Neuroplayer_jump {{event ""} {verbose 1}}
Neuroplayer_jump displays an event. We can pass the event directly to the routine, or we can a keyword that directs the routine to select an event from an event list, or to move to the archive preceeding or following the current playback archive. An event list is a file on disk. Each line in such a file must itself be an event. And event is a list of values. The first two elements in the list give the location of the event. The location can be specified with a file name and an file time in seconds from the file start, or as an absolute date-time string and an offset in seconds from that time. The third element in the list is a selection string, which lists the channel numbers involved in the event. If the selection string is a list of numbers, the jump routine sets the Player's select string to the event selection string. If the selection string is "*", the Player's channel select string will be set to "*" and all channels will be selected after the jump. If the string is "?", the Player's channel select string will be left unchanged. We can suppress the alteration of the Player's select string by setting the Neuroplayer configuration parameter "isolate_events" to 0. If, instead of an event string composed of event elements, we pass one of the keywords "Back", "Go", "Step", "Hop", "Play", or "Stop" the routine will read the current event list from disk and select one of its events for display, just as if this event were passed to the jump routine. The Back, Go, and Step keywords instruct the jump routine to decrement, leave unaltered, or increment the Neuroplayer's event_index. The Hop keyword instructs the jump routine to select an event at random from the list, by setting the event_index to a random number between one and the event list length. We use the Hop instruction to move at random in large event lists to perform random sampling for confirmation of effective event classification. The Play instruction causes the Neuroplayer to move through the event list, displaying each event as fast as it can. The Stop instruction stops the Play instruction but does nothing else. The jump routine will set the baseline powers in preparation for display and processing, according to the jump_strategy parameter. If this is "local" we use the current baseline powers, if "read" we read them from the archive metadata using the baseline power name in the Baselines Panel. If it is "event" we assume the fourth element in the event list is a keyword describing the event and the fifth element is the baseline power we should apply to the selected channels. Another option is "verbose", which if set to zero, suppresses the event description printout in the Neuroplayer text window. The "Next_NDF", "Current_NDF", "Previous_NDF" keywords jump to the start of the next, current, or previous NDF files in the alphabetical list of archives in the playback directory tree.
proc Neuroplayer_list {{index 0} {fl ""}}
Neuroplayer_list prints a list of NDF files and their metadata comments. The routine takes as input a list of files. If the list is empty, it asks the user to select the files to list. The list contains links to open an archive in the Player, to open in the overview window, and to edit metadata.
proc Neuroplayer_magnified_view {figure}
Neuroplayer_magnified_view opens a new window with a larger, or at lease separate, plot of the voltage-time or amplitude-frequency graph. The size of the window is set by the vt_view_zoom and af_view_zoom parameters.
proc Neuroplayer_metadata_view {fn}
Neuroplayer_metadata_view reads the metadata from an NDF file called $fn and displays the metadata string in a metadata viewing panel. You can edit the string and save it to the same file with a Save button.
proc Neuroplayer_metadata_write {w fn}
Neuroplayer_metadata_write writes the contents of a text window, which is $w.text, into the metadata of a file $fn. We use this procedure in the Save button of the metadata display window.
proc Neuroplayer_multi_band_filter {{band_list ""} {show 0} {replace 0}}
Neuroplayer_multi_band_filter allows us to specify ranges of frequency to be included in the filtered signal. The routine returns the sum of the squares of the selected components. The "band_list" parameter is a list containing an even number of real-valued frequencies. Each pair of frequencies is the lowest and highest frequency of a band. The lowest must be specified first. The bands may overlap. Any component in the discrete fourier transform that lies within one or more of these bands will be included in the spectrum of the filtered signal. The band edges are themselves contained in the band, so a 1-4 Hz band will include components of 1 Hz and 4 Hz. When "replace" is set, the routine calculates the inverse fourier transform of the selected components and replaces the original info(values) string with the filtered signal values. But the info(signal) and info(spectrum) are not changed. If a processor is to change info(signal), it can replace all the sample values in info(signal) with the sample values in info(values).
proc Neuroplayer_open {}
Neuroplayer_open creates the Neuroplayer window, with all its buttons, boxes, and displays. It uses routines from the TK library to make the frames and widgets. To make sense of what the procedure is doing, look at the features in the Neuroplayer from top-left to bottom right. That's the order in which we create them in the code. Frames enclose rows of buttons, labels, and entry boxes. The images are TK "photos" associated with label widgets. The last thing to go into the Neuroplayer panel is its text window.
proc Neuroplayer_overview {{fn ""} }
Neuroplayer_overview displays an overview of a file's contents. This routine sets up the overview window and calles a plot routine to sample the archvie and plot the results. An Export button provides a way to export the graph data to disk for plotting in other programs.
proc Neuroplayer_overview_cursor {}
Neuroplayer_overview_cursor draws a vertical line over the plot to show the start of the current playback interval, assuming the file displayed is the current play file.
proc Neuroplayer_overview_excerpt {}
Neuroplayer_overview_excerpt extracts the overview time interval and writes it to disk as a newly-created NDF file, including all channels. This new archive will be written to a file Xt.ndf in the same directory as the original archive, where "X" is the letter X to begin the file name and "t" is the UNIX time taken from the original archive name. The new archive's metadata will include a comment giving the original file name and the time period extracted.
proc Neuroplayer_overview_jump {x y}
Neuroplayer_overview_jump jumps to the point in the overview archive that lies under the coordinates (x,y) in the overview graph. We call it after a mouse double-click in the graph. We round the jump-to time to the nearest second so that accompanying synchronous video will have a key frame to show at the start of the interval.
proc Neuroplayer_overview_newndf {step}
Neuroplayer_overview_newndf finds the file that is the one $step places after the overview file in the Player Directory Tree, switches the overview to the new file, and plots its contents.
proc Neuroplayer_overview_plot {}
Neuroplayer_overview_plot selects an existing overview window and re-plots its graphs using the current display parameters.
proc Neuroplayer_pick {name {post 0}}
Neuroplayer_pick allows the user to pick a new play_file, processor_file, event_file, play_dir, or video_dir. In the special case of the video_dir we clear the video file cache when we select a new video directory.
proc Neuroplayer_play {{command ""}}
Neuroplayer_play manages the play-back and processing of signals from archive files. We start by checking the block of messages in the buffer_image. We read messages out of the play-back archive until it has enough clock messages to span play_interval seconds. Sometimes, the block of messages we read will be many times larger than necessary. We extract from the buffer_image exactly the correct number of messages to span the play_interval and put these in the data_image. We go through the channels string and make a list of channels we want to process. For each of these channels, in the order they appear in the channels string, we apply extraction, reconstruction, transformation, and processing to the data image. If requested by the user, we read a processor_file off disk and apply it in turn to the signal and spectrum we obtained for each channel. We store the results of processing to disk in a text file and print them to the text window also. If we don't specify a command, the Neuroplayer continues with the action indicated by its control variable. But we can specify any of the following commands: Play, Step, Repeat, Back, Pick, PickDir, First, Last, and Reload.
proc Neuroplayer_play_time_format {play_time}
Neuroplayer_play_time_format stops the play time from becoming corrupted by rounding errors, and makes sure that there is always one number after the decimal point, while at the same time dropping unecessary trailing zeros.
proc Neuroplayer_plot_signal {{color ""} {signal ""}}
Neuroplayer_plot_signal plots a signal in off-screen drawing area, which is called vt_image. The procedure does not draw the graph on the screen. We leave the drawing until all the signals have been plotted in the vt_image overlay by successive calls to this procedure. For more information about lwdaw_graph, see the LWDAQ Command Reference. If we don't pass a signal to the routine, it uses $info(signal). The signal string must be a list of time and sample values "t v ". If we don't specify a color, the routine uses the info(channel_num) as the color code. If we don't specify a signal, the routine uses the $info(signal).
proc Neuroplayer_plot_spectrum {{color ""} {spectrum ""}}
Neuroplayer_plot_spectrum plots a spectrum in the af_image overlay, but does not display the plot on the screen. The actual display will take place later, for all channels at once, to save time. If you don't pass a spectrum to the routine, it will plot $info(spectrum). Each spectrum point must be in the format "f a ", where f is frequency in Hertz and a is amplitude in ADC counts. If we don't specify a color for the plot, the routine uses the channel number. If we don't specify a spectrum, it uses $info(spectrum).
proc Neuroplayer_plot_values {{color ""} {values ""}}
Neuroplayer_plot_values takes a list of values and plots them in the value versus time display as if they were evenly-spaced samples. The routine is identical to Neuroplayer_plot_signal except that we don't have to pass it a string of x-y values, only the y-values. We pass the routine a color and a string of values. If the values are omitted, the routine uses the current string of values in info(values).
proc Neuroplayer_print {line {color "black"}}
Neuroplayer_print writes a line to the text window. If the color specified is "verbose", the message prints only when the verbose flag is set, and in black. Warnings and errors are always printed in the warning and error colors. In addition, if the log_warnings is set, the routine writes all warnings and errors to the Neuroplayer log file. The print routine will refrainn from writing the same error message to the text window repeatedly when we set the color to the key word "norepeat". The routine always stores the previous line it writes, so as to compare in the case of a norepeat requirement. Note that the final print to a text window uses LWDAQ_print, which will not try to print to a target with a widget-style name when graphics are disabled.
proc Neuroplayer_print_event {{event ""}}
Neuroplayer_print_event prints an event to the text window with a link embedded in the file name so that we can click on the event and jump to it. If we don't specify an event, the routine prints the current event to the window.
proc Neuroplayer_seek_time {fn payload seek_time {lo_time 0.0} {lo_index 0}}
Neuroplayer_seek_time determines the index of the clock message that occurs just before seek_time and also just after seek time. If the seek time lies exactly upon a clock message, the before and after clock messages will be the same. When the routine searches through an archive for the correct clock messages, it starts at the beginning and proceeds in steps small enough to be less than one complete clock cycle. The clock messages use their sample value to measure time. The sample value counts up from zero to max_sample and then drops to zero again. The clock messages arrive at clocks_per_second. If max_sample = 65536 and clocks_per_second = 128, as is the case for our telemetry receivers, one complete clock cycle is 65536 / 128 Hz = 512 s. If the archive is uncorrupted, it will contain a continuous sequence of clock messages with incrementing sample values, with the exception of clock messages with value max_sample, which will be followed by a message with sample value zero. The seek routine finds time points in the archive quickly because it does not have to look at all the clock messages in the archive. If the archive is severely corrupted, with blocks of null messages and missing data, the seek routine can fail to notice jumps in the clock messages and so fail to note that its time calculation is invalid. As an alternative to jumping through the archive, the Neuroplayer_sequential_time routine starts at the first clock message and counts clock messages, adding one clock period to its measurement of archive time for every clock message, irrespective of the values of the messages. Both routines take the same parameters and return four numbers: lo_time, lo_index, hi_time, and hi_index. The "end clock" is the clock message that follows the last message in the archive. The end clock is not itself included in the archive. If our Neurorecorder was free-running during our recording, the end clock will be the first message in the next archive. If our Neurorecorder was re-synchronizing, the end clock will have been discarded and never written to disk. Even if the archive consists entirely of clock messages, the seek routine assumes that the clock message corresponding to the end of the archive is the one that would follow the final clock message in the archive. The routine will choose the time of the end clock for hi_time and hi_index if the seek time is equal to or greater than the length of the archive. If the seek time is -1, the routine takes this to mean that it should find the end time of the archive, which will be the time and index of the end clock, even though this clock is not included in the archive. Note that the index of a message is its index in the archive's data block, when we divide the block into messages. Messages are at least core_message_length long, and my have an arbitrary payload attached to the end, as given by the payload parameter in the NDF's metadata. The byte address of a message is the byte number of the first byte of the message within the archive's data block. The return string "0 2 0 2" means time zero occurs at message index 2 in the archive. The message with index 2 is the third message in the data block of the archive. We might obtain such a result when we specify seek time of 0 and apply it to an archive that, for some reason, does not start with a clock message. We can pass in optional values for lo_time and lo_index, where the seek should start from these values. The lo_time should be the play time that is correct for message lo_index within the file.
proc Neuroplayer_sequential_time {fn payload seek_time {lo_time 0.0} {lo_index 0}}
Neuroplayer_sequential_time has the same format as Neuroplayer_seek_time but proceeds through the archive calculating time by counting every single clock message. We use this routine with corrupted archvies, in which the time represented by the values of the clock messages is so distorted as to be useless. Instead of using the clock message values, we assume every clock message represents a time increment of one clock period, and we search through every clock message to find the correct time.
proc Neuroplayer_signal {{channel_code ""} {status_only 0}}
Neuroplayer_signal extracts or reconstructs the signal from one channel in the data image. It updates info(num_received) and info(standing_values). It info(frequency) and info(num_messages). It returns the extracted or reconstructed signal. The returned signal format is a space-delimited string giving a sequence of messages. Each message is a timestamp followed by a sample value. The timestamp is an integer number of clock ticks from the beginning of the playback interval. The timestamps and vsample alues alternate in the return string, separated by single spaces. The "extracted" signal is a list of messages that exist in the data image. The "reconstructed" signal is the extracted signal with substitute messages inserted and bad messages removed, so as to create a signal with info(frequency) messages. To perform extraction and reconstruction, the routine calls lwdaq_receiver from the lwdaq library. See the Receiver Manual for more information, and also the LWDAQ Command Reference. The routine takes a single parameter: a channel code, which is of the form "id" or "id:f" or "id:f" where "id" is the channel number and "f" is its nominal message rate per second. If status_only is set, we don't reconstruct, but return after determining if there is loss, extra, or okay reception.
proc Neuroplayer_spectrum {{values ""}}
Neuroplayer_spectrum calculates the discrete Fourier transform of the signal. It returns the spectrum as a sequence of real numbers separated by spaces. Each pair of numbers is the amplitude and phase of a component in the transform. The k'th pair represent a sinusoidal component of frequency k/NT, where T is the sample period and N is the number of samples. We have k = 0 to (N/2)-1. We note that the playback interval has length NT. If the sample frequency is f_s, we have f_s = 1/T. For a f_s = 512 SPS and NT = 1 s, we have 256 pairs of numbers, k = 0 to 255, the k'th component having frequency k/1 = k Hz. Each pair consists of a amplitude, a, and a phase, p, and represents a single sinusoidal component of frequency k/NT whose value at sample n is equal to a*cos(2*pi*k*n/N - p). Here we have sample n occurring at time nT. The final pair is the amplitude and phase of the 255-Hz component. We have not yet accounted for the 256-Hz component, which is the highest frequency we can represent with 512 SPS. The k=0 pair is the first pair, and is an exception. The first number in the k=0 pair is the average value of the signal and the second number is the amplitude of the N/2'th component. This final component has phase 0 or pi, and we represent this phase with the sign of the amplitude, positive for phase 0 and negative for phase pi. If we pass an empty string to the routine, it uses info(values). The procedure calls the lwdaq_fft. You can read more about the Fourier transform routine in the LWDAQ Command Reference.
proc Neuroplayer_values {{signal ""}}
Neuroplayer_values extracts only the voltage values from the Neuroplayer signal. If there are values missing, it adds values so that we have a power of two number of values to pass to the fft later. If there are too many values, we remove some until the number is correct.
proc Neuroplayer_video_close {}
Neuroplayer_video_close shuts down the video player, causing its window to close.
proc Neuroplayer_video_download {}
Neuroplayer_video_download downloads the Videoarchiver zip archive with the help of a web browser.
proc Neuroplayer_video_info {fn}
Neuroplayer_video_info calls ffmpeg to determine the width, height, frame rate and duration of an existing video file. The frame rate is frames per second. The duration is in seconds. If the file does not exist, the routine returns "0 0 0 -1".
proc Neuroplayer_video_play {datetime length}
Neuroplayer_video_play tries to put together a list of one or more files and times within those files that together compose a video corresponding to an interval of "length" seconds starting at absolute time "datetime". We specify the absolute time in UNIX seconds, and the length in seconds also. Both values can be fractional. If no Videoplayer exists, the routine launches one. If the start of the interval exists in no file, or if no video covers a significant portion of the interval, the routine gives up and prints an error message.
proc Neuroplayer_video_seek {datetime}
Neuroplayer_video_seek looks for a video file whose correct time span contains a particular datetime expressed as in UNIX seconds, and accepting fractional seconds. The "correct time span" is the time between a video's start time and the start of the next video in the video directory. The "correct length", clen, is the time between its own start and that of the next file. If there is no next file, the correct length defaults to the "video length", vlen, which is the number of frames the video contains divided by its framerate. The datetime must be greater than or equal to the start of the correct time span, and less than the end of the correct time span. The routine calculates the "seek time", vseek, which is the time from the start of the correct time span of the video that corresponds to the specified datetime. It returns the video file name, vseek, vlen, clen, and the width, height, and framerate of the video. The routine uses a cache of recently-used video files to save time when searching for the correct file, because the search requires that we get the length of the video calculated by ffmpeg, and this calculation is time-consuming. If the video is not in the cache, we use the video directory as a source of video files.
proc Neuroplayer_video_suggest {}
Neuroplayer_video_suggest prints a message with a text link suggesting that the user download the Videoarchiver directory to install ffmpeg.
proc Neuroplayer_video_watchdog {}
Neuroplayer_video_watchdog monitors video playback. It checks to see if the Videoplayer still exists: the window may have been closed by the user. If the Videoplayer is closed, the watchdog makes sure its channel and process are closed and stopped, and clears the channel and process variables to show other Neuroplayer routines that there is no active Videoplayer running. If the video has finished playing, the watchdog changes the video state to Idle and changes the player's state label background back to white. If the user has issued a command, the watchdog will see the video state turn to Stop, to which it responds by sending a stop command to the Videoplayer. So long as the Videoplayer exists, the watchdog posts itself to the event queue and keeps working. As soon as the Videoplayer ceases to exist, the watchdog lets itself terminate.
proc Neurotracker_clear {}
Neurotracker_clear clears the display and the history.
proc Neurotracker_draw_graphs {}
Neurotracker_draw_graphs draws the traker graphs in the tracker window.
proc Neurotracker_extract {}
Neurotracker_extract calculates the position of a transmitter over an array of detector coils and returns the position as a sequency of xyz coordinates accompanied by the power measurement provided by each detector coil. The routine relies upon a prior call to lwdaq_receiver filling a list of power measurements that correspond to some device we want to locate. This list exists in the lwdaq library global variable space, but not in the LWDAQ TclTk variable space. The indices allow the lwdaq_alt routine to find the message payloads in the data image that correspond to the device.
proc Neurotracker_fresh_graphs {}
Neurotracker_fresh_graphs prepares for tracking of available channels. When graphics are available, the routine also clears the overlay of the tracker plot and draws the grid.
proc Neurotracker_open {}
Neurotracker_open opens the tracker window and creates the graphical images and photos required to plot the tracks.
proc Neurotracker_plot {}
Neurotracker_plot plots the locus of the current transmitter channel centroid in the tracker window.