riku
2021-07-12 d978297ae85b2d7453054e616bbbe87bfabe9cbe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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()
        mDataList.subList(mDataList.lastIndex - ncal + 1, 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))
        }
    }
}