Commit 871fc0ef authored by firegnom's avatar firegnom
Browse files

added END calculations

parent 9d9dc666
......@@ -35,6 +35,7 @@ import javax.swing.event.ChangeListener;
import java.lang.Math.*;
import mvplan.gas.Gas;
import mvplan.main.*;
import mvplan.util.GasUtils;
public class GasDialog extends JDialog
implements ActionListener, FocusListener, ChangeListener
......@@ -71,7 +72,7 @@ public class GasDialog extends JDialog
maxMOD = Mvplan.prefs.getMaxMOD(); // Get max pO2
if(gas.getMod()>0.0)
sliderMOD=Gas.getppO2(gas.getFO2(),gas.getMod());
sliderMOD=GasUtils.getppO2(gas.getFO2(),gas.getMod());
else
sliderMOD=maxMOD;
......@@ -195,7 +196,7 @@ public class GasDialog extends JDialog
//System.out.println(e.getActionCommand());
if ("ok".equals(e.getActionCommand())) {
try {
canClose = Gas.validate(
canClose = GasUtils.validate(
h = Double.parseDouble(inputHe.getText())/100.0,
o = Double.parseDouble(inputO2.getText())/100.0,
m= Double.parseDouble(inputMod.getText()));
......@@ -222,7 +223,7 @@ public class GasDialog extends JDialog
o = Double.parseDouble(inputO2.getText())/100.0;
} catch (NumberFormatException ex) { }
if (o>0.0) {
inputMod.setText(String.valueOf( (int)Math.round(Gas.getMod(o,sliderMOD))));
inputMod.setText(String.valueOf( (int)Math.round(GasUtils.getMod(o,sliderMOD))));
}
validateForm();
}
......@@ -238,7 +239,7 @@ public class GasDialog extends JDialog
mod = Double.parseDouble(inputMod.getText());
} catch (NumberFormatException ex) { }
if (fO2>0.0) {
sliderMOD=Gas.getppO2(fO2,mod);
sliderMOD=GasUtils.getppO2(fO2,mod);
//System.out.println("focusLost(): set sliderMOD="+sliderMOD);
ppO2Slider.setValue((int)Math.round(sliderMOD*100));
}
......@@ -257,7 +258,7 @@ public class GasDialog extends JDialog
okButton.setEnabled(false);
return false;
}
check = Gas.validate(h,o,m);
check = GasUtils.validate(h,o,m);
okButton.setEnabled(check);
return check;
}
......@@ -276,11 +277,11 @@ public class GasDialog extends JDialog
// Parse as integer because we want integer numbers input
int n=Integer.parseInt(field.getText());
if (field==(inputMod))
fieldPassed = Gas.validate("mod",(double)n);
fieldPassed = GasUtils.validate("mod",(double)n);
else if (field == inputHe)
fieldPassed = Gas.validate("fHe",((double)n)/100);
fieldPassed = GasUtils.validate("fHe",((double)n)/100);
else if (field == inputO2)
fieldPassed = Gas.validate("fO2",((double)n)/100);
fieldPassed = GasUtils.validate("fO2",((double)n)/100);
} catch (NumberFormatException e) {
fieldPassed=false;
}
......@@ -309,7 +310,7 @@ public class GasDialog extends JDialog
o = 0.0;
}
if (o>0.0) {
inputMod.setText(String.valueOf( (int)Math.round(Gas.getMod(o,sliderMOD))));
inputMod.setText(String.valueOf( (int)Math.round(GasUtils.getMod(o,sliderMOD))));
//System.out.println("stateChanged(): sliderMOD="+sliderMOD+" inputMod:"+inputMod.getText());
validateForm();
}
......
......@@ -29,6 +29,7 @@ import java.io.*;
import java.text.MessageFormat;
import mvplan.main.MvplanInstance;
import mvplan.prefs.Prefs;
import mvplan.util.GasUtils;
/**
*
......@@ -74,64 +75,7 @@ public class Gas implements Comparable<Gas>, Serializable, Cloneable
public Gas() {
}
/**
* Method to validate a field for limits only
*/
public static boolean validate(String field, double value) {
if(field.equals("fHe") || field.equals("fO2"))
return ( value >= 0.0 && value <=1.0);
if(field.equals("mod"))
// Need to hard code nominal max value due to potential of prefs not being fully set up when this is called
return (value >=0.0 && value <= 900.0);
return false;
}
/**
* Method to validate all inputs (fO2, fHe and MOD)
*/
public static boolean validate(double fHe, double fO2, double mod) {
boolean passed=true;
Prefs prefs = MvplanInstance.getPrefs();
// Check individual fields for bounds
passed = (passed && validate("fHe",fHe));
passed = (passed && validate("fO2",fO2));
passed = (passed && validate("mod",mod));
if(!passed) return false;
// Check combined fractions
passed = (passed && (fHe+fO2)<=1.0);
if(!passed) return false;
// Check MOD for sensible value
if(fO2 == 0.0 && mod == 0.0) // Leave empty gases alone to allow construction
return passed;
if(MvplanInstance.getMvplan() != null && prefs != null) { // Need to check that prefs exists. We can get to this point during the initilisation of the prefs object
double d = ((mod+prefs.getPConversion())/prefs.getPConversion()*fO2);
passed = (d <= prefs.getMaxMOD()+0.05); // Tolerance of 0.05 to prevent unneccessary failure due to rounding
}
return passed;
}
/**
* Method to get a maximum MOD based on O2 fraction
*/
public static double getMaxMod(double o) {
Prefs prefs = MvplanInstance.getPrefs();
return (prefs.getMaxMOD()/o * prefs.getPConversion())-prefs.getPConversion();
}
/**
* Method to get a MOD based on O2 fraction and maximum ppO2
*/
public static double getMod(double fO2, double ppO2) {
Prefs prefs = MvplanInstance.getPrefs();
return (ppO2/fO2 * prefs.getPConversion())-prefs.getPConversion();
}
/**
* Method to get a ppO2 based on O2 fraction and MOD
*/
public static double getppO2(double f, double m) {
Prefs prefs = MvplanInstance.getPrefs();
return ( (m+prefs.getPConversion())*f/prefs.getPConversion());
}
/**
* Override the clone method to make it public
......@@ -184,7 +128,7 @@ public class Gas implements Comparable<Gas>, Serializable, Cloneable
*/
public void setGas(double fHe,double fO2, double mod)
{
if( validate(fHe, fO2, mod)) {
if( GasUtils.validate(fHe, fO2, mod)) {
this.fHe=fHe;
this.fO2=fO2;
this.mod=mod;
......
......@@ -116,6 +116,10 @@ public class Prefs implements Serializable
private double factorComp; // COnservatism factor
private double factorDecomp; // ""
private String modelClass; // Deco model class name
private double heliumNarcoticLevel; // is helium a narcotic gas in END calculations level of helium narcosis
private double oxygenNarcoticLevel; // is oxygen a narcotic gas in END calculations level of oxygen narcosis
/*
* Enable proxy connections
* */
......@@ -209,6 +213,8 @@ public class Prefs implements Serializable
factorComp=1.0;
factorDecomp=1.0;
modelClass="mvplan.model.ZHL16B";
heliumNarcoticLevel = 0.23;
oxygenNarcoticLevel = 1;
}
private void setLimits(boolean limits){
......@@ -265,19 +271,19 @@ public class Prefs implements Serializable
// IMPERIAL UNITS
if ( !(lastStopDepth>3.0 && lastStopDepth<=30.0) ) lastStopDepth=10.0;
if ( !(stopDepthIncrement>3.0 && stopDepthIncrement<=30.0) ) stopDepthIncrement=10.0;
if ( !(ascentRate>= -33.0 && ascentRate <= -3.0)) ascentRate=-33.0;
if ( !(ascentRate>= -32.808399 && ascentRate <= -3.0)) ascentRate=-32.808399;
if ( !(descentRate>=15.0 && descentRate<= 150.0)) descentRate=60.0;
if (!(pAmb>15.0 && pAmb<36.0)) pAmb=33.0;
if (!(pAmb>15.0 && pAmb<36.0)) pAmb=32.808399;
if (altitude < 0.0 || altitude > 16500.0) {
altitude = 0.0;
pAmb=33.0;
pAmb=32.808399;
}
pConversion=33.0;
pConversion=32.808399;
if (!(pH2O>=0.0 && pH2O <2.5)) pH2O=2.041;
stopDepthMax=40.0;
descentRateMax=150;
descentRateMin=15.0;
ascentRateMax=-33.0;
ascentRateMax=-32.808399;
ascentRateMin=-3.0;
depthShortString = MvplanInstance.getMvplan().getResource("mvplan.feet.shortText");
volumeShortString = MvplanInstance.getMvplan().getResource("mvplan.cuft.shortText");
......@@ -318,7 +324,10 @@ public class Prefs implements Serializable
seg.setGas( prefGases.get(0));
if(debug >0) System.out.println("Prefs: fixed missing gas.");
}
}
}
if (heliumNarcoticLevel > 1|| heliumNarcoticLevel < 0 ) heliumNarcoticLevel = 0.23;
if (oxygenNarcoticLevel > 1|| oxygenNarcoticLevel < 0 ) oxygenNarcoticLevel = 1;
}
/**
* Used to change the units. Needs to make some changes to some parameters
......@@ -333,9 +342,9 @@ public class Prefs implements Serializable
pConversion = 10.0;
pH2O=0.627;
} else {
//ascentRate=-33.0;
pAmb=33.0;
pConversion = 33.0;
//ascentRate=-32.808399;
pAmb=32.808399;
pConversion = 32.808399;
pH2O=2.041;
}
validatePrefs(); // Just check that everything is still ok.
......@@ -377,15 +386,15 @@ public class Prefs implements Serializable
public double getGfHigh() { return gfHigh; }
public double getGfLow() { return gfLow; }
public double getGfMax() { return gfMax; }
public double getGfMin() {return gfMin; }
public double getGfMin() { return gfMin; }
public double getDecoRMV() { return decoRMV; }
public double getDiveRMV() { return diveRMV; }
public boolean getOcDeco() { return ocDeco; }
public boolean getForceAllStops() { return forceAllStops; }
public boolean getRuntimeFlag() { return runtimeFlag; }
public int getOutputStyle() { return outputStyle; }
public boolean isPrintColour() { return printColour; }
public boolean isShowSeconds() { return showSeconds;}
public boolean isPrintColour() { return printColour; }
public boolean isShowSeconds() { return showSeconds;}
public int getFrameSizeX() { return frameSizeX; }
public int getFrameSizeY() { return frameSizeY; }
public int getFrameSplit() { return frameSplit; }
......@@ -426,8 +435,7 @@ public class Prefs implements Serializable
public String getProxyPort(){return proxyPort;}
public String getProxyUser(){return proxyUser;}
public String getProxyPassword(){return proxyPassword;}
// Mutator methods - TODO no bounds checking here
public void setDisableModUpdate(boolean b) { disableModUpdate = b;}
public void setLastStopDepth(double d) { lastStopDepth=d; }
......@@ -484,7 +492,7 @@ public class Prefs implements Serializable
}
// These are accessors created by Netbeans ...
// These are accessors created by Netbeans ...
public boolean isShowStopTime() {
return showStopTime;
......@@ -533,5 +541,47 @@ public class Prefs implements Serializable
this.homeURL = homeURL;
}
/**
* @return the heliumNarcoticLevel
*/
public double getHeliumNarcoticLevel() {
return heliumNarcoticLevel;
}
/**
* @param heliumNarcoticLevel the heliumNarcoticLevel to set
*/
public void setHeliumNarcoticLevel(double heliumNarcoticLevel) {
this.heliumNarcoticLevel = heliumNarcoticLevel;
}
/**
* @return the oxygenNarcoticLevel
*/
public double getOxygenNarcoticLevel() {
return oxygenNarcoticLevel;
}
/**
* @param oxygenNarcoticLevel the oxygenNarcoticLevel to set
*/
public void setOxygenNarcoticLevel(double oxygenNarcoticLevel) {
this.oxygenNarcoticLevel = oxygenNarcoticLevel;
}
/**
* @return the preferredLocale
*/
public Locale getPreferredLocale() {
return preferredLocale;
}
/**
* @param preferredLocale the preferredLocale to set
*/
public void setPreferredLocale(Locale preferredLocale) {
this.preferredLocale = preferredLocale;
}
}
package mvplan.util;
import mvplan.gas.Gas;
import mvplan.main.MvplanInstance;
import mvplan.prefs.Prefs;
public class GasUtils {
/**
* Calculate equivalent narcosis depth (END) of gas for given depth<br/>
* <br/>
* <br/>
*
* more information can be found here({@link http://www.techdiver.ws/trimix_narcosis.shtml})
* @see Gas
* @see Prefs
* @param g gas that is to be calculated
* @param depth for calculations;
*/
public static double calculateEND(Gas g, double depth) {
Prefs p = MvplanInstance.getPrefs();
double ppAir = .79 +
(.21 * p.getOxygenNarcoticLevel());
double ppF = g.getFN2() +
(g.getFO2() * p.getOxygenNarcoticLevel())+
(g.getFHe() * p.getHeliumNarcoticLevel());
ppF = (ppF*(depth+p.getPConversion())/ppAir)-p.getPConversion();
return ppF;
}
/**
* Calculate equivalent narcosis depth (END) of gas on MOD specifies gas<br/>
* <br/>
* <br/>
* more information can be found here({@link http://www.techdiver.ws/trimix_narcosis.shtml})
* @see Gas
* @see Prefs
* @param g gas that is to be calculated
*/
public static double calculateEND(Gas g) {
return calculateEND(g,g.getMod());
}
/**
* Method to validate a field for limits only
*/
public static boolean validate(String field, double value) {
if(field.equals("fHe") || field.equals("fO2"))
return ( value >= 0.0 && value <=1.0);
if(field.equals("mod"))
// Need to hard code nominal max value due to potential of prefs not being fully set up when this is called
return (value >=0.0 && value <= 900.0);
return false;
}
/**
* Method to validate all inputs (fO2, fHe and MOD)
*/
public static boolean validate(double fHe, double fO2, double mod) {
boolean passed=true;
Prefs prefs = MvplanInstance.getPrefs();
// Check individual fields for bounds
passed = (passed && validate("fHe",fHe));
passed = (passed && validate("fO2",fO2));
passed = (passed && validate("mod",mod));
if(!passed) return false;
// Check combined fractions
passed = (passed && (fHe+fO2)<=1.0);
if(!passed) return false;
// Check MOD for sensible value
if(fO2 == 0.0 && mod == 0.0) // Leave empty gases alone to allow construction
return passed;
if(MvplanInstance.getMvplan() != null && prefs != null) { // Need to check that prefs exists. We can get to this point during the initilisation of the prefs object
double d = ((mod+prefs.getPConversion())/prefs.getPConversion()*fO2);
passed = (d <= prefs.getMaxMOD()+0.05); // Tolerance of 0.05 to prevent unneccessary failure due to rounding
}
return passed;
}
/**
* Method to get a maximum MOD based on O2 fraction
*/
public static double getMaxMod(double o) {
Prefs prefs = MvplanInstance.getPrefs();
return (prefs.getMaxMOD()/o * prefs.getPConversion())-prefs.getPConversion();
}
/**
* Method to get a MOD based on O2 fraction and maximum ppO2
*/
public static double getMod(double fO2, double ppO2) {
Prefs prefs = MvplanInstance.getPrefs();
return (ppO2/fO2 * prefs.getPConversion())-prefs.getPConversion();
}
/**
* Method to get a ppO2 based on O2 fraction and MOD
*/
public static double getppO2(double f, double m) {
Prefs prefs = MvplanInstance.getPrefs();
return ( (m+prefs.getPConversion())*f/prefs.getPConversion());
}
}
package mvplan.util;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import mvplan.gas.Gas;
import mvplan.main.IMvplan;
import mvplan.main.MvplanInstance;
import mvplan.prefs.Prefs;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class GasUtilsTest {
@Mock IMvplan mv;
@Mock Prefs p;
@Before
public void prepeare(){
MockitoAnnotations.initMocks(this);
when(mv.getPrefs()).thenReturn(p);
when(p.getPConversion()).thenReturn(10.0);
when(p.getMaxMOD()).thenReturn(1.607);
MvplanInstance.setMvplan(mv);
}
@Test
public void testCalculateEND1() {
when(p.getHeliumNarcoticLevel()).thenReturn(0.0);
when(p.getOxygenNarcoticLevel()).thenReturn(0.0);
double o2 = .30;
double he = .0;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,40);
assertEquals(34, ((int)end));
}
@Test
public void testCalculateEND2() {
when(p.getHeliumNarcoticLevel()).thenReturn(0.0);
when(p.getOxygenNarcoticLevel()).thenReturn(1.0);
double o2 = .30;
double he = .0;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,40);
assertEquals(40, ((int)end));
}
@Test
public void testCalculateEND3() {
when(p.getHeliumNarcoticLevel()).thenReturn(0.0);
when(p.getOxygenNarcoticLevel()).thenReturn(1.0);
double o2 = .30;
double he = .39;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,40);
assertEquals(20, ((int)end));
}
@Test
public void testCalculateEND4() {
when(p.getHeliumNarcoticLevel()).thenReturn(0.0);
when(p.getOxygenNarcoticLevel()).thenReturn(0.0);
double o2 = .30;
double he = .39;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,40);
assertEquals(10,(int)Math.rint(end));
}
@Test
public void testCalculateEND5() {
when(p.getHeliumNarcoticLevel()).thenReturn(.23);
when(p.getOxygenNarcoticLevel()).thenReturn(1.0);
double o2 = .12;
double he = .51;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,100);
assertEquals(57,(int)Math.rint(end));
}
@Test
public void testCalculateENDImperial1() {
when(p.getHeliumNarcoticLevel()).thenReturn(.0);
when(p.getOxygenNarcoticLevel()).thenReturn(.0);
when(p.getPConversion()).thenReturn(33.0);
double o2 = .21;
double he = .0;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,99);
assertEquals(99,(int)Math.rint(end));
}
@Test
public void testCalculateENDImperial2() {
when(p.getHeliumNarcoticLevel()).thenReturn(.23);
when(p.getOxygenNarcoticLevel()).thenReturn(.1);
when(p.getPConversion()).thenReturn(33.0);
double o2 = .19;
double he = .35;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,139);
assertEquals(86,(int)Math.rint(end));
}
@Test
public void testCalculateENDImperial3() {
when(p.getHeliumNarcoticLevel()).thenReturn(.0);
when(p.getOxygenNarcoticLevel()).thenReturn(.1);
when(p.getPConversion()).thenReturn(33.0);
double o2 = .19;
double he = .35;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,139);
assertEquals(69,(int)Math.rint(end));
}
@Test
public void testCalculateENDImperial4() {
when(p.getHeliumNarcoticLevel()).thenReturn(.0);
when(p.getOxygenNarcoticLevel()).thenReturn(.0);
when(p.getPConversion()).thenReturn(33.0);
double o2 = .19;
double he = .35;
Gas g = new Gas(he,o2,GasUtils.getMaxMod(o2));
double end = GasUtils.calculateEND(g,139);
assertEquals(67,(int)Math.rint(end));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment