From a93641b7222e767d6a3a1be598cd8099d8517059 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Thu, 22 Sep 2011 13:45:53 -0700 Subject: Calculate OTUs for every dive The calculation assumes that the cylinderindex in each sample tells us which PO2 the dive was breathing at that time. This needs to be verified with dives where there is an actual gas switch. No idea where to display them, yet. Far fewer people will care about this than care about SAC - does this still rate a spot in the dive_list? I guess I could make it part of the dive_info - but it's not editable. It doesn't seem to fit with the equipment page (even though this is the one editable field that is related - nitrox %) Signed-off-by: Dirk Hohndel --- dive.h | 6 ++++++ divelist.c | 21 +++++++++++++++++++++ parse-xml.c | 4 ++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/dive.h b/dive.h index e1a5bc007..1766cff82 100644 --- a/dive.h +++ b/dive.h @@ -134,6 +134,11 @@ static inline int to_PSI(pressure_t pressure) return pressure.mbar * 0.0145037738 + 0.5; } +static inline double to_ATM(pressure_t pressure) +{ + return pressure.mbar / 1013.25; +} + struct sample { duration_t time; depth_t depth; @@ -156,6 +161,7 @@ struct dive { depth_t visibility; temperature_t airtemp, watertemp; cylinder_t cylinder[MAX_CYLINDERS]; + double otu; int samples, alloc_samples; struct sample sample[]; }; diff --git a/divelist.c b/divelist.c index 51646c460..c2194bbec 100644 --- a/divelist.c +++ b/divelist.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "divelist.h" #include "dive.h" @@ -222,6 +223,25 @@ static void sac_data_func(GtkTreeViewColumn *col, g_object_set(renderer, "text", buffer, NULL); } +/* calculate OTU for a dive */ +static double calculate_otu(struct dive *dive) +{ + int i; + double otu = 0.0; + + for (i = 1; i < dive->samples; i++) { + int t; + double po2; + struct sample *sample = dive->sample + i; + struct sample *psample = sample - 1; + t = sample->time.seconds - psample->time.seconds; + po2 = dive->cylinder[sample->cylinderindex].gasmix.o2.permille / 1000.0 * + (sample->depth.mm + 10000) / 10000.0; + if (po2 >= 0.5) + otu += pow(po2 - 0.5, 0.83) * t / 30.0; + } + return otu; +} /* * Return air usage (in liters). */ @@ -389,6 +409,7 @@ static void fill_dive_list(void) for (i = 0; i < dive_table.nr; i++) { struct dive *dive = dive_table.dives[i]; + dive->otu = calculate_otu(dive); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, DIVE_INDEX, i, diff --git a/parse-xml.c b/parse-xml.c index 1eb6e95fd..8f916b09a 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -1051,7 +1051,7 @@ static void match_standard_cylinder(cylinder_type_t *type) return; cuft = type->size.mliter / 28317.0; - cuft *= type->workingpressure.mbar / 1013.25; + cuft *= to_ATM(type->workingpressure); psi = type->workingpressure.mbar / 68.95; switch (psi) { @@ -1106,7 +1106,7 @@ static void sanitize_cylinder_type(cylinder_type_t *type) if (input_units.volume == CUFT || import_source == SUUNTO) { volume_of_air = type->size.mliter * 28.317; /* milli-cu ft to milliliter */ - atm = type->workingpressure.mbar / 1013.25; /* working pressure in atm */ + atm = to_ATM(type->workingpressure); /* working pressure in atm */ volume = volume_of_air / atm; /* milliliters at 1 atm: "true size" */ type->size.mliter = volume + 0.5; } -- cgit v1.2.3-70-g09d2 From d5c86ebe3dd67397f0f61d57ae9c07d995c38728 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Thu, 22 Sep 2011 14:02:26 -0700 Subject: Add OTU to divelist and change OTUs to be tracked as int, not double Signed-off-by: Dirk Hohndel --- dive.h | 2 +- divelist.c | 46 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/dive.h b/dive.h index 1766cff82..5cb324123 100644 --- a/dive.h +++ b/dive.h @@ -161,7 +161,7 @@ struct dive { depth_t visibility; temperature_t airtemp, watertemp; cylinder_t cylinder[MAX_CYLINDERS]; - double otu; + int otu; int samples, alloc_samples; struct sample sample[]; }; diff --git a/divelist.c b/divelist.c index c2194bbec..13257a437 100644 --- a/divelist.c +++ b/divelist.c @@ -45,6 +45,7 @@ enum { DIVE_CYLINDER, DIVE_NITROX, /* int: in permille */ DIVE_SAC, /* int: in ml/min */ + DIVE_OTU, /* int: in OTUs */ DIVE_LOCATION, /* "2nd Cathedral, Lanai" */ DIVELIST_COLUMNS }; @@ -223,8 +224,30 @@ static void sac_data_func(GtkTreeViewColumn *col, g_object_set(renderer, "text", buffer, NULL); } +/* Render the OTU data (integer value of "OTU") */ +static void otu_data_func(GtkTreeViewColumn *col, + GtkCellRenderer *renderer, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + int value; + char buffer[16]; + + gtk_tree_model_get(model, iter, DIVE_OTU, &value, -1); + + if (!value) { + g_object_set(renderer, "text", "", NULL); + return; + } + + snprintf(buffer, sizeof(buffer), "%d", value); + + g_object_set(renderer, "text", buffer, NULL); +} + /* calculate OTU for a dive */ -static double calculate_otu(struct dive *dive) +static int calculate_otu(struct dive *dive) { int i; double otu = 0.0; @@ -240,7 +263,7 @@ static double calculate_otu(struct dive *dive) if (po2 >= 0.5) otu += pow(po2 - 0.5, 0.83) * t / 30.0; } - return otu; + return otu + 0.5; } /* * Return air usage (in liters). @@ -330,6 +353,7 @@ static void fill_one_dive(struct dive *dive, DIVE_LOCATION, location, DIVE_CYLINDER, cylinder, DIVE_SAC, sac, + DIVE_OTU, dive->otu, -1); } @@ -501,6 +525,7 @@ GtkWidget *dive_list_create(void) G_TYPE_STRING, /* Cylinder */ G_TYPE_INT, /* Nitrox */ G_TYPE_INT, /* SAC */ + G_TYPE_INT, /* OTU */ G_TYPE_STRING /* Location */ ); dive_list.tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dive_list.model)); @@ -511,14 +536,15 @@ GtkWidget *dive_list_create(void) gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_BROWSE); gtk_widget_set_size_request(dive_list.tree_view, 200, 200); - dive_list.date = divelist_column(&dive_list, DIVE_DATE, "Date", date_data_func, PANGO_ALIGN_LEFT); - dive_list.depth = divelist_column(&dive_list, DIVE_DEPTH, "ft", depth_data_func, PANGO_ALIGN_RIGHT); - dive_list.duration = divelist_column(&dive_list, DIVE_DURATION, "min", duration_data_func, PANGO_ALIGN_RIGHT); - dive_list.temperature = divelist_column(&dive_list, DIVE_TEMPERATURE, UTF8_DEGREE "F", temperature_data_func, PANGO_ALIGN_RIGHT); - dive_list.cylinder = divelist_column(&dive_list, DIVE_CYLINDER, "Cyl", NULL, PANGO_ALIGN_CENTER); - dive_list.nitrox = divelist_column(&dive_list, DIVE_NITROX, "O" UTF8_SUBSCRIPT_2 "%", nitrox_data_func, PANGO_ALIGN_CENTER); - dive_list.sac = divelist_column(&dive_list, DIVE_SAC, "SAC", sac_data_func, PANGO_ALIGN_CENTER); - dive_list.location = divelist_column(&dive_list, DIVE_LOCATION, "Location", NULL, PANGO_ALIGN_LEFT); + dive_list.date = divelist_column(&dive_list, DIVE_DATE, "Date", date_data_func, PANGO_ALIGN_LEFT, TRUE); + dive_list.depth = divelist_column(&dive_list, DIVE_DEPTH, "ft", depth_data_func, PANGO_ALIGN_RIGHT, TRUE); + dive_list.duration = divelist_column(&dive_list, DIVE_DURATION, "min", duration_data_func, PANGO_ALIGN_RIGHT, TRUE); + dive_list.temperature = divelist_column(&dive_list, DIVE_TEMPERATURE, UTF8_DEGREE "F", temperature_data_func, PANGO_ALIGN_RIGHT, TRUE); + dive_list.cylinder = divelist_column(&dive_list, DIVE_CYLINDER, "Cyl", NULL, PANGO_ALIGN_CENTER, TRUE); + dive_list.nitrox = divelist_column(&dive_list, DIVE_NITROX, "O" UTF8_SUBSCRIPT_2 "%", nitrox_data_func, PANGO_ALIGN_CENTER, TRUE); + dive_list.sac = divelist_column(&dive_list, DIVE_SAC, "SAC", sac_data_func, PANGO_ALIGN_CENTER, TRUE); + dive_list.sac = divelist_column(&dive_list, DIVE_OTU, "OTU", otu_data_func, PANGO_ALIGN_CENTER, FALSE); + dive_list.location = divelist_column(&dive_list, DIVE_LOCATION, "Location", NULL, PANGO_ALIGN_LEFT, TRUE); fill_dive_list(); -- cgit v1.2.3-70-g09d2 From dc2a0c1909727a1557b8f03e6b6ac3e427ebe4b7 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Mon, 26 Sep 2011 16:05:24 -0700 Subject: Make OTU column invisible by default Signed-off-by: Dirk Hohndel --- divelist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/divelist.c b/divelist.c index 13257a437..bb2a3e3a1 100644 --- a/divelist.c +++ b/divelist.c @@ -469,7 +469,7 @@ typedef void (*data_func_t)(GtkTreeViewColumn *col, gpointer data); static GtkTreeViewColumn *divelist_column(struct DiveList *dl, int index, const char *title, - data_func_t data_func, PangoAlignment align) + data_func_t data_func, PangoAlignment align, gboolean visible) { GtkCellRenderer *renderer; GtkTreeViewColumn *col; @@ -499,6 +499,7 @@ static GtkTreeViewColumn *divelist_column(struct DiveList *dl, int index, const break; } gtk_cell_renderer_set_alignment(GTK_CELL_RENDERER(renderer), xalign, 0.5); + gtk_tree_view_column_set_visible(col, visible); gtk_tree_view_append_column(GTK_TREE_VIEW(dl->tree_view), col); return col; } -- cgit v1.2.3-70-g09d2