|
|
@@ -823,80 +823,7 @@ namespace HealthMonitor.Service.Biz.db |
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 胎心算法 |
|
|
|
/// <summary> |
|
|
|
/// 获取孕妇心率众数 |
|
|
|
/// </summary> |
|
|
|
/// <param name="serialNo"></param> |
|
|
|
/// <param name="days"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public async Task<int> GetPregnancyHeartRateModeAsync(string serialNo,int days=7) |
|
|
|
{ |
|
|
|
var tableName = typeof(PregnancyHeartRateModel) |
|
|
|
.GetCustomAttribute<STableAttribute>()? |
|
|
|
.STableName; |
|
|
|
var daysAgo = DateTime.Now.AddDays(-days); |
|
|
|
var res = await _clientSqlSugar |
|
|
|
.Queryable<PregnancyHeartRateModel>() |
|
|
|
.AS(tableName) |
|
|
|
.Where(i=>i.SerialNumber.Equals(serialNo)) |
|
|
|
.Where(i => i.Timestamp > daysAgo) |
|
|
|
//.OrderByDescending(i => i.PregnancyHeartRate) |
|
|
|
.Select(i =>i.PregnancyHeartRate) |
|
|
|
.ToListAsync(); |
|
|
|
// 心率数据量必须30个以上才进行计算 |
|
|
|
if (res.Count < 30) return 0; |
|
|
|
|
|
|
|
// 计算众数 |
|
|
|
var mode = res.GroupBy(n => n) |
|
|
|
.OrderByDescending(g => g.Count()) |
|
|
|
.First() |
|
|
|
.Key; |
|
|
|
|
|
|
|
Console.WriteLine("众数是: " + mode); |
|
|
|
|
|
|
|
// 如果有多个众数的情况 |
|
|
|
var maxCount = res.GroupBy(n => n) |
|
|
|
.Max(g => g.Count()); |
|
|
|
|
|
|
|
var modes = res.GroupBy(n => n) |
|
|
|
.Where(g => g.Count() == maxCount) |
|
|
|
.Select(g => g.Key) |
|
|
|
.ToList(); |
|
|
|
// 多个众数,选择最接近平均数或中位数的众数 |
|
|
|
if (modes.Count>1) |
|
|
|
{ |
|
|
|
// 计算平均值 |
|
|
|
double average = res.Average(); |
|
|
|
Console.WriteLine("平均值是: " + average); |
|
|
|
|
|
|
|
// 计算中位数 |
|
|
|
double median; |
|
|
|
int count = res.Count; |
|
|
|
var sortedRes = res.OrderBy(n => n).ToList(); |
|
|
|
if (count % 2 == 0) |
|
|
|
{ |
|
|
|
// 偶数个元素,取中间两个数的平均值 |
|
|
|
median = (sortedRes[count / 2 - 1] + sortedRes[count / 2]) / 2.0; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// 奇数个元素,取中间的数 |
|
|
|
median = sortedRes[count / 2]; |
|
|
|
} |
|
|
|
Console.WriteLine("中位数是: " + median); |
|
|
|
|
|
|
|
// 找出最接近平均值的众数 |
|
|
|
//var closestToAverage = modes.OrderBy(m => Math.Abs(m - average)).First(); |
|
|
|
//Console.WriteLine("最接近平均值的众数是: " + closestToAverage); |
|
|
|
|
|
|
|
// 找出最接近中位数的众数 |
|
|
|
var closestToMedian = modes.OrderBy(m => Math.Abs(m - median)).First(); |
|
|
|
Console.WriteLine("最接近中位数的众数是: " + closestToMedian); |
|
|
|
mode = closestToMedian; |
|
|
|
} |
|
|
|
|
|
|
|
return mode; |
|
|
|
} |
|
|
|
/// <summary> |
|
|
|
/// 计算个人一般心率 |
|
|
|
/// </summary> |
|
|
@@ -904,7 +831,7 @@ namespace HealthMonitor.Service.Biz.db |
|
|
|
/// <param name="days"></param> |
|
|
|
/// <param name="percentage"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public async Task<PregnancyCommonHeartRateModel?> InitPregnancyCommonHeartRateModeAsync(string serialNo, int days = 7,int percentage=90) |
|
|
|
public async Task<PregnancyCommonHeartRateModel?> InitPregnancyCommonHeartRateModeAsync(string serialNo, int days = 7, int percentage = 90) |
|
|
|
{ |
|
|
|
var tableName = typeof(PregnancyHeartRateModel) |
|
|
|
.GetCustomAttribute<STableAttribute>()? |
|
|
@@ -922,7 +849,7 @@ namespace HealthMonitor.Service.Biz.db |
|
|
|
var res = collection |
|
|
|
.Select(i => i.PregnancyHeartRate).ToList(); |
|
|
|
// 心率数据量必须30个以上才进行计算 |
|
|
|
if (res.Count < 30) |
|
|
|
if (res.Count < 30) |
|
|
|
{ |
|
|
|
_logger.LogInformation($"{serialNo} 心率数据不足,无法计算其众数"); |
|
|
|
return null; |
|
|
@@ -992,7 +919,7 @@ namespace HealthMonitor.Service.Biz.db |
|
|
|
|
|
|
|
var fhrMap = _mgrFhrPhrMapCache.GetHeartRatesMap(); |
|
|
|
var watchConfig = await _deviceCacheMgr.GetGpsDeviceWatchConfigCacheObjectBySerialNoAsync(serialNo, "0067"); |
|
|
|
if (watchConfig == null ) |
|
|
|
if (watchConfig == null) |
|
|
|
{ |
|
|
|
return null; |
|
|
|
} |
|
|
@@ -1000,7 +927,7 @@ namespace HealthMonitor.Service.Biz.db |
|
|
|
// "EDOC": "1720860180652",当前时间 - (EDOC - 280) days =怀孕时间 |
|
|
|
//edoc = edoc.ToString().Length == 10 ? edoc * 1000 : edoc; |
|
|
|
var edoc = DateTimeUtil.ToDateTime(watchConfig["EDOC"]!.ToString()); |
|
|
|
int pregnancyWeek = (DateTime.Now- edoc.AddDays(-280)).Days / 7; |
|
|
|
int pregnancyWeek = (DateTime.Now - edoc.AddDays(-280)).Days / 7; |
|
|
|
|
|
|
|
_logger.LogInformation($"IMEI {serialNo},EDOC:{edoc},NOW:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},SinceNOW:{edoc.AddDays(-280).ToString("yyyy-MM-dd HH:mm:ss")},怀孕周数 {pregnancyWeek}"); |
|
|
|
|
|
|
@@ -1010,19 +937,19 @@ namespace HealthMonitor.Service.Biz.db |
|
|
|
// 20-45周之间 |
|
|
|
if (pregnancyWeek >= 12 && pregnancyWeek <= 45) |
|
|
|
{ |
|
|
|
var map= fhrMap |
|
|
|
.Where(i => |
|
|
|
i.PregnancyPeriod![0] <= pregnancyWeek && |
|
|
|
i.PregnancyPeriod[1] >= pregnancyWeek && |
|
|
|
i.PregnancyHeartRateRange![0] <=mode && |
|
|
|
i.PregnancyHeartRateRange[1]>=mode) |
|
|
|
.FirstOrDefault(); |
|
|
|
var map = fhrMap |
|
|
|
.Where(i => |
|
|
|
i.PregnancyPeriod![0] <= pregnancyWeek && |
|
|
|
i.PregnancyPeriod[1] >= pregnancyWeek && |
|
|
|
i.PregnancyHeartRateRange![0] <= mode && |
|
|
|
i.PregnancyHeartRateRange[1] >= mode) |
|
|
|
.FirstOrDefault(); |
|
|
|
|
|
|
|
if (map != null) |
|
|
|
{ |
|
|
|
statMaxValueFprCoefficient = (float)Math.Round((decimal)map.FetalHeartRateRange![1] / res.Max(), 3); |
|
|
|
statMinValueFprCoefficient = (float)Math.Round((decimal)map.FetalHeartRateRange[0] / res.Min(), 3); |
|
|
|
StatModeAvgFprCoefficient = (float)Math.Round((decimal)map.FetalHeartRateAverage / mode, 3); |
|
|
|
StatModeAvgFprCoefficient = (float)Math.Round((decimal)map.FetalHeartRateAverage / mode, 3); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -1042,13 +969,91 @@ namespace HealthMonitor.Service.Biz.db |
|
|
|
StatStartTime = collection.OrderBy(i => i.Timestamp).Select(i => i.Timestamp).First(), |
|
|
|
StatEndTime = collection.OrderBy(i => i.Timestamp).Select(i => i.Timestamp).Last(), |
|
|
|
StatMaxValueFprCoefficient = statMaxValueFprCoefficient, |
|
|
|
StatMinValueFprCoefficient = statMinValueFprCoefficient, |
|
|
|
StatMinValueFprCoefficient = statMinValueFprCoefficient, |
|
|
|
StatModeAvgFprCoefficient = StatModeAvgFprCoefficient, |
|
|
|
Remark = string.Empty, |
|
|
|
SerialTailNumber = serialNo.Substring(serialNo.Length - 2) |
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 获取孕妇心率众数 |
|
|
|
/// </summary> |
|
|
|
/// <param name="serialNo"></param> |
|
|
|
/// <param name="days"></param> |
|
|
|
/// <returns></returns> |
|
|
|
//public async Task<int> GetPregnancyHeartRateModeAsync(string serialNo,int days=7) |
|
|
|
//{ |
|
|
|
// var tableName = typeof(PregnancyHeartRateModel) |
|
|
|
// .GetCustomAttribute<STableAttribute>()? |
|
|
|
// .STableName; |
|
|
|
// var daysAgo = DateTime.Now.AddDays(-days); |
|
|
|
// var res = await _clientSqlSugar |
|
|
|
// .Queryable<PregnancyHeartRateModel>() |
|
|
|
// .AS(tableName) |
|
|
|
// .Where(i=>i.SerialNumber.Equals(serialNo)) |
|
|
|
// .Where(i => i.Timestamp > daysAgo) |
|
|
|
// //.OrderByDescending(i => i.PregnancyHeartRate) |
|
|
|
// .Select(i =>i.PregnancyHeartRate) |
|
|
|
// .ToListAsync(); |
|
|
|
// // 心率数据量必须30个以上才进行计算 |
|
|
|
// if (res.Count < 30) return 0; |
|
|
|
|
|
|
|
// // 计算众数 |
|
|
|
// var mode = res.GroupBy(n => n) |
|
|
|
// .OrderByDescending(g => g.Count()) |
|
|
|
// .First() |
|
|
|
// .Key; |
|
|
|
|
|
|
|
// Console.WriteLine("众数是: " + mode); |
|
|
|
|
|
|
|
// // 如果有多个众数的情况 |
|
|
|
// var maxCount = res.GroupBy(n => n) |
|
|
|
// .Max(g => g.Count()); |
|
|
|
|
|
|
|
// var modes = res.GroupBy(n => n) |
|
|
|
// .Where(g => g.Count() == maxCount) |
|
|
|
// .Select(g => g.Key) |
|
|
|
// .ToList(); |
|
|
|
// // 多个众数,选择最接近平均数或中位数的众数 |
|
|
|
// if (modes.Count>1) |
|
|
|
// { |
|
|
|
// // 计算平均值 |
|
|
|
// double average = res.Average(); |
|
|
|
// Console.WriteLine("平均值是: " + average); |
|
|
|
|
|
|
|
// // 计算中位数 |
|
|
|
// double median; |
|
|
|
// int count = res.Count; |
|
|
|
// var sortedRes = res.OrderBy(n => n).ToList(); |
|
|
|
// if (count % 2 == 0) |
|
|
|
// { |
|
|
|
// // 偶数个元素,取中间两个数的平均值 |
|
|
|
// median = (sortedRes[count / 2 - 1] + sortedRes[count / 2]) / 2.0; |
|
|
|
// } |
|
|
|
// else |
|
|
|
// { |
|
|
|
// // 奇数个元素,取中间的数 |
|
|
|
// median = sortedRes[count / 2]; |
|
|
|
// } |
|
|
|
// Console.WriteLine("中位数是: " + median); |
|
|
|
|
|
|
|
// // 找出最接近平均值的众数 |
|
|
|
// //var closestToAverage = modes.OrderBy(m => Math.Abs(m - average)).First(); |
|
|
|
// //Console.WriteLine("最接近平均值的众数是: " + closestToAverage); |
|
|
|
|
|
|
|
// // 找出最接近中位数的众数 |
|
|
|
// var closestToMedian = modes.OrderBy(m => Math.Abs(m - median)).First(); |
|
|
|
// Console.WriteLine("最接近中位数的众数是: " + closestToMedian); |
|
|
|
// mode = closestToMedian; |
|
|
|
// } |
|
|
|
|
|
|
|
// return mode; |
|
|
|
//} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion |
|
|
|
} |
|
|
|
} |