/* * Calculate the sac rate between the two plot entries 'first' and 'last'. * * Everything in between has a cylinder pressure, and it's all the same * cylinder. */ static int sac_between(struct dive *dive, struct plot_data *first, struct plot_data *last) { int airuse; double pressuretime; pressure_t a, b; cylinder_t *cyl; if (first == last) return 0; /* Calculate air use - trivial */ a.mbar = GET_PRESSURE(first); b.mbar = GET_PRESSURE(last); cyl = dive->cylinder + first->cylinderindex; airuse = gas_volume(cyl, a) - gas_volume(cyl, b); if (airuse <= 0) return 0; /* Calculate depthpressure integrated over time */ pressuretime = 0.0; do { int depth = (first[0].depth + first[1].depth) / 2; int time = first[1].sec - first[0].sec; double atm = depth_to_atm(depth, dive); pressuretime += atm * time; } while (++first < last); /* Turn "atmseconds" into "atmminutes" */ pressuretime /= 60; /* SAC = mliter per minute */ return rint(airuse / pressuretime); }
/* Get local sac-rate (in ml/min) between entry1 and entry2 */ static int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) { int index = entry1->cylinderindex; cylinder_t *cyl; int duration = entry2->sec - entry1->sec; int depth, airuse; pressure_t a, b; double atm; if (entry2->cylinderindex != index) return 0; if (duration <= 0) return 0; a.mbar = GET_PRESSURE(entry1); b.mbar = GET_PRESSURE(entry2); if (!b.mbar || a.mbar <= b.mbar) return 0; /* Mean pressure in ATM */ depth = (entry1->depth + entry2->depth) / 2; atm = depth_to_atm(depth, dive); cyl = dive->cylinder + index; airuse = gas_volume(cyl, a) - gas_volume(cyl, b); /* milliliters per minute */ return airuse / atm * 60 / duration; }
volume_t get_gas_used(struct dive *dive) { int idx; volume_t gas_used = { 0 }; for (idx = 0; idx < MAX_CYLINDERS; idx++) { cylinder_t *cyl = &dive->cylinder[idx]; pressure_t start, end; start = cyl->start.mbar ? cyl->start : cyl->sample_start; end = cyl->end.mbar ?cyl->sample_end : cyl->sample_end; if (start.mbar && end.mbar) gas_used.mliter += gas_volume(cyl, start) - gas_volume(cyl, end); } return gas_used; }
void get_gas_used(struct dive *dive, volume_t gases[MAX_CYLINDERS]) { int idx; for (idx = 0; idx < MAX_CYLINDERS; idx++) { cylinder_t *cyl = &dive->cylinder[idx]; pressure_t start, end; if (!is_cylinder_used(dive, idx)) continue; 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) gases[idx].mliter = gas_volume(cyl, start) - gas_volume(cyl, end); } }
/* we try to show the data from the currently selected divecomputer * right now for some values (e.g., surface pressure) we could fall back * to dive data, but for consistency we don't. */ static void show_single_dive_stats(struct dive *dive) { char buf[256]; double value; int decimals; const char *unit; int idx, offset, gas_used, mbar; struct dive *prev_dive; struct tm tm; struct divecomputer *dc; process_all_dives(dive, &prev_dive); if (!dive) return; dc = select_dc(&dive->dc); utc_mkdate(dive->when, &tm); snprintf(buf, sizeof(buf), /*++GETTEXT 80 chars: weekday, monthname, day, year, hour, min */ _("%1$s, %2$s %3$d, %4$d %5$2d:%6$02d"), weekday(tm.tm_wday), monthname(tm.tm_mon), tm.tm_mday, tm.tm_year + 1900, tm.tm_hour, tm.tm_min); set_label(single_w.date, buf); set_label(single_w.dive_time, _("%d min"), (dive->duration.seconds + 30) / 60); if (prev_dive) set_label(single_w.surf_intv, get_time_string(dive->when - (prev_dive->when + prev_dive->duration.seconds), 4)); else set_label(single_w.surf_intv, _("unknown")); value = get_depth_units(dc->maxdepth.mm, &decimals, &unit); set_label(single_w.max_depth, "%.*f %s", decimals, value, unit); value = get_depth_units(dc->meandepth.mm, &decimals, &unit); set_label(single_w.avg_depth, "%.*f %s", decimals, value, unit); set_label(single_w.viz, star_strings[dive->visibility]); if (dc->watertemp.mkelvin) { value = get_temp_units(dc->watertemp.mkelvin, &unit); set_label(single_w.water_temp, "%.1f %s", value, unit); } else { set_label(single_w.water_temp, ""); } if (dc->airtemp.mkelvin) { value = get_temp_units(dc->airtemp.mkelvin, &unit); set_label(single_w.air_temp, "%.1f %s", value, unit); } else { if (dive->airtemp.mkelvin) { value = get_temp_units(dive->airtemp.mkelvin, &unit); set_label(single_w.air_temp, "%.1f %s", value, unit); } else { set_label(single_w.air_temp, ""); } } mbar = dc->surface_pressure.mbar; /* it would be easy to get dive data here: * if (!mbar) * mbar = get_surface_pressure_in_mbar(dive, FALSE); */ if (mbar) { set_label(single_w.air_press, "%d mbar", mbar); } else { set_label(single_w.air_press, ""); } value = get_volume_units(dive->sac, &decimals, &unit); if (value > 0) set_label(single_w.sac, _("%.*f %s/min"), decimals, value, unit); else set_label(single_w.sac, ""); set_label(single_w.otu, "%d", dive->otu); offset = 0; gas_used = 0; buf[0] = '\0'; /* for the O2/He readings just create a list of them */ for (idx = 0; idx < MAX_CYLINDERS; idx++) { cylinder_t *cyl = &dive->cylinder[idx]; pressure_t start, end; start = cyl->start.mbar ? cyl->start : cyl->sample_start; end = cyl->end.mbar ?cyl->sample_end : cyl->sample_end; if (!cylinder_none(cyl)) { /* 0% O2 strangely means air, so 21% - I don't like that at all */ int o2 = get_o2(&cyl->gasmix); int he = get_he(&cyl->gasmix); if (offset > 0) { snprintf(buf+offset, 80-offset, ", "); offset += 2; } snprintf(buf+offset, 80-offset, "%d/%d", (o2 + 5) / 10, (he + 5) / 10); offset = strlen(buf); } /* and if we have size, start and end pressure, we can * calculate the total gas used */ if (start.mbar && end.mbar) gas_used += gas_volume(cyl, start) - gas_volume(cyl, end); } set_label(single_w.o2he, buf); if (gas_used) { value = get_volume_units(gas_used, &decimals, &unit); set_label(single_w.gas_used, "%.*f %s", decimals, value, unit); } else { set_label(single_w.gas_used, ""); } }