Issues with SAC?

Linus Torvalds torvalds at linux-foundation.org
Mon Jul 17 18:46:46 PDT 2017


On Mon, Jul 17, 2017 at 2:53 PM, Linus Torvalds
<torvalds at linux-foundation.org> wrote:
>
> But I could easily add some logic that says "if some cylinder is used
> and doesn't have pressure or size data, airuse is meaningless".

Actually, I just went the other direction instead.

Just ignore cylinders that we don't have data for, and calculate SAC
for the parts we *do* have data for.

So if you don't have deco bottle information and only the travel gas,
the SAC for the dive will be the average SAC for the time when you
used the travel gas.

We had most of the infrastructure for this in place anyway (since we
calculate the gas use and SAC per cylinder for the statistics page),
so it wasn't really any extra work compared to just invalidating the
SAC calculation when some cylinder use wasn't known.

Very lightly tested patch attached. Somebody who has more dives like
this really should check the results. And anybody could check the
logic..

                   Linus
-------------- next part --------------
 core/divelist.c | 63 ++++++++++++++++++++++++++-------------------------------
 1 file changed, 29 insertions(+), 34 deletions(-)

diff --git a/core/divelist.c b/core/divelist.c
index 4f253039..1d1610db 100644
--- a/core/divelist.c
+++ b/core/divelist.c
@@ -46,6 +46,7 @@
 #include "planner.h"
 #include "qthelperfromc.h"
 #include "git-access.h"
+#include "statistics.h"
 
 static short dive_list_changed = false;
 
@@ -263,53 +264,47 @@ static int calculate_cns(struct dive *dive)
 	dive->cns = lrint(cns);
 	return dive->cns;
 }
-/*
- * Return air usage (in liters).
- */
-static double calculate_airuse(struct dive *dive)
-{
-	int airuse = 0;
-	int i;
 
+static int calculate_sac(struct dive *dive)
+{
+	volume_t gases[MAX_CYLINDERS] = {};
+	int mean[MAX_CYLINDERS], duration[MAX_CYLINDERS];
+	double duration_depth;
+	int i, total_duration, meandepth, gasuse;
+	double pressure, sac;
+
+	get_gas_used(dive, gases);
+	per_cylinder_mean_depth(dive, select_dc(dive), mean, duration);
+
+	gasuse = 0;
+	total_duration = 0;
+	duration_depth = 0;
 	for (i = 0; i < MAX_CYLINDERS; i++) {
-		pressure_t start, end;
-		cylinder_t *cyl = dive->cylinder + i;
+		int time = duration[i];
+		volume_t vol = gases[i];
 
-		start = cyl->start.mbar ? cyl->start : cyl->sample_start;
-		end = cyl->end.mbar ? cyl->end : cyl->sample_end;
-		if (!end.mbar || start.mbar <= end.mbar)
+		if (!time)
 			continue;
-
-		airuse += gas_volume(cyl, start) - gas_volume(cyl, end);
+		if (!vol.mliter)
+			continue;
+		gasuse += vol.mliter;
+		total_duration += time;
+		duration_depth += (double) time * mean[i];
 	}
-	return airuse / 1000.0;
-}
-
-/* this only uses the first divecomputer to calculate the SAC rate */
-static int calculate_sac(struct dive *dive)
-{
-	struct divecomputer *dc = &dive->dc;
-	double airuse, pressure, sac;
-	int duration, meandepth;
 
-	airuse = calculate_airuse(dive);
-	if (!airuse)
+	if (!gasuse)
 		return 0;
-
-	duration = dc->duration.seconds;
-	if (!duration)
-		return 0;
-
-	meandepth = dc->meandepth.mm;
-	if (!meandepth)
+	if (!total_duration)
 		return 0;
+	meandepth = lrint(duration_depth / total_duration);
 
 	/* Mean pressure in ATM (SAC calculations are in atm*l/min) */
 	pressure = depth_to_atm(meandepth, dive);
-	sac = airuse / pressure * 60 / duration;
 
 	/* milliliters per minute.. */
-	return lrint(sac * 1000);
+	sac = gasuse / pressure * 60 / total_duration;
+
+	return lrint(sac);
 }
 
 /* for now we do this based on the first divecomputer */


More information about the subsurface mailing list