00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 package ikayaki;
00024
00025 import static ikayaki.MeasurementResult.Type.*;
00026 import static java.lang.Math.atan2;
00027 import static java.lang.Math.PI;
00028 import static java.lang.Math.atan;
00029 import static java.lang.Math.pow;
00030 import static java.lang.Math.sqrt;
00031
00038 public abstract class MeasurementValue <T> {
00039
00043 public static final MeasurementValue<Double> GEOGRAPHIC_X =
00044 new MeasurementValue<Double>("X'", "Am\u00B2", "Average X (geographic coordinates)") {
00045 public Double getValue(MeasurementStep step) {
00046 double sum = 0.0;
00047 int count = 0;
00048 for (int i = 0; i < step.getResults(); i++) {
00049 MeasurementResult r = step.getResult(i);
00050 if (r.getType() != SAMPLE) {
00051 continue;
00052 }
00053 sum += r.getGeographicX();
00054 count++;
00055 }
00056 if (count > 0) {
00057 return new Double(sum / count);
00058 } else {
00059 return null;
00060 }
00061 }
00062 };
00063
00067 public static final MeasurementValue<Double> GEOGRAPHIC_Y =
00068 new MeasurementValue<Double>("Y'", "Am\u00B2", "Average Y (geographic coordinates)") {
00069 public Double getValue(MeasurementStep step) {
00070 double sum = 0.0;
00071 int count = 0;
00072 for (int i = 0; i < step.getResults(); i++) {
00073 MeasurementResult r = step.getResult(i);
00074 if (r.getType() != SAMPLE) {
00075 continue;
00076 }
00077 sum += r.getGeographicY();
00078 count++;
00079 }
00080 if (count > 0) {
00081 return new Double(sum / count);
00082 } else {
00083 return null;
00084 }
00085 }
00086 };
00087
00091 public static final MeasurementValue<Double> GEOGRAPHIC_Z =
00092 new MeasurementValue<Double>("Z'", "Am\u00B2", "Average Z (geographic coordinates)") {
00093 public Double getValue(MeasurementStep step) {
00094 double sum = 0.0;
00095 int count = 0;
00096 for (int i = 0; i < step.getResults(); i++) {
00097 MeasurementResult r = step.getResult(i);
00098 if (r.getType() != SAMPLE) {
00099 continue;
00100 }
00101 sum += r.getGeographicZ();
00102 count++;
00103 }
00104 if (count > 0) {
00105 return new Double(sum / count);
00106 } else {
00107 return null;
00108 }
00109 }
00110 };
00111
00115 public static final MeasurementValue<Double> SAMPLE_X =
00116 new MeasurementValue<Double>("X", "Am\u00B2", "Average X (sample coordinates)") {
00117 public Double getValue(MeasurementStep step) {
00118 double sum = 0.0;
00119 int count = 0;
00120 for (int i = 0; i < step.getResults(); i++) {
00121 MeasurementResult r = step.getResult(i);
00122 if (r.getType() != SAMPLE) {
00123 continue;
00124 }
00125 sum += r.getSampleX();
00126 count++;
00127 }
00128 if (count > 0) {
00129 return new Double(sum / count);
00130 } else {
00131 return null;
00132 }
00133 }
00134 };
00135
00139 public static final MeasurementValue<Double> SAMPLE_Y =
00140 new MeasurementValue<Double>("Y", "Am\u00B2", "Average Y (sample coordinates)") {
00141 public Double getValue(MeasurementStep step) {
00142 double sum = 0.0;
00143 int count = 0;
00144 for (int i = 0; i < step.getResults(); i++) {
00145 MeasurementResult r = step.getResult(i);
00146 if (r.getType() != SAMPLE) {
00147 continue;
00148 }
00149 sum += r.getSampleY();
00150 count++;
00151 }
00152 if (count > 0) {
00153 return new Double(sum / count);
00154 } else {
00155 return null;
00156 }
00157 }
00158 };
00159
00163 public static final MeasurementValue<Double> SAMPLE_Z =
00164 new MeasurementValue<Double>("Z", "Am\u00B2", "Average Z (sample coordinates)") {
00165 public Double getValue(MeasurementStep step) {
00166 double sum = 0.0;
00167 int count = 0;
00168 for (int i = 0; i < step.getResults(); i++) {
00169 MeasurementResult r = step.getResult(i);
00170 if (r.getType() != SAMPLE) {
00171 continue;
00172 }
00173 sum += r.getSampleZ();
00174 count++;
00175 }
00176 if (count > 0) {
00177 return new Double(sum / count);
00178 } else {
00179 return null;
00180 }
00181 }
00182 };
00183
00187 public static final MeasurementValue<Double> GEOGRAPHIC_X_NORMALIZED =
00188 new NormalizedValue("X'", "Normalized average X (geographic coordinates)") {
00189 protected Double getValue0(MeasurementStep step) {
00190 return GEOGRAPHIC_X.getValue(step);
00191 }
00192 };
00193
00197 public static final MeasurementValue<Double> GEOGRAPHIC_Y_NORMALIZED =
00198 new NormalizedValue("Y'", "Normalized average Y (geographic coordinates)") {
00199 protected Double getValue0(MeasurementStep step) {
00200 return GEOGRAPHIC_Y.getValue(step);
00201 }
00202 };
00203
00207 public static final MeasurementValue<Double> GEOGRAPHIC_Z_NORMALIZED =
00208 new NormalizedValue("Z'", "Normalized average Z (geographic coordinates)") {
00209 protected Double getValue0(MeasurementStep step) {
00210 return GEOGRAPHIC_Z.getValue(step);
00211 }
00212 };
00213
00217 public static final MeasurementValue<Double> SAMPLE_X_NORMALIZED =
00218 new NormalizedValue("X", "Normalized average X (sample coordinates)") {
00219 protected Double getValue0(MeasurementStep step) {
00220 return SAMPLE_X.getValue(step);
00221 }
00222 };
00223
00227 public static final MeasurementValue<Double> SAMPLE_Y_NORMALIZED =
00228 new NormalizedValue("Y", "Normalized average Y (sample coordinates)") {
00229 protected Double getValue0(MeasurementStep step) {
00230 return SAMPLE_Y.getValue(step);
00231 }
00232 };
00233
00237 public static final MeasurementValue<Double> SAMPLE_Z_NORMALIZED =
00238 new NormalizedValue("Z", "Normalized average Z (sample coordinates)") {
00239 protected Double getValue0(MeasurementStep step) {
00240 return SAMPLE_Z.getValue(step);
00241 }
00242 };
00243
00247 public static final MeasurementValue<Double> DECLINATION =
00248 new MeasurementValue<Double>("D", "\u00b0", "Geographic declination") {
00249 public Double getValue(MeasurementStep step) {
00250 Double x = GEOGRAPHIC_X.getValue(step);
00251 Double y = GEOGRAPHIC_Y.getValue(step);
00252 if (x == null || y == null) {
00253 return null;
00254 } else {
00255 double d = atan2(y, x);
00256 if (d < 0.0) {
00257 d += PI * 2;
00258 }
00259 return Math.toDegrees(d);
00260 }
00261 }
00262 };
00263
00267 public static final MeasurementValue<Double> INCLINATION =
00268 new MeasurementValue<Double>("I", "\u00b0", "Geographic inclination") {
00269 public Double getValue(MeasurementStep step) {
00270 Double x = GEOGRAPHIC_X.getValue(step);
00271 Double y = GEOGRAPHIC_Y.getValue(step);
00272 Double z = GEOGRAPHIC_Z.getValue(step);
00273 if (x == null || y == null || z == null) {
00274 return null;
00275 } else {
00276 if (x == 0.0) {
00277 x = 0.000000000001;
00278 }
00279 if (y == 0.0) {
00280 y = 0.000000000001;
00281 }
00282 double d = atan(z / sqrt(pow(x, 2) + pow(y, 2)));
00283 return Math.toDegrees(d);
00284 }
00285 }
00286 };
00287
00291 public static final MeasurementValue<Double> MOMENT =
00292 new MeasurementValue<Double>("M", "Am\u00B2", "Magnetic moment") {
00293 public Double getValue(MeasurementStep step) {
00294 Double x = SAMPLE_X.getValue(step);
00295 Double y = SAMPLE_Y.getValue(step);
00296 Double z = SAMPLE_Z.getValue(step);
00297 if (x == null || y == null || z == null) {
00298 return null;
00299 } else {
00300 return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
00301 }
00302 }
00303 };
00304
00309 public static final MeasurementValue<Double> MAGNETIZATION =
00310 new NormalizedValue("J", "Magnetic intensity") {
00311 protected Double getValue0(MeasurementStep step) {
00312 return MOMENT.getValue(step);
00313 }
00314 };
00315
00319 public static final MeasurementValue<Double> RELATIVE_MAGNETIZATION =
00320 new MeasurementValue<Double>("J/Jo", "", "Relative magnetic intensity") {
00321 public Double getValue(MeasurementStep step) {
00322 Project project = step.getProject();
00323 if (project == null) {
00324 return null;
00325 }
00326 Double j = MAGNETIZATION.getValue(step);
00327 Double j0 = MAGNETIZATION.getValue(project.getStep(0));
00328 if (j == null || j0 == null) {
00329 return null;
00330 } else {
00331 return j.doubleValue() / j0.doubleValue();
00332 }
00333 }
00334 };
00335
00339 public static final MeasurementValue<Double> THETA63 =
00340 new MeasurementValue<Double>("\u03b863", "\u00b0", "Angular standard deviation") {
00341 public Double getValue(MeasurementStep step) {
00342 int count = 0;
00343 double sumX = 0.0;
00344 double sumY = 0.0;
00345 double sumZ = 0.0;
00346 double sumLength = 0.0;
00347
00348 for (int i = 0; i < step.getResults(); i++) {
00349 MeasurementResult r = step.getResult(i);
00350 if (r.getType() != SAMPLE) {
00351 continue;
00352 }
00353
00354 sumX += r.getSampleX();
00355 sumY += r.getSampleY();
00356 sumZ += r.getSampleZ();
00357 sumLength += r.getSampleVector().length();
00358 count++;
00359 }
00360 if (count < 2) {
00361 return null;
00362 }
00363 double avgLength = sumLength / count;
00364
00365 double N = sumLength;
00366 double R = sqrt((sumX * sumX) + (sumY * sumY) + (sumZ * sumZ));
00367 double k = (N - avgLength) / (N - R);
00368 return 81.0 / sqrt(k);
00369 }
00370 };
00371
00375 public static final MeasurementValue<Double> SIGNAL_TO_NOISE =
00376 new MeasurementValue<Double>("caption", "unit", "description") {
00377 public Double getValue(MeasurementStep step) {
00378 if (step == null) {
00379 return null;
00380 }
00381
00382
00383 int count = 0;
00384 double lengthSum = 0.0;
00385 for (MeasurementResult r : step) {
00386 lengthSum += r.getSampleVector().length();
00387 count++;
00388 }
00389 if (count < 2) {
00390 return null;
00391 }
00392 double lengthAvg = lengthSum / count;
00393
00394
00395 double squareSum = 0.0;
00396 for (MeasurementResult r : step) {
00397 double d = r.getSampleVector().length() - lengthAvg;
00398 squareSum += (d * d);
00399 }
00400 double stdev = Math.sqrt(squareSum / (count - 1));
00401
00402 return lengthAvg / stdev;
00403 }
00404 };
00405
00409 public static final MeasurementValue<Double> SIGNAL_TO_DRIFT =
00410 new MeasurementValue<Double>("caption", "unit", "description") {
00411 public Double getValue(MeasurementStep step) {
00412 if (step == null) {
00413 return null;
00414 }
00415 Double signal = MOMENT.getValue(step);
00416 if (signal == null) {
00417 return null;
00418 }
00419 double d = step.getNoise().length();
00420 if (d == 0.0) {
00421 return null;
00422 }
00423 return signal.doubleValue() / d;
00424 }
00425 };
00426
00430 public static final MeasurementValue<Double> SIGNAL_TO_HOLDER =
00431 new MeasurementValue<Double>("caption", "unit", "description") {
00432 public Double getValue(MeasurementStep step) {
00433 if (step == null) {
00434 return null;
00435 }
00436 Double signal = MOMENT.getValue(step);
00437 if (signal == null) {
00438 return null;
00439 }
00440 double d = step.getHolder().length();
00441 if (d == 0.0) {
00442 return null;
00443 }
00444 return signal.doubleValue() / d;
00445 }
00446 };
00447
00448
00449
00450
00454 private final String caption;
00455
00459 private final String unit;
00460
00464 private final String description;
00465
00474 public MeasurementValue(String caption, String unit, String description) {
00475 if (caption == null || unit == null || description == null) {
00476 throw new NullPointerException();
00477 }
00478 this.caption = caption;
00479 this.unit = unit;
00480 this.description = description;
00481 }
00482
00490 public abstract T getValue(MeasurementStep step);
00491
00498 public String getCaption(Project project) {
00499 return caption;
00500 }
00501
00508 public String getUnit(Project project) {
00509 return unit;
00510 }
00511
00518 public String getDescription(Project project) {
00519 return description;
00520 }
00521 }
00522
00528 abstract class NormalizedValue extends MeasurementValue<Double> {
00529
00530 public NormalizedValue(String caption, String description) {
00531 super(caption, "", description);
00532 }
00533
00542 public final Double getValue(MeasurementStep step) {
00543 return normalize(step, getValue0(step));
00544 }
00545
00553 protected abstract Double getValue0(MeasurementStep step);
00554
00558 @Override public String getUnit(Project project) {
00559 if (project == null) {
00560 return "mA/m";
00561 } else if (project.getNormalization() == Project.Normalization.VOLUME) {
00562 return "mA/m";
00563 } else if (project.getNormalization() == Project.Normalization.MASS) {
00564 return "Am\u00B2/kg";
00565 } else {
00566 assert false;
00567 return "";
00568 }
00569 }
00570
00579 private static Double normalize(MeasurementStep step, Double value) {
00580 Project project = step.getProject();
00581 if (project == null) {
00582 return null;
00583 }
00584
00585 double normalizer;
00586 if (project.getNormalization() == Project.Normalization.VOLUME) {
00587 normalizer = step.getVolume();
00588 if (normalizer < 0.0) {
00589 normalizer = project.getVolume();
00590 }
00591 normalizer = normalizer / 1000000.0;
00592
00593 } else if (project.getNormalization() == Project.Normalization.MASS) {
00594 normalizer = step.getMass();
00595 if (normalizer < 0.0) {
00596 normalizer = project.getMass();
00597 }
00598 normalizer = normalizer / 1000.0;
00599
00600 } else {
00601 assert false;
00602 return null;
00603 }
00604 if (normalizer <= 0.0) {
00605 return null;
00606 }
00607
00608 if (value == null) {
00609 return null;
00610 } else {
00611 return (value * 1000.0) / normalizer;
00612 }
00613 }
00614 }