package com.flightfeather.uav.model.epw
|
|
import com.flightfeather.uav.lightshare.bean.CompanySOP
|
import com.flightfeather.uav.lightshare.bean.DataVo
|
import com.flightfeather.uav.model.BaseDataPrep
|
import com.flightfeather.uav.socket.eunm.FactorType
|
import kotlin.math.max
|
import kotlin.math.min
|
import kotlin.math.sqrt
|
|
class EPWDataPrep : BaseDataPrep<DataVo, CompanySOP>() {
|
|
// 向前检索的数据记录数
|
private val ncal = 15
|
// 标准差倍数参数
|
private val nstd = 3
|
// 均值倍数参数
|
private val xratio = 3
|
// 需要处理的因子类型
|
private val calTypes =
|
// emptyList<String>()
|
WeightType.prep
|
|
private val lastData = mutableListOf<DataVo>()
|
|
override fun mDataPrep(mDataList: List<DataVo>): List<DataVo> {
|
mDataList.forEach {
|
it.values?.forEach v@{a ->
|
if (!calTypes.contains(a.factorName)) return@v
|
|
val range = FactorType.getRange(a.factorName) ?: return@v
|
// 判断数据是否在合理范围内
|
if (a.factorData ?: 0.0 < range.first || a.factorData ?: 0.0 > range.second) {
|
a.factorData = null
|
}
|
}
|
}
|
|
// val newDataList = mutableListOf<DataVo>()
|
// mDataList.forEach {
|
// newDataList.add(it.copy())
|
// }
|
|
var i = ncal
|
if (lastData.isNotEmpty()) {
|
i = 0
|
}
|
while (i < mDataList.size) {
|
for (y in mDataList[i].values?.indices ?: 0..0) {
|
val it = mDataList[i].values?.get(y) ?: continue
|
|
if (!calTypes.contains(it.factorName)) continue
|
val vMax = FactorType.getVMax(it.factorName) ?: continue
|
it.factorData ?: continue
|
|
if (it.factorData!! > vMax) {
|
val lastDataIndex = i
|
val thisIndex = if (i-ncal<0) 0 else i - ncal
|
val list = mutableListOf<DataVo>()
|
if (lastDataIndex < lastData.size) {
|
list.addAll(lastData.subList(lastDataIndex, lastData.lastIndex + 1))
|
}
|
list.addAll(mDataList.subList(thisIndex, i))
|
|
// 去除无效值的平均
|
val avg = average(list, it.factorName)
|
// 去除无效值的标准差
|
val std = standardDeviation(avg.first, list, it.factorName)
|
// 合理最大值
|
val max = max(avg.first + std * nstd, avg.first + avg.first * xratio)
|
// 合理最小值
|
val min = min(avg.first - std * nstd, avg.first / (1 + xratio))
|
|
// 数据不处于合理范围并且有效个数达标时,采用计算所得均值代替原始值
|
if (avg.second > max(ncal / 5, 2)
|
&& (it.factorData!! < min || it.factorData!! > max)
|
) {
|
// 原始数据
|
it.factorData = null
|
// newDataList[i].values?.get(y)?.factorData = avg.first
|
}
|
}
|
}
|
|
i++
|
}
|
|
lastData.clear()
|
val s = if ((mDataList.lastIndex - ncal + 1) < 0) 0 else mDataList.lastIndex - ncal + 1
|
mDataList.subList(s, mDataList.lastIndex + 1).forEach {
|
lastData.add(it.copy())
|
}
|
|
return mDataList
|
}
|
|
override fun sopPrep(sopList: List<CompanySOP>): List<CompanySOP> {
|
return sopList
|
}
|
|
/**
|
* 去除无效值的平均
|
* @param list 监测数据
|
* @return 均值和有效数据个数
|
*/
|
private fun average(list: List<DataVo>, factorName:String?): Pair<Double, Int> {
|
var t = 0.0
|
var c = 0
|
list.forEach {
|
for (i in it.values?.indices ?: 0..0) {
|
val f = it.values?.get(i)
|
if (f?.factorName == factorName) {
|
if (f?.factorData != null) {
|
t += f.factorData!!
|
c++
|
}
|
break
|
}
|
}
|
}
|
|
val avg = if (c == 0) {
|
0.0
|
} else {
|
t / c
|
}
|
|
return Pair(avg, c)
|
}
|
|
/**
|
* 去除无效值的标准差
|
*/
|
private fun standardDeviation(avg: Double, list: List<DataVo>, factorName: String?): Double {
|
var t = 0.0
|
var c = 0
|
list.forEach {
|
for (i in it.values?.indices ?: 0..0) {
|
val f = it.values?.get(i)
|
if (f?.factorName == factorName) {
|
if (f?.factorData != null) {
|
t += (f.factorData!! - avg) * (f.factorData!! - avg)
|
c++
|
}
|
break
|
}
|
}
|
}
|
|
return if (c <= 1) {
|
0.0
|
} else {
|
sqrt(t / (c - 1))
|
}
|
}
|
}
|