173 TLinearFitter fitter(nDim,
"1 ++ x0 ++ x1",
"");
174 std::array<size_t, dcs::Temperature::SensorsPerSide> startPos{};
181 const int lastIntervalDuration = (refTimeMax - refTime) % fitInterval;
184 const bool procLastInt = (lastIntervalDuration / fitInterval > 0.5);
185 int numIntervals = (refTimeMax - refTime) / fitInterval + procLastInt;
186 if (numIntervals == 0) {
191 std::vector<double> xVals;
192 std::vector<double> temperatures;
193 xVals.reserve(2 * 1000);
194 temperatures.reserve(1000);
196 for (
int interval = 0; interval < numIntervals; ++interval) {
201 temperatures.clear();
208 const auto& sensor =
raw[iSensor + sensorOffset];
210 LOGP(
debug,
"sensor {}, start {}, size {}", sensor.sensorNumber, startPos[iSensor], sensor.data.size());
211 while (startPos[iSensor] < sensor.data.size()) {
212 const auto& dataPoint = sensor.data[startPos[iSensor]];
213 if (((dataPoint.time - timeStart) >= fitInterval) && (interval != numIntervals - 1)) {
214 LOGP(
debug,
"sensor {}, {} - {} >= {}", sensor.sensorNumber, dataPoint.time, timeStart, fitInterval);
217 firstTime = std::min(firstTime, dataPoint.time);
218 LastTime = std::max(LastTime, dataPoint.time);
219 const auto temperature = dataPoint.value;
222 if (temperature < 15 || temperature > 25) {
226 xVals.emplace_back(
pos.x);
227 xVals.emplace_back(
pos.y);
228 temperatures.emplace_back(temperature);
231 if (firstTime < std::numeric_limits<dcs::TimeStampType>::max() && !temperatures.empty()) {
232 const bool fitOk = makeFit(fitter, nDim, xVals, temperatures);
236 auto& stat = stats.data.emplace_back();
237 stat.time = (firstTime + LastTime) / 2;
238 stat.value.mean = fitter.GetParameter(0);
239 stat.value.gradX = fitter.GetParameter(1);
240 stat.value.gradY = fitter.GetParameter(2);
243 const float maxDeltaT = 1;
244 const float meanTemp = fitter.GetParameter(0);
245 const bool isDataGood = std::all_of(temperatures.begin(), temperatures.end(), [meanTemp, maxDeltaT](
double t) { return std::abs(t - meanTemp) < maxDeltaT; });
249 std::vector<double> xVals2;
250 std::vector<double> temperatures2;
251 xVals2.reserve(xVals.size());
252 temperatures2.reserve(temperatures.size());
253 for (
int i = 0;
i < temperatures.size(); ++
i) {
254 if (std::abs(temperatures[
i] - meanTemp) < maxDeltaT) {
255 const int idx = 2 *
i;
256 xVals2.emplace_back(xVals[idx]);
257 xVals2.emplace_back(xVals[idx + 1]);
258 temperatures2.emplace_back(temperatures[
i]);
261 const bool fitOk2 = makeFit(fitter, nDim, xVals2, temperatures2);
263 stat.value.mean = fitter.GetParameter(0);
264 stat.value.gradX = fitter.GetParameter(1);
265 stat.value.gradY = fitter.GetParameter(2);
375 tStart = tStart / 1000 * 1000;
377 const int minPointsRef = 50;
382 int nIntervals = std::round((tEnd - tStart) / timeInterval);
383 if (nIntervals == 0) {
386 std::vector<ULong64_t>
times;
387 times.reserve(nIntervals);
388 for (
int i = 0;
i < nIntervals; ++
i) {
389 times.emplace_back(tStart + (
i + 0.5) * timeInterval);
393 const int minPoints = 4;
399 std::pair<std::vector<float>, std::vector<TimeStampType>> cavernAtmosPressure12;
400 std::pair<std::vector<float>, std::vector<TimeStampType>> cavernAtmosPressure1S;
401 std::pair<std::vector<float>, std::vector<TimeStampType>> cavernAtmosPressure2S;
402 cavernAtmosPressure12.first.reserve(nIntervals);
403 cavernAtmosPressure1S.first.reserve(nIntervals);
404 cavernAtmosPressure2S.first.reserve(nIntervals);
405 cavernAtmosPressure12.second.reserve(nIntervals);
406 cavernAtmosPressure1S.second.reserve(nIntervals);
407 cavernAtmosPressure2S.second.reserve(nIntervals);
409 for (
int i = 0;
i < nIntervals;
i++) {
411 const int maxDist = 600 * 1000;
412 const bool cavernOk = (cavernAtmosPressureStats.median[
i] > 0) && (cavernAtmosPressureStats.closestDistanceL[
i] < maxDist) && (cavernAtmosPressureStats.closestDistanceR[
i] < maxDist);
413 const bool cavern2Ok = (cavernAtmosPressure2Stats.median[
i] > 0) && (cavernAtmosPressure2Stats.closestDistanceL[
i] < maxDist) && (cavernAtmosPressure2Stats.closestDistanceR[
i] < maxDist);
414 const bool surfaceOk = (surfaceAtmosPressureStats.median[
i] > 0) && (surfaceAtmosPressureStats.closestDistanceL[
i] < maxDist) && (surfaceAtmosPressureStats.closestDistanceR[
i] < maxDist);
416 if (cavernOk && cavern2Ok) {
417 cavernAtmosPressure12.first.emplace_back(cavernAtmosPressureStats.median[
i] - cavernAtmosPressure2Stats.median[
i]);
418 cavernAtmosPressure12.second.emplace_back(
times[
i]);
420 if (cavernOk && surfaceOk) {
421 cavernAtmosPressure1S.first.emplace_back(cavernAtmosPressureStats.median[
i] - surfaceAtmosPressureStats.median[
i]);
422 cavernAtmosPressure1S.second.emplace_back(
times[
i]);
424 if (cavern2Ok && surfaceOk) {
425 cavernAtmosPressure2S.first.emplace_back(cavernAtmosPressure2Stats.median[
i] - surfaceAtmosPressureStats.median[
i]);
426 cavernAtmosPressure2S.second.emplace_back(
times[
i]);
440 const float maxDist = 20 * timeInterval;
441 const float maxDiff = 0.2;
442 std::pair<std::vector<float>, std::vector<TimeStampType>> robustPressureTmp;
443 robustPressureTmp.first.reserve(nIntervals);
444 robustPressureTmp.second.reserve(nIntervals);
445 std::vector<uint8_t> isOk(nIntervals);
447 for (
int i = 0;
i < nIntervals; ++
i) {
449 const float delta12 = cavernAtmosPressureStats.median[
i] - cavernAtmosPressure2Stats.median[
i] - cavernAtmosPressure12Stats.median[
i];
450 const float delta1S = cavernAtmosPressureStats.median[
i] - surfaceAtmosPressureStats.median[
i] - cavernAtmosPressure1SStats.median[
i];
451 const float delta2S = cavernAtmosPressure2Stats.median[
i] - surfaceAtmosPressureStats.median[
i] - cavernAtmosPressure2SStats.median[
i];
453 const auto distCavernAtmosPressureL = cavernAtmosPressureStats.closestDistanceL[
i];
454 const auto distCavernAtmosPressure2L = cavernAtmosPressure2Stats.closestDistanceL[
i];
455 const auto distSurfaceAtmosPressureL = surfaceAtmosPressureStats.closestDistanceL[
i];
456 const auto distCavernAtmosPressureR = cavernAtmosPressureStats.closestDistanceR[
i];
457 const auto distCavernAtmosPressure2R = cavernAtmosPressure2Stats.closestDistanceR[
i];
458 const auto distSurfaceAtmosPressureR = surfaceAtmosPressureStats.closestDistanceR[
i];
461 const bool cavernDistOk = (cavernAtmosPressureStats.median[
i] > 0) && ((distCavernAtmosPressureL < maxDist) || (distCavernAtmosPressureR < maxDist));
462 const bool cavern2DistOk = (cavernAtmosPressure2Stats.median[
i] > 0) && ((distCavernAtmosPressure2L < maxDist) || (distCavernAtmosPressure2R < maxDist));
463 const bool surfaceDistOk = (surfaceAtmosPressureStats.median[
i] > 0) && ((distSurfaceAtmosPressureL < maxDist) || (distSurfaceAtmosPressureR < maxDist));
464 const bool onlyOneSensor = (cavernDistOk + cavern2DistOk + surfaceDistOk) == 1;
466 uint8_t maskIsOkTmp = 0;
467 const int cavernBit = 0;
468 const int cavern2Bit = 1;
469 const int surfaceBit = 2;
473 if (((std::abs(delta12) < maxDiff) && (cavernDistOk && cavern2DistOk)) || onlyOneSensor) {
475 maskIsOkTmp |= (1 << cavernBit);
478 maskIsOkTmp |= (1 << cavern2Bit);
484 if ((std::abs(delta1S) < maxDiff) && ((cavernDistOk && surfaceDistOk)) || onlyOneSensor) {
486 maskIsOkTmp |= (1 << cavernBit);
489 maskIsOkTmp |= (1 << surfaceBit);
495 if ((std::abs(delta2S) < maxDiff) && ((cavern2DistOk && surfaceDistOk)) || onlyOneSensor) {
497 maskIsOkTmp |= (1 << cavern2Bit);
500 maskIsOkTmp |= (1 << surfaceBit);
506 int pressureCount = 0;
507 if ((maskIsOkTmp >> cavernBit) & 1) {
508 pressure += cavernAtmosPressureStats.median[
i];
512 if ((maskIsOkTmp >> cavern2Bit) & 1) {
513 pressure += cavernAtmosPressure2Stats.median[
i] + cavernAtmosPressure12Stats.median[
i];
517 if ((maskIsOkTmp >> surfaceBit) & 1) {
518 pressure += surfaceAtmosPressureStats.median[
i] + cavernAtmosPressure1SStats.median[
i];
522 isOk[
i] = maskIsOkTmp;
523 if (pressureCount > 0) {
524 pressure /= pressureCount;
525 robustPressureTmp.first.emplace_back(pressure);
526 robustPressureTmp.second.emplace_back(
times[
i]);
538 while (
times.size() > 1 && !robBuffTimes.empty() &&
times.back() + lookaheadMargin > robBuffTimes.back()) {
541 isOk.resize(
times.size());
560 pOut.
isOk = std::move(isOk);