增加日志输出,以便观察实际波形信息
This commit is contained in:
@@ -876,32 +876,19 @@ public class ComtradeReader {
|
||||
// 记录段的起始位置
|
||||
dataBuf.getSegmentStartIndices()[seg] = sampleIndex;
|
||||
|
||||
// 只对超过512的段降采样到256
|
||||
float targetRate = segmentSamplesPerCycle;
|
||||
int downsampleMod = 1;
|
||||
// 记录段的原始采样率(不做降采样)
|
||||
dataBuf.getSegmentSampleRates()[seg] = segmentSamplesPerCycle;
|
||||
|
||||
if (segmentSamplesPerCycle > 512) {
|
||||
targetRate = 256;
|
||||
downsampleMod = Math.round(segmentSamplesPerCycle / 256);
|
||||
log.info("段{} - 原始: {}点/周波 > 512, 降采样到256, 模数: {}",
|
||||
seg, segmentSamplesPerCycle, downsampleMod);
|
||||
} else {
|
||||
log.info("段{} - 原始: {}点/周波, 保持不变",
|
||||
log.info("段{} - 原始: {}点/周波, 保留原始数据",
|
||||
seg, segmentSamplesPerCycle);
|
||||
}
|
||||
|
||||
// 记录段的采样率(降采样后的)
|
||||
dataBuf.getSegmentSampleRates()[seg] = targetRate;
|
||||
|
||||
// 读取当前段的数据
|
||||
// 读取当前段的所有数据(不降采样)
|
||||
for (int i = 0; i < segmentSamples; i++) {
|
||||
int bytesRead = dis.read(buffer, 0, recordSize);
|
||||
if (bytesRead != recordSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 降采样(仅当>512时)
|
||||
if (i % downsampleMod == 0) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(buffer);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
@@ -915,12 +902,11 @@ public class ComtradeReader {
|
||||
}
|
||||
sampleIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
log.info("段{} 完成 - 起始索引: {}, 输出采样点: {}, 采样率: {}点/周波",
|
||||
seg, dataBuf.getSegmentStartIndices()[seg],
|
||||
sampleIndex - dataBuf.getSegmentStartIndices()[seg],
|
||||
targetRate);
|
||||
segmentSamplesPerCycle);
|
||||
}
|
||||
|
||||
log.info("=== 多段数据处理完成 - 总采样点: {} ===", sampleIndex);
|
||||
@@ -931,15 +917,11 @@ public class ComtradeReader {
|
||||
dataBuf.getSegmentStartIndices()[0] = 0;
|
||||
|
||||
float samplesPerCycle = (float) cfgInfo.getSampleRate() / lineFreq;
|
||||
float targetRate = samplesPerCycle;
|
||||
int downsampleMod = 1;
|
||||
|
||||
if (samplesPerCycle > 512) {
|
||||
targetRate = 256;
|
||||
downsampleMod = Math.round(samplesPerCycle / 256);
|
||||
}
|
||||
// 记录原始采样率(不降采样)
|
||||
dataBuf.getSegmentSampleRates()[0] = samplesPerCycle;
|
||||
|
||||
dataBuf.getSegmentSampleRates()[0] = targetRate;
|
||||
log.info("单段数据 - 原始: {}点/周波, 保留原始数据", samplesPerCycle);
|
||||
|
||||
int totalSamples = cfgInfo.getTotalSamples();
|
||||
for (int i = 0; i < totalSamples; i++) {
|
||||
@@ -948,7 +930,6 @@ public class ComtradeReader {
|
||||
break;
|
||||
}
|
||||
|
||||
if (i % downsampleMod == 0) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(buffer);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
@@ -961,9 +942,8 @@ public class ComtradeReader {
|
||||
}
|
||||
sampleIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
log.info("单段数据处理完成 - 采样点: {}, 采样率: {}点/周波", sampleIndex, targetRate);
|
||||
log.info("单段数据处理完成 - 采样点: {}, 采样率: {}点/周波", sampleIndex, samplesPerCycle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.njcn.gather.tools.comtrade.comparewave.core.Constants.MAX_CH_NUM;
|
||||
|
||||
/**
|
||||
* 波形比对分析服务实现类
|
||||
*
|
||||
@@ -418,6 +420,20 @@ public class CompareWaveServiceImpl implements ICompareWaveService {
|
||||
break;
|
||||
}
|
||||
|
||||
// 检查采样率是否过低(< 128)
|
||||
boolean sourceLowSampleRate = (sourceSampleRate < 128);
|
||||
boolean targetLowSampleRate = (targetSampleRate < 128);
|
||||
|
||||
if (sourceLowSampleRate || targetLowSampleRate) {
|
||||
log.warn("窗口 {} - 采样率过低(源文件: {}点/周波, 目标文件: {}点/周波, 最小要求128),该窗口被丢弃",
|
||||
window, sourceSampleRate, targetSampleRate);
|
||||
|
||||
// 推进位置到下一个窗口
|
||||
sourceCurrentPos = sourceWindowEnd;
|
||||
targetCurrentPos = targetWindowEnd;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 判断源文件窗口是否跨段
|
||||
int sourceEndSegment = findSegmentIndex(sourceDataBuf, sourceWindowEnd - 1);
|
||||
boolean sourceCrossSegment = (sourceSegment != sourceEndSegment);
|
||||
@@ -429,12 +445,14 @@ public class CompareWaveServiceImpl implements ICompareWaveService {
|
||||
// 如果任一文件跨段,两个文件都丢弃该窗口
|
||||
if (sourceCrossSegment || targetCrossSegment) {
|
||||
if (sourceCrossSegment) {
|
||||
log.warn("窗口 {} - 源文件跨段(段{} -> 段{}),该窗口被丢弃",
|
||||
window, sourceSegment, sourceEndSegment);
|
||||
float sourceEndSampleRate = sourceDataBuf.getSegmentSampleRates()[sourceEndSegment];
|
||||
log.warn("窗口 {} - 源文件跨段(段{}/{}点/周波 -> 段{}/{}点/周波),该窗口被丢弃",
|
||||
window, sourceSegment, sourceSampleRate, sourceEndSegment, sourceEndSampleRate);
|
||||
}
|
||||
if (targetCrossSegment) {
|
||||
log.warn("窗口 {} - 目标文件跨段(段{} -> 段{}),该窗口被丢弃",
|
||||
window, targetSegment, targetEndSegment);
|
||||
float targetEndSampleRate = targetDataBuf.getSegmentSampleRates()[targetEndSegment];
|
||||
log.warn("窗口 {} - 目标文件跨段(段{}/{}点/周波 -> 段{}/{}点/周波),该窗口被丢弃",
|
||||
window, targetSegment, targetSampleRate, targetEndSegment, targetEndSampleRate);
|
||||
}
|
||||
|
||||
// 推进位置到下一个窗口
|
||||
@@ -449,24 +467,16 @@ public class CompareWaveServiceImpl implements ICompareWaveService {
|
||||
ClockStruct sourceDataTime = calculateWindowTime(sourceStartTime, window);
|
||||
ClockStruct targetDataTime = calculateWindowTime(targetStartTime, window);
|
||||
|
||||
// 计算源文件窗口
|
||||
float sourceOriginalRate = sourceDataBuf.getSmpRate();
|
||||
sourceDataBuf.setSmpRate(sourceSampleRate);
|
||||
sourceDataBuf.setDataPoint(validWindowCount);
|
||||
PowerQualityCalculator.pqs200msDataCal(sourceDataBuf, sourceDataTime, sourceWindowEnd);
|
||||
sourceDataBuf.setSmpRate(sourceOriginalRate);
|
||||
|
||||
PqsDataStruct sourceResult = sourceDataBuf.getPqData()[validWindowCount];
|
||||
// 计算源文件窗口(如果采样率>512,降采样到256)
|
||||
PqsDataStruct sourceResult = calculateWindowWithDownsampling(
|
||||
sourceDataBuf, sourceCurrentPos, sourceWindowEnd,
|
||||
sourceSampleRate, sourceDataTime, validWindowCount);
|
||||
sourceResults.add(sourceResult);
|
||||
|
||||
// 计算目标文件窗口
|
||||
float targetOriginalRate = targetDataBuf.getSmpRate();
|
||||
targetDataBuf.setSmpRate(targetSampleRate);
|
||||
targetDataBuf.setDataPoint(validWindowCount);
|
||||
PowerQualityCalculator.pqs200msDataCal(targetDataBuf, targetDataTime, targetWindowEnd);
|
||||
targetDataBuf.setSmpRate(targetOriginalRate);
|
||||
|
||||
PqsDataStruct targetResult = targetDataBuf.getPqData()[validWindowCount];
|
||||
// 计算目标文件窗口(如果采样率>512,降采样到256)
|
||||
PqsDataStruct targetResult = calculateWindowWithDownsampling(
|
||||
targetDataBuf, targetCurrentPos, targetWindowEnd,
|
||||
targetSampleRate, targetDataTime, validWindowCount);
|
||||
targetResults.add(targetResult);
|
||||
|
||||
log.info("有效窗口 {} (总窗口{}) - 源文件段{}/{}点, 目标文件段{}/{}点, UA: {}/{}, IA: {}/{}",
|
||||
@@ -501,6 +511,81 @@ public class CompareWaveServiceImpl implements ICompareWaveService {
|
||||
compareWaveDTO.setTargetResults(targetResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算窗口电能质量参数(如果采样率>512,降采样到256)
|
||||
*
|
||||
* @param dataBuf 数据缓冲区
|
||||
* @param windowStart 窗口起始位置
|
||||
* @param windowEnd 窗口结束位置
|
||||
* @param sampleRate 窗口采样率(点/周波)
|
||||
* @param dataTime 时间戳
|
||||
* @param windowIndex 窗口索引
|
||||
* @return 计算结果
|
||||
*/
|
||||
private PqsDataStruct calculateWindowWithDownsampling(
|
||||
DataPq dataBuf, int windowStart, int windowEnd,
|
||||
float sampleRate, ClockStruct dataTime, int windowIndex) {
|
||||
|
||||
float originalRate = dataBuf.getSmpRate();
|
||||
int originalDataPoint = dataBuf.getDataPoint();
|
||||
|
||||
try {
|
||||
// 判断是否需要降采样
|
||||
if (sampleRate > 512) {
|
||||
// 需要降采样到256
|
||||
int downsampleMod = Math.round(sampleRate / 256);
|
||||
float targetRate = 256;
|
||||
int windowSamples = windowEnd - windowStart;
|
||||
int downsampledSamples = (windowSamples + downsampleMod - 1) / downsampleMod;
|
||||
|
||||
log.debug("窗口{}降采样: {}点/周波 -> 256点/周波, 模数: {}, 原始{}点 -> {}点",
|
||||
windowIndex, sampleRate, downsampleMod, windowSamples, downsampledSamples);
|
||||
|
||||
// 备份原始数据
|
||||
int[][] backup = new int[MAX_CH_NUM][windowSamples];
|
||||
for (int ch = 0; ch < MAX_CH_NUM; ch++) {
|
||||
System.arraycopy(dataBuf.getSmpData()[ch], windowStart, backup[ch], 0, windowSamples);
|
||||
}
|
||||
|
||||
// 降采样:每downsampleMod个点取1个
|
||||
int downsampledIndex = 0;
|
||||
for (int i = 0; i < windowSamples; i += downsampleMod) {
|
||||
for (int ch = 0; ch < MAX_CH_NUM; ch++) {
|
||||
dataBuf.getSmpData()[ch][windowStart + downsampledIndex] =
|
||||
dataBuf.getSmpData()[ch][windowStart + i];
|
||||
}
|
||||
downsampledIndex++;
|
||||
}
|
||||
|
||||
// 设置降采样后的采样率和窗口结束位置
|
||||
dataBuf.setSmpRate(targetRate);
|
||||
dataBuf.setDataPoint(windowIndex);
|
||||
int downsampledWindowEnd = windowStart + downsampledSamples;
|
||||
|
||||
// 计算电能质量参数
|
||||
PowerQualityCalculator.pqs200msDataCal(dataBuf, dataTime, downsampledWindowEnd);
|
||||
|
||||
// 恢复原始数据
|
||||
for (int ch = 0; ch < MAX_CH_NUM; ch++) {
|
||||
System.arraycopy(backup[ch], 0, dataBuf.getSmpData()[ch], windowStart, windowSamples);
|
||||
}
|
||||
|
||||
} else {
|
||||
// 不需要降采样,直接计算
|
||||
dataBuf.setSmpRate(sampleRate);
|
||||
dataBuf.setDataPoint(windowIndex);
|
||||
PowerQualityCalculator.pqs200msDataCal(dataBuf, dataTime, windowEnd);
|
||||
}
|
||||
|
||||
return dataBuf.getPqData()[windowIndex];
|
||||
|
||||
} finally {
|
||||
// 恢复原始设置
|
||||
dataBuf.setSmpRate(originalRate);
|
||||
dataBuf.setDataPoint(originalDataPoint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算窗口的时间戳
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user