--- title: "Hyperscanning" slug: "hyperscanning" updated: 2025-03-07T02:57:09Z published: 2025-03-07T02:57:09Z canonical: "docs.kernel.com/hyperscanning" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.kernel.com/llms.txt > Use this file to discover all available pages before exploring further. # Hyperscanning #### Requirements If you would like to measure two participants at once, you will need: - Two Flow Headsets - Two Acquisition Computers The easiest way for the data to be aligned is to put the computers onto the same clock. This can be done using [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) and synchronizing the two computers to the same time server. If the time server is on the local network, each computer should have <1ms error for a total error of <2ms. If the time server is on the internet, you should measure the error to decide if it is acceptable or not. #### Synchronization via Task Events When the NTP error is too high, we also support synchronizing via custom task events. ![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcJEDDtE-qc8H6Q_xAb3HrVfmr6ve96bRDCXHY0_cz5UOaF9JUL3rtadM-85-TmIrOZqfLkAR7Qo_9g9ZOx2qf5pp6ObN7wO9TONrPSCfET-y64lrU14BfS7MnXefR7kk1z2ERyMQ?key=mm8J23HwPw2NvvCAjo0B9BMA) *Diagram 1: Two task connections emit task events to two acquisition drivers* To synchronize two datasets recorded for hyperscanning, you can configure the [task client](/v1/docs/kernel-tasks-sdk) to emit events to both acquisition drivers at the same time. Each task records the time the event was emitted, and each acquisition driver will record the time the event was received. When the task and acquisition driver are running on the same PC (PC1), the latency between when the event is sent (ts_tx) and when it is received (ts_rx) is negligible (ε), and there is no clock difference since the sent time and the receive time are recorded with the same clock. However, when the event is sent to another PC (PC2) the receive time will be affected by the clock offset between PC1 and PC2 (θ) and any network latency that occurred (ℓ). That is: PC1 ts_rx - PC1 ts_tx = ε PC2 ts_rx - PC1 ts_tx = θ + ℓ In order to synchronize the sessions we need to find the clock offset θ and correct the NIRS times by it. To calculate θ, we’ll need to find the network latency ℓ and send it as a special task event named **ping_latency_ms**. Ping is a common tool to determine the latency, and we’ll use a pure Python implementation in our example. You can use your own implementation, but be aware that the quality of the ℓ will affect the quality of synchronization. ```python from kernel.sdk.task import TaskClient, ClientProtocol from tcppinglib import tcpping tcp_port = 6767 conn1 = TaskClient(“localhost”,tcp_port, protocol=ClientProtocol.TCP) remote_ip = “xxx.xxx.xxx.xxx” conn2 = TaskClient(remote_ip,tcp_port, protocol=ClientProtocol.TCP) # fill ip in with the ip of the remote pc while True: conn2_rtt = tcpping(remote_ip,tcp_port,count=4,interval=0.25).avg_rtt # get the average round-trip time for 1 second conn1.send_event(ping_latency_ms=0.0) # latency on localhost is negligible conn2.send_event(ping_latency_ms=conn2_rtt/2) # assume network symmetry, so latency to pc2 is rtt/2 ``` The offset will appear as **ClockOffset** in the SNIRF file later, and we can use this to correct the NIRS data. There are multiple ways to do the correction; here we’ll just use a simple average: ```python from snirf import Snirf import numpy as np snirf_file = Snirf('some\path\session1.snirf') # get the offset info offset_idx = np.where(snirf_file.nirs[0].stim[0].dataLabels == "ClockOffset")[0].item() offset_column = snirf_file.nirs[0].stim[0].data[:,offset_idx] offsets = offset_column[~np.isnan(offset_column)] average_offset = np.average(offsets) # now correct the nirs timestamps by the average snirf_file.nirs[0].data[0].time = snirf_file.nirs[0].data[0].time - average_offset snirf_file.save() # write corrected timestamps back to disk ``` Note that the corrected timestamps may be negative (in case the receiver’s clock is behind the sender’s clock).