X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=dive.c;h=31be3291d76c13647b4dec8607b51636a26eec81;hb=0f139718697035fa8e1b26f908403ad27bb36554;hp=bd1b92619198851b6bdc3f70b162c75f3af7cc48;hpb=d03a92728fb625a388ce4eb4d8e885c6fc40d55a;p=ext%2Fsubsurface.git diff --git a/dive.c b/dive.c index bd1b926..31be329 100644 --- a/dive.c +++ b/dive.c @@ -224,21 +224,57 @@ static void fixup_pressure(struct dive *dive, struct sample *sample) cyl->sample_end.mbar = pressure; } +/* + * If the cylinder tank pressures are within half a bar + * (about 8 PSI) of the sample pressures, we consider it + * to be a rounding error, and throw them away as redundant. + */ +static int same_rounded_pressure(pressure_t a, pressure_t b) +{ + return abs(a.mbar - b.mbar) <= 500; +} + struct dive *fixup_dive(struct dive *dive) { - int i; + int i,j; double depthtime = 0; int lasttime = 0; + int lastindex = -1; int start = -1, end = -1; int maxdepth = 0, mintemp = 0; int lastdepth = 0; - int lasttemp = 0; + int lasttemp = 0, lastpressure = 0; + int pressure_delta[MAX_CYLINDERS] = {INT_MAX, }; for (i = 0; i < dive->samples; i++) { struct sample *sample = dive->sample + i; int time = sample->time.seconds; int depth = sample->depth.mm; int temp = sample->temperature.mkelvin; + int pressure = sample->cylinderpressure.mbar; + int index = sample->cylinderindex; + + if (index == lastindex) { + /* Remove duplicate redundant pressure information */ + if (pressure == lastpressure) + sample->cylinderpressure.mbar = 0; + /* check for simply linear data in the samples + +INT_MAX means uninitialized, -INT_MAX means not linear */ + if (pressure_delta[index] != -INT_MAX && lastpressure) { + if (pressure_delta[index] == INT_MAX) { + pressure_delta[index] = abs(pressure - lastpressure); + } else { + int cur_delta = abs(pressure - lastpressure); + if (cur_delta && abs(cur_delta - pressure_delta[index]) > 150) { + /* ok the samples aren't just a linearisation + * between start and end */ + pressure_delta[index] = -INT_MAX; + } + } + } + } + lastindex = index; + lastpressure = pressure; if (lastdepth) end = time; @@ -270,6 +306,33 @@ struct dive *fixup_dive(struct dive *dive) lastdepth = depth; lasttime = time; } + /* if all the samples for a cylinder have pressure data that + * is basically equidistant throw out the sample cylinder pressure + * information but make sure we still have a valid start and end + * pressure + * this happens when DivingLog decides to linearalize the + * pressure between beginning and end and for strange reasons + * decides to put that in the sample data as if it came from + * the dive computer; we don't want that (we'll visualize with + * constant SAC rate instead) + * WARNING WARNING - I have only seen this in single tank dives + * --- maybe I should try to create a multi tank dive and see what + * --- divinglog does there - but the code right now is only tested + * --- for the single tank case */ + for (j = 0; j < MAX_CYLINDERS; j++) { + if (abs(pressure_delta[j]) != INT_MAX) { + cylinder_t *cyl = dive->cylinder + j; + for (i = 0; i < dive->samples; i++) + if (dive->sample[i].cylinderindex == j) + dive->sample[i].cylinderpressure.mbar = 0; + if (! cyl->start.mbar) + cyl->start.mbar = cyl->sample_start.mbar; + if (! cyl->end.mbar) + cyl->end.mbar = cyl->sample_end.mbar; + cyl->sample_start.mbar = 0; + cyl->sample_end.mbar = 0; + } + } if (end < 0) return dive; @@ -287,9 +350,9 @@ struct dive *fixup_dive(struct dive *dive) for (i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = dive->cylinder + i; add_cylinder_description(&cyl->type); - if (cyl->sample_start.mbar == cyl->start.mbar) + if (same_rounded_pressure(cyl->sample_start, cyl->start)) cyl->start.mbar = 0; - if (cyl->sample_end.mbar == cyl->end.mbar) + if (same_rounded_pressure(cyl->sample_end, cyl->end)) cyl->end.mbar = 0; }