我想要分析的流(一个大的二进制文件)组成如下:
10字节信号流:
信号由每隔SIGNAL_INTERVAL
发送一次脉冲的信号源发出,探测器可能检测到也可能没有检测到信号。如果检测器计数,它会将结果发送到计数器的通道,该通道打印如上所示的计数。该计数器共有8个通道。
为了增加检测器的数量,使用多路复用方法。两个检测器将它们的计数发送到相同的通道(例如,检测器1和9耦合在计数器的通道1上)。其中一个信号(例如9)延迟DELAY
,因此延迟计数相对于非延迟计数发生偏移。
想法是将延迟数据与非延迟数据相除,然后减去延迟(将通道值加8,使通道1上的延迟计数显示为通道9上的计数),然后重新加入这两个阵列。
如果SIGNAL_INTERVAL
是常数,这相对容易:我定义了一个“掩码”[0, DELAY, SIGNAL_INTERVAL]
,并且在获取参考时间戳值时,查看掩码中每个计数的位置。
尝试不同的面具并计算哪一个计数最多,可以识别非延迟计数的延迟计数。完成最后一部分是因为我们允许时间计数出错,因此流不会完美地聚集。此外,如果第一个计数是延迟计数,非延迟计数或偶数计数,则无法知道先验。
这是逐个通道完成的,因为通道可能具有彼此不同的响应时间。
使用这种方法,代码非常简单:
uint64_t maskCheck(struct count *data, int ch_num, int elements){
const int MAX_NUM = 27; // Maximum number of masks checked
int ref = 0; // The reference variable used as starting point at every cycle
uint64_t sing_count[2][MAX_NUM]; // The array containing the singles counts
uint64_t max_count; // Variable used to find the maximum in the array
int t = 0; // Time index for the following loop
uint64_t result = 0; // The final result, i.e. the index with the most singles counts
// Initializing max_count (it has MAX_NUM as length, so it must be initialized after being declared)
for(int i = 0; i < MAX_NUM; i++)sing_count[0][i] = 0;
for(int i = 0; i < MAX_NUM; i++)sing_count[1][i] = 0;
while(getChannel(data[t])!=ch_num){
t++;
if(t == elements - 1){
printf("%s\n", "Nothing found");
return 0;
}
}
if(getChannel(data[t]) == ch_num) ref = getTimestamp(data[t]);
uint64_t ref_indexed = ref;
for(int index = 0; index < MAX_NUM; index++){
sing_count[1][index] = ref + nsToBins(index) - nsToBins(MAX_NUM/2);
ref_indexed = sing_count[1][index];
for(t = 0; t < elements; t++){
// Skips the counts not occurring at ch_num
if(getChannel(data[t]) != ch_num) {
continue;
}
if(longAbs(getTimestamp(data[t]), ref_indexed) % nsToBins(SIGNAL_INTERVAL) <= nsToBins(MASK) + nsToBins(COUNT_ERROR) &&
longAbs(getTimestamp(data[t]), ref_indexed) % nsToBins(SIGNAL_INTERVAL) >= nsToBins(MASK) - nsToBins(COUNT_ERROR)){
sing_count[0][index]++;
}
else if(longAbs(getTimestamp(data[t]), ref_indexed) % nsToBins(SIGNAL_INTERVAL) <= nsToBins(COUNT_ERROR) ||
longAbs(getTimestamp(data[t]), ref_indexed) % nsToBins(SIGNAL_INTERVAL) >= nsToBins(SIGNAL_INTERVAL) - nsToBins(COUNT_ERROR)){
sing_count[0][index]++;
}
}
}
// This last part maximizes the array.
max_count = sing_count[0][0];
result = sing_count[1][0];
for(int i = 1; i < MAX_NUM; i++){
if(sing_count[0][i] > max_count)
{
max_count = sing_count[0][i];
result = sing_count[1][i];
}
}
其中struct count
被定义为函数getTimestamp()
和getChannel()
读取的10字节数组,而nsToBins()
只是转换时间单位。
拥有“最佳掩码”,我可以通过它分割数组,然后执行所有其他所需的操作。
现在,问题来了。 SIGNAL_INTERVAL
不是常数,并且它甚至没有确定(为了给你一个想法,频率在75.6 Mhz
和76.3 MHz
之间振荡)。
上述方法现在证明是非常不成功的:
SIGNAL_INTERVAL
的错误大约为0.3 ns
SIGNAL_INTERVAL
的数量级为10 ns
,仅一秒后误差就会太大我想到的是分析数据中的聚类(SIGNAL_INTERVAL
不是常数,但振荡远小于DELAY
,因此原则上可以观察到一些聚类)并找到另一种划分两个数组的方法。
但到目前为止我一无所有。任何帮助将不胜感激。