增加日志输出,以便观察实际波形信息
This commit is contained in:
@@ -876,51 +876,37 @@ public class ComtradeReader {
|
|||||||
// 记录段的起始位置
|
// 记录段的起始位置
|
||||||
dataBuf.getSegmentStartIndices()[seg] = sampleIndex;
|
dataBuf.getSegmentStartIndices()[seg] = sampleIndex;
|
||||||
|
|
||||||
// 只对超过512的段降采样到256
|
// 记录段的原始采样率(不做降采样)
|
||||||
float targetRate = segmentSamplesPerCycle;
|
dataBuf.getSegmentSampleRates()[seg] = segmentSamplesPerCycle;
|
||||||
int downsampleMod = 1;
|
|
||||||
|
|
||||||
if (segmentSamplesPerCycle > 512) {
|
log.info("段{} - 原始: {}点/周波, 保留原始数据",
|
||||||
targetRate = 256;
|
seg, segmentSamplesPerCycle);
|
||||||
downsampleMod = Math.round(segmentSamplesPerCycle / 256);
|
|
||||||
log.info("段{} - 原始: {}点/周波 > 512, 降采样到256, 模数: {}",
|
|
||||||
seg, segmentSamplesPerCycle, downsampleMod);
|
|
||||||
} else {
|
|
||||||
log.info("段{} - 原始: {}点/周波, 保持不变",
|
|
||||||
seg, segmentSamplesPerCycle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 记录段的采样率(降采样后的)
|
// 读取当前段的所有数据(不降采样)
|
||||||
dataBuf.getSegmentSampleRates()[seg] = targetRate;
|
|
||||||
|
|
||||||
// 读取当前段的数据
|
|
||||||
for (int i = 0; i < segmentSamples; i++) {
|
for (int i = 0; i < segmentSamples; i++) {
|
||||||
int bytesRead = dis.read(buffer, 0, recordSize);
|
int bytesRead = dis.read(buffer, 0, recordSize);
|
||||||
if (bytesRead != recordSize) {
|
if (bytesRead != recordSize) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 降采样(仅当>512时)
|
ByteBuffer bb = ByteBuffer.wrap(buffer);
|
||||||
if (i % downsampleMod == 0) {
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
ByteBuffer bb = ByteBuffer.wrap(buffer);
|
|
||||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
|
|
||||||
bb.getInt(); // 序号
|
bb.getInt(); // 序号
|
||||||
bb.getInt(); // 时间戳
|
bb.getInt(); // 时间戳
|
||||||
|
|
||||||
// 读取模拟通道数据
|
// 读取模拟通道数据
|
||||||
for (int ch = 0; ch < cfgInfo.getAnalogChannels() && ch < MAX_CH_NUM; ch++) {
|
for (int ch = 0; ch < cfgInfo.getAnalogChannels() && ch < MAX_CH_NUM; ch++) {
|
||||||
short rawValue = bb.getShort();
|
short rawValue = bb.getShort();
|
||||||
dataBuf.getSmpData()[ch][sampleIndex] = rawValue;
|
dataBuf.getSmpData()[ch][sampleIndex] = rawValue;
|
||||||
}
|
|
||||||
sampleIndex++;
|
|
||||||
}
|
}
|
||||||
|
sampleIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("段{} 完成 - 起始索引: {}, 输出采样点: {}, 采样率: {}点/周波",
|
log.info("段{} 完成 - 起始索引: {}, 输出采样点: {}, 采样率: {}点/周波",
|
||||||
seg, dataBuf.getSegmentStartIndices()[seg],
|
seg, dataBuf.getSegmentStartIndices()[seg],
|
||||||
sampleIndex - dataBuf.getSegmentStartIndices()[seg],
|
sampleIndex - dataBuf.getSegmentStartIndices()[seg],
|
||||||
targetRate);
|
segmentSamplesPerCycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("=== 多段数据处理完成 - 总采样点: {} ===", sampleIndex);
|
log.info("=== 多段数据处理完成 - 总采样点: {} ===", sampleIndex);
|
||||||
@@ -931,15 +917,11 @@ public class ComtradeReader {
|
|||||||
dataBuf.getSegmentStartIndices()[0] = 0;
|
dataBuf.getSegmentStartIndices()[0] = 0;
|
||||||
|
|
||||||
float samplesPerCycle = (float) cfgInfo.getSampleRate() / lineFreq;
|
float samplesPerCycle = (float) cfgInfo.getSampleRate() / lineFreq;
|
||||||
float targetRate = samplesPerCycle;
|
|
||||||
int downsampleMod = 1;
|
|
||||||
|
|
||||||
if (samplesPerCycle > 512) {
|
// 记录原始采样率(不降采样)
|
||||||
targetRate = 256;
|
dataBuf.getSegmentSampleRates()[0] = samplesPerCycle;
|
||||||
downsampleMod = Math.round(samplesPerCycle / 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
dataBuf.getSegmentSampleRates()[0] = targetRate;
|
log.info("单段数据 - 原始: {}点/周波, 保留原始数据", samplesPerCycle);
|
||||||
|
|
||||||
int totalSamples = cfgInfo.getTotalSamples();
|
int totalSamples = cfgInfo.getTotalSamples();
|
||||||
for (int i = 0; i < totalSamples; i++) {
|
for (int i = 0; i < totalSamples; i++) {
|
||||||
@@ -948,22 +930,20 @@ public class ComtradeReader {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i % downsampleMod == 0) {
|
ByteBuffer bb = ByteBuffer.wrap(buffer);
|
||||||
ByteBuffer bb = ByteBuffer.wrap(buffer);
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
|
|
||||||
bb.getInt();
|
bb.getInt();
|
||||||
bb.getInt();
|
bb.getInt();
|
||||||
|
|
||||||
for (int ch = 0; ch < cfgInfo.getAnalogChannels() && ch < MAX_CH_NUM; ch++) {
|
for (int ch = 0; ch < cfgInfo.getAnalogChannels() && ch < MAX_CH_NUM; ch++) {
|
||||||
short rawValue = bb.getShort();
|
short rawValue = bb.getShort();
|
||||||
dataBuf.getSmpData()[ch][sampleIndex] = rawValue;
|
dataBuf.getSmpData()[ch][sampleIndex] = rawValue;
|
||||||
}
|
|
||||||
sampleIndex++;
|
|
||||||
}
|
}
|
||||||
|
sampleIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("单段数据处理完成 - 采样点: {}, 采样率: {}点/周波", sampleIndex, targetRate);
|
log.info("单段数据处理完成 - 采样点: {}, 采样率: {}点/周波", sampleIndex, samplesPerCycle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import java.io.InputStream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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;
|
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);
|
int sourceEndSegment = findSegmentIndex(sourceDataBuf, sourceWindowEnd - 1);
|
||||||
boolean sourceCrossSegment = (sourceSegment != sourceEndSegment);
|
boolean sourceCrossSegment = (sourceSegment != sourceEndSegment);
|
||||||
@@ -429,12 +445,14 @@ public class CompareWaveServiceImpl implements ICompareWaveService {
|
|||||||
// 如果任一文件跨段,两个文件都丢弃该窗口
|
// 如果任一文件跨段,两个文件都丢弃该窗口
|
||||||
if (sourceCrossSegment || targetCrossSegment) {
|
if (sourceCrossSegment || targetCrossSegment) {
|
||||||
if (sourceCrossSegment) {
|
if (sourceCrossSegment) {
|
||||||
log.warn("窗口 {} - 源文件跨段(段{} -> 段{}),该窗口被丢弃",
|
float sourceEndSampleRate = sourceDataBuf.getSegmentSampleRates()[sourceEndSegment];
|
||||||
window, sourceSegment, sourceEndSegment);
|
log.warn("窗口 {} - 源文件跨段(段{}/{}点/周波 -> 段{}/{}点/周波),该窗口被丢弃",
|
||||||
|
window, sourceSegment, sourceSampleRate, sourceEndSegment, sourceEndSampleRate);
|
||||||
}
|
}
|
||||||
if (targetCrossSegment) {
|
if (targetCrossSegment) {
|
||||||
log.warn("窗口 {} - 目标文件跨段(段{} -> 段{}),该窗口被丢弃",
|
float targetEndSampleRate = targetDataBuf.getSegmentSampleRates()[targetEndSegment];
|
||||||
window, targetSegment, targetEndSegment);
|
log.warn("窗口 {} - 目标文件跨段(段{}/{}点/周波 -> 段{}/{}点/周波),该窗口被丢弃",
|
||||||
|
window, targetSegment, targetSampleRate, targetEndSegment, targetEndSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 推进位置到下一个窗口
|
// 推进位置到下一个窗口
|
||||||
@@ -449,24 +467,16 @@ public class CompareWaveServiceImpl implements ICompareWaveService {
|
|||||||
ClockStruct sourceDataTime = calculateWindowTime(sourceStartTime, window);
|
ClockStruct sourceDataTime = calculateWindowTime(sourceStartTime, window);
|
||||||
ClockStruct targetDataTime = calculateWindowTime(targetStartTime, window);
|
ClockStruct targetDataTime = calculateWindowTime(targetStartTime, window);
|
||||||
|
|
||||||
// 计算源文件窗口
|
// 计算源文件窗口(如果采样率>512,降采样到256)
|
||||||
float sourceOriginalRate = sourceDataBuf.getSmpRate();
|
PqsDataStruct sourceResult = calculateWindowWithDownsampling(
|
||||||
sourceDataBuf.setSmpRate(sourceSampleRate);
|
sourceDataBuf, sourceCurrentPos, sourceWindowEnd,
|
||||||
sourceDataBuf.setDataPoint(validWindowCount);
|
sourceSampleRate, sourceDataTime, validWindowCount);
|
||||||
PowerQualityCalculator.pqs200msDataCal(sourceDataBuf, sourceDataTime, sourceWindowEnd);
|
|
||||||
sourceDataBuf.setSmpRate(sourceOriginalRate);
|
|
||||||
|
|
||||||
PqsDataStruct sourceResult = sourceDataBuf.getPqData()[validWindowCount];
|
|
||||||
sourceResults.add(sourceResult);
|
sourceResults.add(sourceResult);
|
||||||
|
|
||||||
// 计算目标文件窗口
|
// 计算目标文件窗口(如果采样率>512,降采样到256)
|
||||||
float targetOriginalRate = targetDataBuf.getSmpRate();
|
PqsDataStruct targetResult = calculateWindowWithDownsampling(
|
||||||
targetDataBuf.setSmpRate(targetSampleRate);
|
targetDataBuf, targetCurrentPos, targetWindowEnd,
|
||||||
targetDataBuf.setDataPoint(validWindowCount);
|
targetSampleRate, targetDataTime, validWindowCount);
|
||||||
PowerQualityCalculator.pqs200msDataCal(targetDataBuf, targetDataTime, targetWindowEnd);
|
|
||||||
targetDataBuf.setSmpRate(targetOriginalRate);
|
|
||||||
|
|
||||||
PqsDataStruct targetResult = targetDataBuf.getPqData()[validWindowCount];
|
|
||||||
targetResults.add(targetResult);
|
targetResults.add(targetResult);
|
||||||
|
|
||||||
log.info("有效窗口 {} (总窗口{}) - 源文件段{}/{}点, 目标文件段{}/{}点, UA: {}/{}, IA: {}/{}",
|
log.info("有效窗口 {} (总窗口{}) - 源文件段{}/{}点, 目标文件段{}/{}点, UA: {}/{}, IA: {}/{}",
|
||||||
@@ -501,6 +511,81 @@ public class CompareWaveServiceImpl implements ICompareWaveService {
|
|||||||
compareWaveDTO.setTargetResults(targetResults);
|
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