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 ikayaki.squid.Squid;
00026 import ikayaki.util.DocumentUtilities;
00027 import ikayaki.util.LastExecutor;
00028 import org.w3c.dom.Document;
00029 import org.w3c.dom.Element;
00030 import org.w3c.dom.NodeList;
00031
00032 import javax.swing.*;
00033 import javax.swing.event.EventListenerList;
00034 import javax.vecmath.Matrix3d;
00035 import javax.xml.parsers.DocumentBuilderFactory;
00036 import javax.xml.parsers.ParserConfigurationException;
00037 import java.io.*;
00038 import java.text.DecimalFormat;
00039 import java.text.DecimalFormatSymbols;
00040 import java.text.FieldPosition;
00041 import java.util.*;
00042
00043 import static ikayaki.MeasurementStep.State.READY;
00044 import static java.lang.Math.sin;
00045 import static java.lang.Math.cos;
00046 import static ikayaki.MeasurementEvent.Type.*;
00047 import static ikayaki.MeasurementResult.Type.*;
00048 import static ikayaki.Project.Normalization.*;
00049 import static ikayaki.Project.Orientation.*;
00050 import static ikayaki.Project.State.*;
00051 import static ikayaki.Project.SampleType.*;
00052 import static ikayaki.Project.Type.*;
00053 import static ikayaki.ProjectEvent.Type.*;
00054
00066 public class Project {
00067
00068 private static final boolean DEBUG = false;
00069
00070
00071 public static final String MEASUREMENT_TYPE_PROPERTY = "measurementType";
00072 public static final String MEASUREMENT_TYPE_AUTO_VALUE = "AUTO";
00073 public static final String MEASUREMENT_TYPE_MANUAL_VALUE = "MANUAL";
00074 public static final String OPERATOR_PROPERTY = "operator";
00075 public static final String DATE_PROPERTY = "date";
00076 public static final String ROCK_TYPE_PROPERTY = "rockType";
00077 public static final String AREA_PROPERTY = "area";
00078 public static final String SITE_PROPERTY = "site";
00079 public static final String COMMENT_PROPERTY = "comment";
00080 public static final String LATITUDE_PROPERTY = "latitude";
00081 public static final String LONGITUDE_PROPERTY = "longitude";
00082
00087 private static final Hashtable<File, Project> projectCache = new Hashtable<File, Project>();
00088
00093 private static final Hashtable<File, Object> projectTypeCache = new Hashtable<File, Object>();
00094
00098 private final File file;
00102 private final Type type;
00103
00108 private State state = IDLE;
00109
00113 private boolean closed = false;
00114
00118 private Squid squid = null;
00119
00124 private final Properties properties = new Properties();
00125
00130 private MeasurementSequence sequence = new MeasurementSequence();
00131
00135 private double strike = 0.0;
00136
00140 private double dip = 0.0;
00141
00145 private SampleType sampleType = HAND;
00146
00150 private Orientation orientation = MINUS_Z;
00151
00155 private Normalization normalization = VOLUME;
00156
00161 private Matrix3d transform = new Matrix3d();
00162
00166 private double mass = -1.0;
00167
00171 private double volume = -1.0;
00172
00176 private double susceptibility = -1.0;
00177
00181 private MeasurementStep currentStep = null;
00182
00186 private final EventListenerList listenerList = new EventListenerList();
00187
00191 private boolean modified = false;
00192
00196 private final LastExecutor autosaveQueue = new LastExecutor(500, true);
00197
00201 private Runnable autosaveRunnable = new Runnable() {
00202 public void run() {
00203 saveNow();
00204 }
00205 };
00206
00214 public static Project createCalibrationProject(File file) {
00215 return createProject(file, CALIBRATION);
00216 }
00217
00225 public static Project createAFProject(File file) {
00226 return createProject(file, AF);
00227 }
00228
00236 public static Project createThellierProject(File file) {
00237 return createProject(file, THELLIER);
00238 }
00239
00247 public static Project createThermalProject(File file) {
00248 return createProject(file, THERMAL);
00249 }
00250
00260 public static synchronized Project createProject(File file, Type type) {
00261 if (file == null || type == null) {
00262 throw new NullPointerException();
00263 }
00264
00265
00266 try {
00267 file = file.getCanonicalFile();
00268 } catch (IOException e) {
00269 e.printStackTrace();
00270 return null;
00271 }
00272
00273
00274 try {
00275 if (!file.createNewFile()) {
00276 return null;
00277 }
00278 } catch (IOException e) {
00279 return null;
00280 }
00281
00282
00283 Project project = new Project(file, type);
00284 if (!project.saveNow()) {
00285 return null;
00286 }
00287 projectCache.put(file, project);
00288 projectTypeCache.put(file, project.getType());
00289 return project;
00290 }
00291
00300 public static synchronized Project loadProject(File file) {
00301 if (file == null) {
00302 throw new NullPointerException();
00303 }
00304 if (!file.canRead() || !file.isFile()) {
00305 return null;
00306 }
00307
00308
00309 try {
00310 file = file.getCanonicalFile();
00311 } catch (IOException e) {
00312 e.printStackTrace();
00313 return null;
00314 }
00315
00316
00317 Project project = projectCache.get(file);
00318 if (project != null) {
00319 return project;
00320 }
00321
00322
00323 try {
00324 Document document = DocumentUtilities.loadFromXML(file);
00325 if (document == null) {
00326 return null;
00327 }
00328 project = new Project(file, document);
00329 projectCache.put(file, project);
00330 projectTypeCache.put(file, project.getType());
00331
00332 } catch (IllegalArgumentException e) {
00333 e.printStackTrace();
00334 return null;
00335 }
00336 return project;
00337 }
00338
00352 public static synchronized boolean closeProject(Project project) {
00353 if (project == null) {
00354 throw new NullPointerException();
00355 }
00356
00357 synchronized (project) {
00358
00359 if (project.isClosed()) {
00360 new Exception("closeProject success: the project is already closed!").printStackTrace();
00361 return true;
00362 }
00363 if (project.getState() != IDLE) {
00364 System.err.println("closeProject failed: the project's state is " + project.getState());
00365 return false;
00366 }
00367 if (!project.setSquid(null) || !project.saveNow()) {
00368 System.err.println("closeProject failed: unable to detatch the squid or save the file");
00369 return false;
00370 }
00371 projectCache.remove(project.getFile());
00372
00373
00374 project.closed = true;
00375 project.autosaveRunnable = new Runnable() {
00376 public void run() {
00377 assert false;
00378 throw new IllegalStateException("Tried to save a closed project!");
00379 }
00380 };
00381 }
00382 return true;
00383 }
00384
00388 public static synchronized Project[] getCachedProjects() {
00389 return projectCache.values().toArray(new Project[0]);
00390 }
00391
00401 public static Type getType(File file) {
00402 if (file == null) {
00403 throw new NullPointerException();
00404 }
00405
00406
00407 Object value = projectTypeCache.get(file);
00408 if (value != null) {
00409 if (value instanceof Type) {
00410 return (Type) value;
00411 } else {
00412 return null;
00413 }
00414 }
00415
00416
00417 Type type = null;
00418 BufferedReader reader = null;
00419 try {
00420 reader = new BufferedReader(new FileReader(file));
00421
00422
00423 String line = reader.readLine();
00424 if (line == null || line.indexOf("<?xml") < 0) {
00425 return null;
00426 }
00427
00428
00429
00430 line = reader.readLine();
00431 if (line == null) {
00432 return null;
00433 }
00434 int start = line.indexOf("<project type=\"");
00435 if (start < 0) {
00436 return null;
00437 }
00438 start += 15;
00439 int end = line.indexOf("\"", start);
00440 if (end < 0) {
00441 return null;
00442 }
00443 type = Type.valueOf(line.substring(start, end));
00444 } catch (FileNotFoundException e) {
00445 e.printStackTrace();
00446 } catch (IOException e) {
00447 e.printStackTrace();
00448 } catch (IllegalArgumentException e) {
00449 e.printStackTrace();
00450 } finally {
00451
00452
00453 if (reader != null) {
00454 try {
00455 reader.close();
00456 } catch (IOException e) {
00457 e.printStackTrace();
00458 }
00459 }
00460
00461
00462 if (type != null) {
00463 projectTypeCache.put(file, type);
00464 } else {
00465 projectTypeCache.put(file, new Object());
00466 }
00467 }
00468 return type;
00469 }
00470
00480 private Project(File file, Type type) {
00481 if (file == null || type == null) {
00482 throw new NullPointerException();
00483 }
00484 this.file = file.getAbsoluteFile();
00485 this.type = type;
00486 updateTransforms();
00487 modified = true;
00488 }
00489
00500 private Project(File file, Document document) {
00501 if (file == null || document == null) {
00502 throw new NullPointerException();
00503 }
00504 this.file = file.getAbsoluteFile();
00505 String s = null;
00506
00507 synchronized (this) {
00508 try {
00509
00510
00511 Element root = document.getDocumentElement();
00512 if (!root.getTagName().equals("project")) {
00513 throw new IllegalArgumentException("Invalid tag name: " + root.getTagName());
00514 }
00515 String version = root.getAttribute("version");
00516
00517 if (version.equals("1.0")) {
00518
00519
00520
00521
00522 s = root.getAttribute("type");
00523 try {
00524 type = Type.valueOf(s);
00525 } catch (IllegalArgumentException e) {
00526 throw new IllegalArgumentException("Unknown project type: " + s, e);
00527 }
00528
00529
00530 NodeList propertiesList = root.getElementsByTagName("properties");
00531 if (propertiesList.getLength() != 1) {
00532 throw new IllegalArgumentException(
00533 "One properties required, found " + propertiesList.getLength());
00534 }
00535 Element properties = (Element) propertiesList.item(0);
00536
00537
00538 s = properties.getAttribute("strike");
00539 try {
00540 strike = Double.parseDouble(s);
00541 } catch (NumberFormatException e) {
00542 throw new IllegalArgumentException("Invalid strike: " + s, e);
00543 }
00544 s = properties.getAttribute("dip");
00545 try {
00546 dip = Double.parseDouble(s);
00547 } catch (NumberFormatException e) {
00548 throw new IllegalArgumentException("Invalid dip: " + s, e);
00549 }
00550 s = properties.getAttribute("mass");
00551 try {
00552 mass = Double.parseDouble(s);
00553 } catch (NumberFormatException e) {
00554 throw new IllegalArgumentException("Invalid mass: " + s, e);
00555 }
00556 s = properties.getAttribute("volume");
00557 try {
00558 volume = Double.parseDouble(s);
00559 } catch (NumberFormatException e) {
00560 throw new IllegalArgumentException("Invalid volume: " + s, e);
00561 }
00562 s = properties.getAttribute("susceptibility");
00563 try {
00564 susceptibility = Double.parseDouble(s);
00565 } catch (NumberFormatException e) {
00566 throw new IllegalArgumentException("Invalid susceptibility: " + s, e);
00567 }
00568 s = properties.getAttribute("sampletype");
00569 try {
00570 sampleType = SampleType.valueOf(s);
00571 } catch (IllegalArgumentException e) {
00572 throw new IllegalArgumentException("Invalid sampletype: " + s, e);
00573 }
00574 s = properties.getAttribute("orientation");
00575 try {
00576 orientation = Orientation.valueOf(s);
00577 } catch (IllegalArgumentException e) {
00578 throw new IllegalArgumentException("Invalid orientation: " + s, e);
00579 }
00580 s = properties.getAttribute("normalization");
00581 try {
00582 normalization = Normalization.valueOf(s);
00583 } catch (IllegalArgumentException e) {
00584 throw new IllegalArgumentException("Invalid normalization: " + s, e);
00585 }
00586
00587
00588 NodeList propertyList = properties.getElementsByTagName("property");
00589 for (int i = 0; i < propertyList.getLength(); i++) {
00590 Element property = (Element) propertyList.item(i);
00591 this.properties.put(property.getAttribute("key"), property.getAttribute("value"));
00592 }
00593
00594
00595 NodeList sequenceList = root.getElementsByTagName("sequence");
00596 if (sequenceList.getLength() != 1) {
00597 throw new IllegalArgumentException("One sequence required, found " + sequenceList.getLength());
00598 }
00599 updateTransforms();
00600 sequence = new MeasurementSequence((Element) sequenceList.item(0), this);
00601
00602
00603 Date lastTimestamp = new Date(0);
00604 MeasurementStep.State lastState = MeasurementStep.State.DONE;
00605 for (int i = 0; i < sequence.getSteps(); i++) {
00606 MeasurementStep step = sequence.getStep(i);
00607 Date currentTimestamp = step.getTimestamp();
00608 MeasurementStep.State currentState = step.getState();
00609
00610
00611 if (lastTimestamp != null && currentTimestamp != null
00612 && currentTimestamp.before(lastTimestamp)) {
00613 throw new IllegalArgumentException("The timestamp of step " + i + " is too early.");
00614 }
00615 if (lastTimestamp == null && currentTimestamp != null) {
00616 throw new IllegalArgumentException(
00617 "The non-null timestamp of step " + i + " follows a null timestamp.");
00618 }
00619
00620
00621 switch (currentState) {
00622 case DONE_RECENTLY:
00623 case MEASURING:
00624
00625 throw new IllegalArgumentException("The state of step " + i + " is " + currentState);
00626 case DONE:
00627 if (lastState == READY) {
00628 throw new IllegalArgumentException("The state of step " + i + " is "
00629 + currentState + " after a " + READY);
00630 }
00631 break;
00632 case READY:
00633
00634 break;
00635 default:
00636 throw new IllegalArgumentException(
00637 "The step " + i + " has an unknown state: " + currentState);
00638 }
00639
00640 lastTimestamp = currentTimestamp;
00641 lastState = currentState;
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 } else {
00657 throw new IllegalArgumentException("Unknown version: " + version);
00658 }
00659
00660 } catch (RuntimeException e) {
00661
00662
00663
00664
00665 throw e;
00666 } finally {
00667 modified = false;
00668 }
00669 }
00670 }
00671
00677 public synchronized Document getDocument() {
00678 Document document = null;
00679 try {
00680 document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
00681 } catch (ParserConfigurationException e) {
00682 return null;
00683 }
00684
00685
00686
00687
00688 Element root = document.createElement("project");
00689 root.setAttribute("version", "1.0");
00690 root.setAttribute("type", type.name());
00691
00692
00693 Element properties = document.createElement("properties");
00694 properties.setAttribute("strike", Double.toString(strike));
00695 properties.setAttribute("dip", Double.toString(dip));
00696 properties.setAttribute("mass", Double.toString(mass));
00697 properties.setAttribute("volume", Double.toString(volume));
00698 properties.setAttribute("susceptibility", Double.toString(susceptibility));
00699 properties.setAttribute("sampletype", sampleType.name());
00700 properties.setAttribute("orientation", orientation.name());
00701 properties.setAttribute("normalization", normalization.name());
00702
00703
00704 Set<Map.Entry<Object, Object>> entries = this.properties.entrySet();
00705 for (Map.Entry<Object, Object> entry : entries) {
00706 Element property = document.createElement("property");
00707 property.setAttribute("key", entry.getKey().toString());
00708 property.setAttribute("value", entry.getValue().toString());
00709 properties.appendChild(property);
00710 }
00711
00712
00713 Element sequence = this.sequence.getElement(document);
00714
00715
00716 root.appendChild(properties);
00717 root.appendChild(sequence);
00718 document.appendChild(root);
00719 return document;
00720 }
00721
00725 public synchronized boolean isModified() {
00726 return modified;
00727 }
00728
00735 public synchronized void save() {
00736 if (isClosed()) {
00737 throw new IllegalStateException("The project is closed");
00738 }
00739 modified = true;
00740 autosaveQueue.execute(autosaveRunnable);
00741 }
00742
00750 public boolean saveNow() {
00751 if (isClosed()) {
00752 throw new IllegalStateException("The project is closed");
00753 }
00754 File file;
00755 Document document;
00756 synchronized (this) {
00757
00758 autosaveQueue.clear();
00759
00760
00761 if (!isModified()) {
00762 return true;
00763 }
00764 file = getFile();
00765 document = getDocument();
00766 }
00767 if (DocumentUtilities.storeToXML(file, document)) {
00768 modified = false;
00769 fireProjectEvent(FILE_SAVED);
00770 return true;
00771 } else {
00772 return false;
00773 }
00774 }
00775
00784 private static String pad(String s, int length, int alignment) {
00785 while (s.length() < length) {
00786 if (alignment < 0) {
00787
00788 s = s + " ";
00789 } else if (alignment > 0) {
00790
00791 s = " " + s;
00792 } else {
00793
00794 if (s.length() % 2 == 0) {
00795 s = s + " ";
00796 } else {
00797 s = " " + s;
00798 }
00799 }
00800 }
00801 return s;
00802 }
00803
00811 public boolean exportToDAT(File file) {
00812 if (file == null) {
00813 throw new NullPointerException();
00814 }
00815 PrintStream out = null;
00816 try {
00817 out = new PrintStream(file, "ISO-8859-1");
00818 double d;
00819 Double dd;
00820 String s;
00821
00822
00823 Locale locale = new Locale("en");
00824 DecimalFormat format2Frac = new DecimalFormat("###0.00", new DecimalFormatSymbols(locale));
00825 DecimalFormat format3Frac = new DecimalFormat("##0.000", new DecimalFormatSymbols(locale));
00826 DecimalFormat format5Numb = new DecimalFormat("###0.0000", new DecimalFormatSymbols(locale)) {
00827 @Override public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
00828 StringBuffer sb = super.format(number, result, fieldPosition);
00829 if (number < 0) {
00830 sb.delete(7, sb.length());
00831 } else {
00832 sb.delete(6, sb.length());
00833 }
00834 return sb;
00835 }
00836 };
00837
00838
00839 out.print(pad("SQUID", 11, -1));
00840 out.println(Ikayaki.APP_NAME + " " + Ikayaki.APP_VERSION);
00841
00842 out.print(pad("Name", 10, -1));
00843 out.print(":");
00844 out.println(getName());
00845
00846 out.print(pad("Rocktype", 10, -1));
00847 out.print(":");
00848 out.println(getProperty(ROCK_TYPE_PROPERTY, ""));
00849
00850 out.print(pad("Site", 10, -1));
00851 out.print(":");
00852 s = getProperty(AREA_PROPERTY, "");
00853 if (s.length() > 0) {
00854 s += "/";
00855 }
00856 s += getProperty(SITE_PROPERTY, "");
00857 out.println(s);
00858
00859 out.print(pad("Sampletype", 10, -1));
00860 out.print(":");
00861 if (getSampleType() == CORE) {
00862 out.println("core sample");
00863 } else {
00864 out.println("hand sample");
00865 }
00866
00867 out.print(pad("Comment", 10, -1));
00868 out.print(":");
00869 out.println(getProperty(COMMENT_PROPERTY, "").replaceAll("\\s", " "));
00870
00871
00872 String header = "";
00873 String values = "";
00874
00875 try {
00876 d = Double.parseDouble(getProperty(LATITUDE_PROPERTY, "0.0"));
00877 } catch (NumberFormatException e) {
00878 d = 0.0;
00879 }
00880 header += pad("Lat ", 8, 1);
00881 values += pad(" " + format2Frac.format(d), 8, 1);
00882
00883 try {
00884 d = Double.parseDouble(getProperty(LONGITUDE_PROPERTY, "0.0"));
00885 } catch (NumberFormatException e) {
00886 d = 0.0;
00887 }
00888 header += pad("Lon ", 8, 1);
00889 values += pad(" " + format2Frac.format(d), 8, 1);
00890
00891 d = getStrike();
00892 header += pad("Str ", 8, 1);
00893 values += pad(" " + format2Frac.format(d), 8, 1);
00894
00895 d = getDip();
00896 header += pad("Dip ", 8, 1);
00897 values += pad(" " + format2Frac.format(d), 8, 1);
00898
00899 d = 0.0;
00900 header += pad("Bstr", 8, 1);
00901 values += pad(" " + format2Frac.format(d), 8, 1);
00902
00903 d = 0.0;
00904 header += pad("Bdip", 8, 1);
00905 values += pad(" " + format2Frac.format(d), 8, 1);
00906
00907 d = Math.min(getVolume(), 0.0);
00908 header += pad("Vol ", 8, 1);
00909 values += pad(" " + format3Frac.format(d), 8, 1);
00910
00911 d = Math.min(getMass(), 0.0);
00912 header += pad("Mass ", 8, 1);
00913 values += pad(" " + format3Frac.format(d), 8, 1);
00914
00915 out.println(header);
00916 out.println(values);
00917
00918
00919 if (getType() == THELLIER || getType() == THERMAL) {
00920 out.print("TH");
00921 } else {
00922 out.print("AF");
00923 }
00924 out.println(" Dec Inc Int Sus T63 Xkomp Ykomp Zkomp");
00925
00926 for (int i = 0; i < getCompletedSteps(); i++) {
00927 MeasurementStep step = getStep(i);
00928
00929
00930 if (getType() == THELLIER || getType() == THERMAL) {
00931 s = "" + Math.max((int) Math.round(step.getStepValue()), 0);
00932 } else {
00933 s = "" + Math.max((int) Math.round(step.getStepValue() * 10), 0);
00934 }
00935 out.print(pad(s, 4, 1));
00936
00937
00938 dd = MeasurementValue.DECLINATION.getValue(step);
00939 d = dd != null ? dd : 0.0;
00940 s = format2Frac.format(d);
00941 out.print(pad(" " + s, 8, 1));
00942
00943
00944 dd = MeasurementValue.INCLINATION.getValue(step);
00945 d = dd != null ? dd : 0.0;
00946 s = format2Frac.format(d);
00947 out.print(pad(" " + s, 7, 1));
00948
00949
00950 dd = MeasurementValue.MAGNETIZATION.getValue(step);
00951 d = dd != null ? dd : 0.0;
00952 s = format5Numb.format(d);
00953 out.print(pad(" " + s, 11, 1));
00954
00955
00956 d = step.getSusceptibility();
00957 d = d >= 0.0 ? d : Math.max(getSusceptibility(), 0.0);
00958 s = format5Numb.format(d);
00959 out.print(pad(" " + s, 9, 1));
00960
00961
00962 dd = MeasurementValue.THETA63.getValue(step);
00963 d = dd != null ? dd : 0.0;
00964 s = format2Frac.format(d);
00965 out.print(pad(" " + s, 7, 1));
00966
00967
00968 dd = MeasurementValue.SAMPLE_X.getValue(step);
00969 d = dd != null ? dd : 0.0;
00970 s = format5Numb.format(d);
00971 out.print(pad(" " + s, 11, 1));
00972
00973
00974 dd = MeasurementValue.SAMPLE_Y.getValue(step);
00975 d = dd != null ? dd : 0.0;
00976 s = format5Numb.format(d);
00977 out.print(pad(" " + s, 11, 1));
00978
00979
00980 dd = MeasurementValue.SAMPLE_Z.getValue(step);
00981 d = dd != null ? dd : 0.0;
00982 s = format5Numb.format(d);
00983 out.print(pad(" " + s, 11, 1));
00984
00985 out.println();
00986 }
00987
00988
00989 return true;
00990
00991 } catch (FileNotFoundException e) {
00992 e.printStackTrace();
00993 } catch (UnsupportedEncodingException e) {
00994 e.printStackTrace();
00995 } finally {
00996 if (out != null) {
00997 out.close();
00998 }
00999 }
01000 return false;
01001 }
01002
01010 public boolean exportToSRM(File file) {
01011 if (file == null) {
01012 throw new NullPointerException();
01013 }
01014 return false;
01015 }
01016
01024 public boolean exportToTDT(File file) {
01025 if (file == null) {
01026 throw new NullPointerException();
01027 }
01028 PrintStream out = null;
01029 try {
01030 out = new PrintStream(file, "ISO-8859-1");
01031 double d;
01032 Double dd;
01033 String s;
01034
01035
01036 Locale locale = new Locale("en");
01037 DecimalFormat format0Frac = new DecimalFormat("######0", new DecimalFormatSymbols(locale));
01038 DecimalFormat format2Frac = new DecimalFormat("###0.00", new DecimalFormatSymbols(locale));
01039 DecimalFormat format3Frac = new DecimalFormat("##0.000", new DecimalFormatSymbols(locale));
01040
01041
01042 out.println("Thellier-tdt");
01043
01044
01045 s = format3Frac.format(0.0);
01046 out.print(pad(s, Math.max(getName().length(), 8), 1));
01047
01048
01049 s = format2Frac.format(getStrike());
01050 out.print(pad(" " + s, 8, 1));
01051
01052
01053 s = format2Frac.format(getDip());
01054 out.print(pad(" " + s, 8, 1));
01055
01056
01057 try {
01058 d = Double.parseDouble(getProperty(LATITUDE_PROPERTY, "0.0"));
01059 } catch (NumberFormatException e) {
01060 d = 0.0;
01061 }
01062 s = format2Frac.format(d);
01063 out.print(pad(" " + s, 8, 1));
01064
01065
01066 try {
01067 d = Double.parseDouble(getProperty(LONGITUDE_PROPERTY, "0.0"));
01068 } catch (NumberFormatException e) {
01069 d = 0.0;
01070 }
01071 out.print(pad(format2Frac.format(d), 8, 1));
01072 out.println();
01073
01074 for (int i = 0; i < getCompletedSteps(); i++) {
01075 MeasurementStep step = getStep(i);
01076
01077
01078 out.print(pad(getName(), 8, -1));
01079
01080
01081 d = Math.max(step.getStepValue(), 0.0);
01082 if (getType() == THELLIER) {
01083
01084 s = format2Frac.format(d);
01085 } else {
01086
01087 s = format0Frac.format(d) + ".00";
01088 }
01089 out.print(pad(" " + s, 8, 1));
01090
01091
01092 dd = MeasurementValue.MAGNETIZATION.getValue(step);
01093 d = dd != null ? dd : 0.0;
01094 s = format0Frac.format(d);
01095 out.print(pad(" " + s, 8, 1));
01096
01097
01098 dd = MeasurementValue.DECLINATION.getValue(step);
01099 d = dd != null ? dd : 0.0;
01100 s = format0Frac.format(d);
01101 out.print(pad(" " + s, 8, 1));
01102
01103
01104 dd = MeasurementValue.INCLINATION.getValue(step);
01105 d = dd != null ? dd : 0.0;
01106 s = format0Frac.format(d);
01107 out.print(pad(" " + s, 8, 1));
01108
01109 out.println();
01110 }
01111
01112
01113 return true;
01114
01115 } catch (FileNotFoundException e) {
01116 e.printStackTrace();
01117 } catch (UnsupportedEncodingException e) {
01118 e.printStackTrace();
01119 } finally {
01120 if (out != null) {
01121 out.close();
01122 }
01123 }
01124 return false;
01125 }
01126
01130 public synchronized File getFile() {
01131 return file;
01132 }
01133
01137 public synchronized Type getType() {
01138 return type;
01139 }
01140
01144 public synchronized boolean isHolderCalibration() {
01145 if (getType() == CALIBRATION && getFile().equals(Settings.getHolderCalibrationFile())) {
01146 return true;
01147 } else {
01148 return false;
01149 }
01150 }
01151
01157 public synchronized State getState() {
01158 return state;
01159 }
01160
01166 private void setState(State state) {
01167 this.state = state;
01168 fireProjectEvent(STATE_CHANGED);
01169 }
01170
01175 public boolean isClosed() {
01176 return closed;
01177 }
01178
01182 public synchronized String getName() {
01183 String name = getFile().getName();
01184 if (name.endsWith(Ikayaki.FILE_TYPE)) {
01185 name = name.substring(0, name.length() - Ikayaki.FILE_TYPE.length());
01186 }
01187 return name;
01188 }
01189
01196 public synchronized Date getTimestamp() {
01197 for (int i = sequence.getSteps() - 1; i >= 0; i--) {
01198 Date d = sequence.getStep(i).getTimestamp();
01199 if (d != null) {
01200 return d;
01201 }
01202 }
01203 return null;
01204 }
01205
01212 public synchronized Squid getSquid() {
01213 return squid;
01214 }
01215
01228 public synchronized boolean setSquid(Squid squid) {
01229
01230 if (squid == null) {
01231 if (getSquid() == null) {
01232 return true;
01233 }
01234 if (getState() == IDLE && getSquid().setOwner(null)) {
01235 this.squid = null;
01236 fireProjectEvent(STATE_CHANGED);
01237 return true;
01238 }
01239 return false;
01240 }
01241
01242
01243 synchronized (squid) {
01244 if (squid.getOwner() == this) {
01245 return true;
01246 }
01247 if (squid.getOwner() != null) {
01248 squid.getOwner().setSquid(null);
01249 }
01250 if (squid.getOwner() == null && squid.setOwner(this)) {
01251 this.squid = squid;
01252 fireProjectEvent(STATE_CHANGED);
01253 return true;
01254 }
01255 return false;
01256 }
01257 }
01258
01265 public synchronized String getProperty(String key) {
01266 return properties.getProperty(key);
01267 }
01268
01276 public synchronized String getProperty(String key, String defaultValue) {
01277 return properties.getProperty(key, defaultValue);
01278 }
01279
01286 public synchronized void setProperty(String key, String value) {
01287 properties.setProperty(key, value);
01288 save();
01289 }
01290
01294 public synchronized double getStrike() {
01295 return strike;
01296 }
01297
01301 public synchronized void setStrike(double strike) {
01302 this.strike = strike;
01303 updateTransforms();
01304 fireProjectEvent(DATA_CHANGED);
01305 save();
01306 }
01307
01311 public synchronized double getDip() {
01312 return dip;
01313 }
01314
01318 public synchronized void setDip(double dip) {
01319 this.dip = dip;
01320 updateTransforms();
01321 fireProjectEvent(DATA_CHANGED);
01322 save();
01323 }
01324
01328 public synchronized SampleType getSampleType() {
01329 return sampleType;
01330 }
01331
01337 public synchronized void setSampleType(SampleType sampleType) {
01338 if (sampleType == null) {
01339 throw new NullPointerException();
01340 }
01341 this.sampleType = sampleType;
01342 updateTransforms();
01343 fireProjectEvent(DATA_CHANGED);
01344 save();
01345 }
01346
01350 public synchronized Orientation getOrientation() {
01351 return orientation;
01352 }
01353
01359 public synchronized void setOrientation(Orientation orientation) {
01360 if (orientation == null) {
01361 throw new NullPointerException();
01362 }
01363 this.orientation = orientation;
01364 updateTransforms();
01365 fireProjectEvent(DATA_CHANGED);
01366 save();
01367 }
01368
01372 public Normalization getNormalization() {
01373 return normalization;
01374 }
01375
01381 public void setNormalization(Normalization normalization) {
01382 if (normalization == null) {
01383 throw new NullPointerException();
01384 }
01385 this.normalization = normalization;
01386 fireProjectEvent(DATA_CHANGED);
01387 save();
01388 }
01389
01399 protected synchronized Matrix3d getTransform() {
01400 return transform;
01401 }
01402
01407 private synchronized void updateTransforms() {
01408 double s;
01409 double d;
01410 s = Math.toRadians(getStrike());
01411 d = Math.toRadians(getDip());
01412
01413 if (sampleType == CORE) {
01414
01415 transform.setRow(0, sin(d) * cos(s), -sin(s), cos(s) * cos(d));
01416 transform.setRow(1, sin(s) * sin(d), cos(s), cos(d) * sin(s));
01417 transform.setRow(2, -cos(d), 0, sin(d));
01418 } else if (sampleType == HAND) {
01419
01420 transform.setRow(0, cos(s), -sin(s) * cos(d), sin(s) * sin(d));
01421 transform.setRow(1, sin(s), cos(s) * cos(d), -sin(d) * cos(s));
01422 transform.setRow(2, 0, sin(d), cos(d));
01423 } else {
01424 assert false;
01425 }
01426
01427 for (int i = 0; i < sequence.getSteps(); i++) {
01428 sequence.getStep(i).updateTransforms();
01429 }
01430 }
01431
01437 public synchronized double getMass() {
01438 return mass;
01439 }
01440
01446 public synchronized void setMass(double mass) {
01447 if (mass < 0.0) {
01448 mass = -1.0;
01449 }
01450 this.mass = mass;
01451 fireProjectEvent(DATA_CHANGED);
01452 save();
01453 }
01454
01460 public synchronized double getVolume() {
01461 return volume;
01462 }
01463
01469 public synchronized void setVolume(double volume) {
01470 if (volume < 0.0) {
01471 volume = -1.0;
01472 }
01473 this.volume = volume;
01474 fireProjectEvent(DATA_CHANGED);
01475 save();
01476 }
01477
01483 public synchronized double getSusceptibility() {
01484 return susceptibility;
01485 }
01486
01492 public synchronized void setSusceptibility(double susceptibility) {
01493 if (susceptibility < 0.0) {
01494 susceptibility = -1.0;
01495 }
01496 this.susceptibility = susceptibility;
01497 fireProjectEvent(DATA_CHANGED);
01498 save();
01499 }
01500
01506 public synchronized void addProjectListener(ProjectListener l) {
01507 listenerList.add(ProjectListener.class, l);
01508 }
01509
01515 public synchronized void removeProjectListener(ProjectListener l) {
01516 listenerList.remove(ProjectListener.class, l);
01517 }
01518
01524 protected synchronized void fireProjectEvent(ProjectEvent.Type type) {
01525 final ProjectEvent event = new ProjectEvent(this, type);
01526 final ProjectListener[] listeners = listenerList.getListeners(ProjectListener.class);
01527 SwingUtilities.invokeLater(new Runnable() {
01528 public void run() {
01529 for (ProjectListener l : listeners) {
01530 try {
01531 l.projectUpdated(event);
01532 } catch (Throwable t) {
01533 t.printStackTrace();
01534 }
01535 }
01536 }
01537 });
01538 }
01539
01545 public synchronized void addMeasurementListener(MeasurementListener l) {
01546 listenerList.add(MeasurementListener.class, l);
01547 }
01548
01554 public synchronized void removeMeasurementListener(MeasurementListener l) {
01555 listenerList.remove(MeasurementListener.class, l);
01556 }
01557
01564 protected synchronized void fireMeasurementEvent(MeasurementStep step, MeasurementEvent.Type type) {
01565 final MeasurementEvent event = new MeasurementEvent(this, step, type);
01566 final MeasurementListener[] listeners = listenerList.getListeners(MeasurementListener.class);
01567 SwingUtilities.invokeLater(new Runnable() {
01568 public void run() {
01569 for (MeasurementListener l : listeners) {
01570 try {
01571 l.measurementUpdated(event);
01572 } catch (Throwable t) {
01573 t.printStackTrace();
01574 }
01575 }
01576 }
01577 });
01578 }
01579
01590 public synchronized boolean addSequence(MeasurementSequence append) {
01591 if (append == null) {
01592 throw new NullPointerException();
01593 }
01594 if (!isSequenceEditEnabled()) {
01595 assert false;
01596 return false;
01597 }
01598 for (int i = 0; i < append.getSteps(); i++) {
01599 MeasurementStep step = new MeasurementStep(this);
01600 step.setStepValue(append.getStep(i).getStepValue());
01601 sequence.addStep(step);
01602 }
01603 fireProjectEvent(DATA_CHANGED);
01604 save();
01605 return true;
01606 }
01607
01617 public synchronized MeasurementSequence copySequence(int start, int end) {
01618 if (start < 0 || end >= getSteps()) {
01619 throw new IndexOutOfBoundsException();
01620 }
01621 MeasurementSequence copy = new MeasurementSequence();
01622 for (int i = start; i <= end; i++) {
01623 MeasurementStep step = new MeasurementStep();
01624 step.setStepValue(sequence.getStep(i).getStepValue());
01625 copy.addStep(step);
01626 }
01627 return copy;
01628 }
01629
01639 public synchronized MeasurementSequence copySequence(int... indices) {
01640 MeasurementSequence copy = new MeasurementSequence();
01641 for (int i : indices) {
01642 MeasurementStep step = new MeasurementStep();
01643 step.setStepValue(sequence.getStep(i).getStepValue());
01644 copy.addStep(step);
01645 }
01646 return copy;
01647 }
01648
01657 public synchronized boolean addStep(MeasurementStep step) {
01658 if (step == null) {
01659 throw new NullPointerException();
01660 }
01661 double stepValue = step.getStepValue();
01662 step = new MeasurementStep(this);
01663 step.setStepValue(stepValue);
01664 sequence.addStep(step);
01665
01666 fireProjectEvent(DATA_CHANGED);
01667 save();
01668 return true;
01669 }
01670
01686 public synchronized boolean addStep(int index, MeasurementStep step) {
01687 if (step == null) {
01688 throw new NullPointerException();
01689 }
01690 if (index < getCompletedSteps() || index > getSteps()) {
01691 throw new IndexOutOfBoundsException();
01692 }
01693 if (!isSequenceEditEnabled()) {
01694 assert false;
01695 return false;
01696 }
01697 double stepValue = step.getStepValue();
01698 step = new MeasurementStep(this);
01699 step.setStepValue(stepValue);
01700 sequence.addStep(index, step);
01701
01702 fireProjectEvent(DATA_CHANGED);
01703 save();
01704 return true;
01705 }
01706
01717 public synchronized boolean removeStep(int index) {
01718 if (index < getCompletedSteps() || index >= getSteps()) {
01719 throw new IndexOutOfBoundsException();
01720 }
01721 if (!isSequenceEditEnabled()) {
01722 assert false;
01723 return false;
01724 }
01725 sequence.removeStep(index);
01726
01727 fireProjectEvent(DATA_CHANGED);
01728 save();
01729 return true;
01730 }
01731
01743 public synchronized boolean removeStep(int start, int end) {
01744 if (start < getCompletedSteps() || end >= getSteps()) {
01745 throw new IndexOutOfBoundsException();
01746 }
01747 if (!isSequenceEditEnabled()) {
01748 assert false;
01749 return false;
01750 }
01751 for (int i = end; i >= start; i--) {
01752 sequence.removeStep(i);
01753 }
01754 fireProjectEvent(DATA_CHANGED);
01755 save();
01756 return true;
01757 }
01758
01762 public synchronized int getSteps() {
01763 return sequence.getSteps();
01764 }
01765
01770 public synchronized int getCompletedSteps() {
01771 int i;
01772 for (i = sequence.getSteps() - 1; i >= 0; i--) {
01773 MeasurementStep.State state = sequence.getStep(i).getState();
01774 if (state == READY) {
01775 continue;
01776 } else {
01777 break;
01778 }
01779 }
01780 return i + 1;
01781 }
01782
01790 public synchronized MeasurementStep getStep(int index) {
01791 return sequence.getStep(index);
01792 }
01793
01799 public synchronized MeasurementStep getCurrentStep() {
01800 return currentStep;
01801 }
01802
01813 public synchronized <A> A getValue(int index, MeasurementValue<A> algorithm) {
01814 return algorithm.getValue(sequence.getStep(index));
01815 }
01816
01824 private void runMeasurement() {
01825 if (getSquid() == null && !DEBUG) {
01826 throw new IllegalStateException("Unable to run measurement, squid is: " + getSquid());
01827 }
01828 if (getState() == IDLE) {
01829 throw new IllegalStateException("Unable to run measurement, state is: " + getState());
01830 }
01831
01832 try {
01833 if (DEBUG) {
01834 synchronized (DummyMeasurement.class) {
01835 new DummyMeasurement().run();
01836 }
01837 } else {
01838 synchronized (Measurement.class) {
01839 new Measurement().run();
01840 }
01841 }
01842 } catch (Exception e) {
01843 e.printStackTrace();
01844 }
01845 setState(IDLE);
01846 }
01847
01852 public synchronized boolean isDegaussingEnabled() {
01853 if (type == CALIBRATION || type == THELLIER || type == THERMAL) {
01854 return false;
01855 } else if (type == AF) {
01856 return true;
01857 } else {
01858 return false;
01859 }
01860 }
01861
01866 public synchronized boolean isSequenceEditEnabled() {
01867 if (type == CALIBRATION) {
01868 return false;
01869 } else if (type == AF || type == THELLIER || type == THERMAL) {
01870 return true;
01871 } else {
01872 return false;
01873 }
01874 }
01875
01880 public synchronized boolean isManualControlEnabled() {
01881 if (getSquid() == null) {
01882 return false;
01883 }
01884 if (getState() == IDLE) {
01885 return true;
01886 } else {
01887 return false;
01888 }
01889 }
01890
01895 public synchronized boolean isAutoStepEnabled() {
01896 if (getSquid() == null && !DEBUG) {
01897 return false;
01898 }
01899 if (type == CALIBRATION || type == THELLIER || type == THERMAL) {
01900 return false;
01901 } else if (type == AF) {
01902 if (getState() == IDLE) {
01903 return true;
01904 } else {
01905 return false;
01906 }
01907 } else {
01908 return false;
01909 }
01910 }
01911
01916 public synchronized boolean isSingleStepEnabled() {
01917 if (getSquid() == null && !DEBUG) {
01918 return false;
01919 }
01920 if (type == CALIBRATION || type == AF || type == THELLIER || type == THERMAL) {
01921 if (getState() == IDLE) {
01922 return true;
01923 } else {
01924 return false;
01925 }
01926 } else {
01927 return false;
01928 }
01929 }
01930
01935 public synchronized boolean isPauseEnabled() {
01936 if (type == CALIBRATION || type == THELLIER || type == THERMAL) {
01937 return false;
01938 } else if (type == AF) {
01939 if (getState() == MEASURING) {
01940 return true;
01941 } else {
01942 return false;
01943 }
01944 } else {
01945 return false;
01946 }
01947 }
01948
01953 public synchronized boolean isAbortEnabled() {
01954 if (getState() == MEASURING || getState() == PAUSED) {
01955 return true;
01956 } else {
01957 return false;
01958 }
01959 }
01960
01970 public synchronized boolean doAutoStep() {
01971 if (getSquid() == null && !DEBUG) {
01972 return false;
01973 }
01974 if (getState() == IDLE) {
01975 if (isAutoStepEnabled()) {
01976 setState(MEASURING);
01977 } else if (isSingleStepEnabled()) {
01978 setState(PAUSED);
01979 } else {
01980 return false;
01981 }
01982
01983
01984 if (getSteps() == getCompletedSteps()) {
01985 addStep(new MeasurementStep(this));
01986 }
01987
01988 new Thread() {
01989 @Override public void run() {
01990 runMeasurement();
01991 }
01992 }.start();
01993 return true;
01994 } else {
01995 return false;
01996 }
01997 }
01998
02006 public synchronized boolean doSingleStep() {
02007 if (!isSingleStepEnabled()) {
02008 return false;
02009 }
02010
02011 if (doAutoStep()) {
02012 return doPause();
02013 } else {
02014 return false;
02015 }
02016 }
02017
02027 public synchronized boolean doPause() {
02028
02029
02030
02031 if (getState() == IDLE) {
02032 return false;
02033 } else if (getState() == MEASURING) {
02034 setState(PAUSED);
02035 return true;
02036 } else if (getState() == PAUSED) {
02037 return true;
02038 } else {
02039 return false;
02040 }
02041 }
02042
02051 public synchronized boolean doAbort() {
02052 if (!isAbortEnabled()) {
02053 return false;
02054 }
02055 if (getState() == IDLE) {
02056 return false;
02057 } else {
02058 setState(ABORTED);
02059 return true;
02060 }
02061 }
02062
02071 private synchronized boolean doManualMove(ManualMovePosition position) {
02072 if (!isManualControlEnabled()) {
02073 return false;
02074 }
02075 setState(PAUSED);
02076 new Thread(new ManualMove(position)).start();
02077 return true;
02078 }
02079
02087 public synchronized boolean doManualMoveDegausserY() {
02088 return doManualMove(ManualMovePosition.DEGAUSSER_Y);
02089 }
02090
02098 public synchronized boolean doManualMoveDegausserZ() {
02099 return doManualMove(ManualMovePosition.DEGAUSSER_Z);
02100 }
02101
02109 public synchronized boolean doManualMoveBackground() {
02110 return doManualMove(ManualMovePosition.BACKGROUND);
02111 }
02112
02120 public synchronized boolean doManualMoveMeasurement() {
02121 return doManualMove(ManualMovePosition.MEASUREMENT);
02122 }
02123
02132 public synchronized boolean doManualMoveHome() {
02133 return doManualMove(ManualMovePosition.HOME);
02134 }
02135
02144 public synchronized boolean doManualMoveRightLimit() {
02145 return doManualMove(ManualMovePosition.RIGHT_LIMIT);
02146 }
02147
02156 public synchronized boolean doManualMoveLeftLimit() {
02157 return doManualMove(ManualMovePosition.LEFT_LIMIT);
02158 }
02159
02160
02169 public synchronized boolean doManualRotate(int angle) {
02170 if (!isManualControlEnabled()) {
02171 return false;
02172 }
02173 setState(PAUSED);
02174 new Thread(new ManualRotate(angle)).start();
02175 return true;
02176 }
02177
02186 public synchronized boolean doManualMeasure() {
02187 if (!isManualControlEnabled()) {
02188 return false;
02189 }
02190 setState(PAUSED);
02191 new Thread(new ManualMeasure()).start();
02192 return true;
02193 }
02194
02195
02203 public synchronized boolean doManualReset() {
02204 if (!isManualControlEnabled()) {
02205 return false;
02206 }
02207 setState(PAUSED);
02208 new Thread(new Runnable() {
02209 public void run() {
02210 if (getSquid() == null) {
02211 throw new IllegalStateException();
02212 }
02213
02214 getSquid().getMagnetometer().pulseReset('A');
02215 getSquid().getMagnetometer().clearFlux('A');
02216 setState(IDLE);
02217 }
02218 }).start();
02219 return true;
02220 }
02221
02231 public synchronized boolean doManualDemagZ(double amplitude) {
02232 if (!isManualControlEnabled()) {
02233 return false;
02234 }
02235 setState(PAUSED);
02236 new Thread(new ManualDemag(ManualDemagAxel.Z, amplitude)).start();
02237 return true;
02238 }
02239
02249 public synchronized boolean doManualDemagY(double amplitude) {
02250 if (!isManualControlEnabled()) {
02251 return false;
02252 }
02253 setState(PAUSED);
02254 new Thread(new ManualDemag(ManualDemagAxel.Y, amplitude)).start();
02255 return true;
02256 }
02257
02265 public synchronized boolean doManualStepDone() {
02266 if (!isManualControlEnabled()) {
02267 return false;
02268 }
02269 if (currentStep != null) {
02270 currentStep.setDone();
02271 fireMeasurementEvent(currentStep, STEP_END);
02272 currentStep = null;
02273 }
02274 return true;
02275 }
02276
02280 public enum Type {
02281 CALIBRATION("Calibration"), AF("AF"), THELLIER("Thellier"), THERMAL("Thermal");
02282
02283 private String name;
02284
02285 private Type(String name) {
02286 this.name = name;
02287 }
02288
02289 @Override public String toString() {
02290 return name;
02291 }
02292 }
02293
02297 public enum State {
02298 IDLE, MEASURING, PAUSED, ABORTED
02299 }
02300
02304 public enum SampleType {
02305 CORE, HAND
02306 }
02307
02311 public enum Orientation {
02312 PLUS_Z, MINUS_Z
02313 }
02314
02318 public enum Normalization {
02319 VOLUME, MASS
02320 }
02321
02326 private class Measurement implements Runnable {
02327 public void run() {
02328 if (getState() == IDLE) {
02329 throw new IllegalStateException();
02330 }
02331 if (getSquid() == null) {
02332 throw new IllegalStateException();
02333 }
02334
02335 for (int i = getCompletedSteps(); i < getSteps(); i++) {
02336
02337
02338 currentStep = getStep(i);
02339 currentStep.setMeasuring();
02340 fireMeasurementEvent(currentStep, STEP_START);
02341
02342 try {
02343
02344 if (getSquid().getHandler().getRotation() != 0) {
02345 getSquid().getHandler().rotateTo(0);
02346 getSquid().getHandler().join();
02347 }
02348 checkAborted();
02349
02350
02351 if (currentStep.getStepValue() > 0.05 && isDegaussingEnabled()) {
02352
02353
02354 getSquid().getHandler().moveToDegausserZ();
02355 fireMeasurementEvent(currentStep, HANDLER_MOVE);
02356 getSquid().getHandler().join();
02357 fireMeasurementEvent(currentStep, HANDLER_STOP);
02358 checkAborted();
02359 fireMeasurementEvent(currentStep, DEMAGNETIZE_START);
02360 if (!getSquid().getDegausser().demagnetizeZ(currentStep.getStepValue())) {
02361 throw new InterruptedException("demagnetizeZ = false");
02362 }
02363 fireMeasurementEvent(currentStep, DEMAGNETIZE_END);
02364 checkAborted();
02365
02366
02367 getSquid().getHandler().moveToDegausserY();
02368 fireMeasurementEvent(currentStep, HANDLER_MOVE);
02369 getSquid().getHandler().join();
02370 fireMeasurementEvent(currentStep, HANDLER_STOP);
02371 checkAborted();
02372 fireMeasurementEvent(currentStep, DEMAGNETIZE_START);
02373 if (!getSquid().getDegausser().demagnetizeY(currentStep.getStepValue())) {
02374 throw new InterruptedException("demagnetizeY = false");
02375 }
02376 fireMeasurementEvent(currentStep, DEMAGNETIZE_END);
02377 checkAborted();
02378
02379
02380 getSquid().getHandler().rotateTo(90);
02381 fireMeasurementEvent(currentStep, HANDLER_ROTATE);
02382 getSquid().getHandler().join();
02383 fireMeasurementEvent(currentStep, HANDLER_STOP);
02384 checkAborted();
02385 fireMeasurementEvent(currentStep, DEMAGNETIZE_START);
02386 if (!getSquid().getDegausser().demagnetizeY(currentStep.getStepValue())) {
02387 throw new InterruptedException("demagnetizeY = false");
02388 }
02389 fireMeasurementEvent(currentStep, DEMAGNETIZE_END);
02390 checkAborted();
02391 getSquid().getHandler().rotateTo(0);
02392 fireMeasurementEvent(currentStep, HANDLER_ROTATE);
02393 getSquid().getHandler().join();
02394 fireMeasurementEvent(currentStep, HANDLER_STOP);
02395 checkAborted();
02396 }
02397
02398
02399 getSquid().getHandler().moveToBackground();
02400 fireMeasurementEvent(currentStep, HANDLER_MOVE);
02401 getSquid().getHandler().join();
02402 fireMeasurementEvent(currentStep, HANDLER_STOP);
02403 checkAborted();
02404
02405
02406 getSquid().getMagnetometer().pulseReset('A');
02407 getSquid().getMagnetometer().clearFlux('A');
02408 double[] results = getSquid().getMagnetometer().readData();
02409 currentStep.addResult(new MeasurementResult(NOISE, 0, results[0], results[1], results[2]));
02410 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02411 checkAborted();
02412
02413
02414 getSquid().getHandler().moveToMeasurement();
02415 fireMeasurementEvent(currentStep, HANDLER_MOVE);
02416 getSquid().getHandler().join();
02417 fireMeasurementEvent(currentStep, HANDLER_STOP);
02418 checkAborted();
02419
02420
02421 int rotations = Settings.getMeasurementRotations();
02422 if (rotations == 0) {
02423
02424
02425 results = getSquid().getMagnetometer().readData();
02426 currentStep.addResult(new MeasurementResult(SAMPLE, 0, results[0], results[1], results[2]));
02427 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02428 checkAborted();
02429
02430 } else {
02431
02432
02433 for (int j = 0; j < rotations; j++) {
02434
02435
02436 results = getSquid().getMagnetometer().readData();
02437 currentStep.addResult(new MeasurementResult(SAMPLE, 0, results[0], results[1], results[2]));
02438 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02439 checkAborted();
02440
02441
02442 getSquid().getHandler().rotateTo(90);
02443 fireMeasurementEvent(currentStep, HANDLER_ROTATE);
02444 getSquid().getHandler().join();
02445 fireMeasurementEvent(currentStep, HANDLER_STOP);
02446 checkAborted();
02447 results = getSquid().getMagnetometer().readData();
02448 currentStep.addResult(
02449 new MeasurementResult(SAMPLE, 90, results[0], results[1], results[2]));
02450 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02451 checkAborted();
02452
02453
02454 getSquid().getHandler().rotateTo(180);
02455 fireMeasurementEvent(currentStep, HANDLER_ROTATE);
02456 getSquid().getHandler().join();
02457 fireMeasurementEvent(currentStep, HANDLER_STOP);
02458 checkAborted();
02459 results = getSquid().getMagnetometer().readData();
02460 currentStep.addResult(
02461 new MeasurementResult(SAMPLE, 180, results[0], results[1], results[2]));
02462 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02463 checkAborted();
02464
02465
02466 getSquid().getHandler().rotateTo(270);
02467 fireMeasurementEvent(currentStep, HANDLER_ROTATE);
02468 getSquid().getHandler().join();
02469 fireMeasurementEvent(currentStep, HANDLER_STOP);
02470 checkAborted();
02471 results = getSquid().getMagnetometer().readData();
02472 currentStep.addResult(
02473 new MeasurementResult(SAMPLE, 270, results[0], results[1], results[2]));
02474 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02475 checkAborted();
02476
02477
02478 getSquid().getHandler().rotateTo(0);
02479 fireMeasurementEvent(currentStep, HANDLER_ROTATE);
02480 getSquid().getHandler().join();
02481 fireMeasurementEvent(currentStep, HANDLER_STOP);
02482 checkAborted();
02483 }
02484 }
02485
02486
02487 getSquid().getHandler().moveToBackground();
02488 fireMeasurementEvent(currentStep, HANDLER_MOVE);
02489 getSquid().getHandler().join();
02490 fireMeasurementEvent(currentStep, HANDLER_STOP);
02491 checkAborted();
02492 results = getSquid().getMagnetometer().readData();
02493 currentStep.addResult(new MeasurementResult(NOISE, 0, results[0], results[1], results[2]));
02494 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02495 checkAborted();
02496
02497 } catch (InterruptedException e) {
02498
02499
02500 if (getState() == ABORTED) {
02501 System.err.println(e.getMessage());
02502 } else {
02503 e.printStackTrace();
02504 }
02505 } catch (IllegalStateException e) {
02506 e.printStackTrace();
02507 } finally {
02508
02509
02510 currentStep.setDone();
02511 fireMeasurementEvent(currentStep, STEP_END);
02512 currentStep = null;
02513 }
02514
02515 if (getState() == PAUSED || getState() == ABORTED) {
02516 setState(IDLE);
02517 return;
02518 }
02519 }
02520 setState(IDLE);
02521 }
02522
02529 private void checkAborted() throws InterruptedException {
02530 if (getState() == ABORTED) {
02531 fireMeasurementEvent(currentStep, STEP_ABORTED);
02532 throw new InterruptedException("Measurement aborted");
02533 }
02534 }
02535 }
02536
02541 private class DummyMeasurement implements Runnable {
02542 public void run() {
02543 if (getState() == IDLE) {
02544 throw new IllegalStateException();
02545 }
02546
02547 System.out.println("Measurement started");
02548 for (int i = getCompletedSteps(); i < getSteps(); i++) {
02549
02550 System.out.println("Measuring step " + i + "...");
02551 currentStep = getStep(i);
02552 currentStep.setMeasuring();
02553 fireMeasurementEvent(currentStep, STEP_START);
02554
02555 try {
02556
02557 Thread.sleep(500);
02558 if (getState() == ABORTED) {
02559 System.out.println("Measurement aborted");
02560 setState(IDLE);
02561 return;
02562 }
02563 currentStep.addResult(new MeasurementResult(NOISE, 0,
02564 Math.random() * 0.000001, Math.random() * 0.000001, Math.random() * 0.000001));
02565 System.out.println("Result added");
02566 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02567
02568
02569 Thread.sleep(500);
02570 if (getState() == ABORTED) {
02571 System.out.println("Measurement aborted");
02572 setState(IDLE);
02573 currentStep.setDone();
02574 return;
02575 }
02576 currentStep.addResult(new MeasurementResult(SAMPLE, 0,
02577 Math.random() * 0.0001, Math.random() * 0.0001, Math.random() * 0.0001));
02578 System.out.println("Result added");
02579 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02580
02581
02582 Thread.sleep(500);
02583 if (getState() == ABORTED) {
02584 System.out.println("Measurement aborted");
02585 setState(IDLE);
02586 currentStep.setDone();
02587 return;
02588 }
02589 currentStep.addResult(new MeasurementResult(SAMPLE, 90,
02590 Math.random() * 0.0001, Math.random() * 0.0001, Math.random() * 0.0001));
02591 System.out.println("Result added");
02592 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02593
02594
02595 Thread.sleep(500);
02596 if (getState() == ABORTED) {
02597 System.out.println("Measurement aborted");
02598 setState(IDLE);
02599 currentStep.setDone();
02600 return;
02601 }
02602 currentStep.addResult(new MeasurementResult(SAMPLE, 180,
02603 Math.random() * 0.0001, Math.random() * 0.0001, Math.random() * 0.0001));
02604 System.out.println("Result added");
02605 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02606
02607
02608 Thread.sleep(500);
02609 if (getState() == ABORTED) {
02610 System.out.println("Measurement aborted");
02611 setState(IDLE);
02612 currentStep.setDone();
02613 return;
02614 }
02615 currentStep.addResult(new MeasurementResult(SAMPLE, 270,
02616 Math.random() * 0.0001, Math.random() * 0.0001, Math.random() * 0.0001));
02617 System.out.println("Result added");
02618 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02619
02620
02621 Thread.sleep(500);
02622 if (getState() == ABORTED) {
02623 System.out.println("Measurement aborted");
02624 setState(IDLE);
02625 currentStep.setDone();
02626 return;
02627 }
02628 currentStep.addResult(new MeasurementResult(NOISE, 0,
02629 Math.random() * 0.000001, Math.random() * 0.000001, Math.random() * 0.000001));
02630 System.out.println("Result added");
02631 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02632
02633 } catch (InterruptedException e) {
02634 e.printStackTrace();
02635 } finally {
02636
02637 currentStep.setDone();
02638 System.out.println("Step " + i + " completed");
02639 fireMeasurementEvent(currentStep, STEP_END);
02640 currentStep = null;
02641 }
02642
02643 if (getState() == PAUSED) {
02644 System.out.println("Measurement ended (paused)");
02645 setState(IDLE);
02646 return;
02647 }
02648 }
02649 System.out.println("Measurement ended");
02650 setState(IDLE);
02651 }
02652 }
02653
02654 private enum ManualMovePosition {
02655 DEGAUSSER_Y,
02656 DEGAUSSER_Z,
02657 BACKGROUND,
02658 MEASUREMENT,
02659 HOME,
02660 RIGHT_LIMIT,
02661 LEFT_LIMIT
02662 }
02663
02667 private class ManualMove implements Runnable {
02668
02669 private ManualMovePosition pos;
02670
02671 public ManualMove(ManualMovePosition pos) {
02672 this.pos = pos;
02673 }
02674
02675 public void run() {
02676 if (getState() == IDLE) {
02677 throw new IllegalStateException();
02678 }
02679 if (getSquid() == null) {
02680 throw new IllegalStateException();
02681 }
02682
02683 switch (pos) {
02684 case DEGAUSSER_Y:
02685 getSquid().getHandler().moveToDegausserY();
02686 break;
02687 case DEGAUSSER_Z:
02688 getSquid().getHandler().moveToDegausserZ();
02689 break;
02690 case BACKGROUND:
02691 getSquid().getHandler().moveToBackground();
02692 break;
02693 case MEASUREMENT:
02694 getSquid().getHandler().moveToMeasurement();
02695 break;
02696 case HOME:
02697 getSquid().getHandler().moveToSampleLoad();
02698 break;
02699 case RIGHT_LIMIT:
02700 getSquid().getHandler().moveToRightLimit();
02701 break;
02702 case LEFT_LIMIT:
02703 getSquid().getHandler().moveToLeftLimit();
02704 break;
02705 default:
02706 System.err.println("Invalid pos: " + pos);
02707 assert false;
02708 break;
02709 }
02710 fireMeasurementEvent(null, HANDLER_MOVE);
02711
02712 try {
02713 getSquid().getHandler().join();
02714 } catch (InterruptedException e) {
02715 e.printStackTrace();
02716 }
02717 fireMeasurementEvent(null, HANDLER_STOP);
02718 setState(IDLE);
02719 }
02720 }
02721
02725 private class ManualRotate implements Runnable {
02726
02727 private int angle;
02728
02729 public ManualRotate(int angle) {
02730 this.angle = angle;
02731 }
02732
02733 public void run() {
02734 if (getState() == IDLE) {
02735 throw new IllegalStateException();
02736 }
02737 if (getSquid() == null) {
02738 throw new IllegalStateException();
02739 }
02740
02741 getSquid().getHandler().rotateTo(angle);
02742 fireMeasurementEvent(null, HANDLER_ROTATE);
02743
02744 try {
02745 getSquid().getHandler().join();
02746 } catch (InterruptedException e) {
02747 e.printStackTrace();
02748 }
02749 fireMeasurementEvent(null, HANDLER_STOP);
02750
02751 setState(IDLE);
02752 }
02753 }
02754
02759 private class ManualMeasure implements Runnable {
02760 public void run() {
02761 if (getState() == IDLE) {
02762 throw new IllegalStateException();
02763 }
02764 if (getSquid() == null) {
02765 throw new IllegalStateException();
02766 }
02767
02768
02769 if (currentStep == null) {
02770 int i = getCompletedSteps();
02771 if (i == getSteps()) {
02772 addStep(new MeasurementStep(Project.this));
02773 }
02774 currentStep = getStep(i);
02775 currentStep.setMeasuring();
02776 fireMeasurementEvent(currentStep, STEP_START);
02777 }
02778
02779 double[] results = getSquid().getMagnetometer().readData();
02780
02781
02782 MeasurementResult.Type resultType;
02783 int rotation;
02784 if (getSquid().getHandler().getPosition() == Settings.getHandlerMeasurementPosition()) {
02785 resultType = SAMPLE;
02786 rotation = getSquid().getHandler().getRotation();
02787 } else {
02788 resultType = NOISE;
02789 rotation = 0;
02790 }
02791 currentStep.addResult(new MeasurementResult(resultType, rotation, results[0], results[1], results[2]));
02792 fireMeasurementEvent(currentStep, VALUE_MEASURED);
02793
02794 setState(IDLE);
02795 }
02796 }
02797
02798 private enum ManualDemagAxel {
02799 Z,
02800 Y
02801 }
02802
02807 private class ManualDemag implements Runnable {
02808
02809 private ManualDemagAxel axel;
02810 private double amplitude;
02811
02812 public ManualDemag(ManualDemagAxel axel, double amplitude) {
02813 if (axel == null) {
02814 throw new NullPointerException();
02815 }
02816 this.axel = axel;
02817 this.amplitude = amplitude;
02818 }
02819
02820 public void run() {
02821 if (getState() == IDLE) {
02822 throw new IllegalStateException("getState() == IDLE");
02823 }
02824 if (getSquid() == null) {
02825 throw new IllegalStateException("getSquid() == null");
02826 }
02827 if (!isDegaussingEnabled()) {
02828 throw new IllegalStateException("!isDegaussingEnabled()");
02829 }
02830
02831 amplitude = Math.max(amplitude, Settings.getDegausserMinimumField());
02832 amplitude = Math.min(amplitude, Settings.getDegausserMaximumField());
02833
02834
02835 if (currentStep != null) {
02836 currentStep.setDone();
02837 fireMeasurementEvent(currentStep, STEP_END);
02838 currentStep = null;
02839 }
02840
02841
02842 int i = getCompletedSteps();
02843 if (i == getSteps()) {
02844 addStep(new MeasurementStep(Project.this));
02845 }
02846 currentStep = getStep(i);
02847 currentStep.setStepValue(amplitude);
02848 currentStep.setMeasuring();
02849 fireMeasurementEvent(currentStep, STEP_START);
02850
02851
02852 fireMeasurementEvent(currentStep, DEMAGNETIZE_START);
02853 switch (axel) {
02854 case Y:
02855 getSquid().getDegausser().demagnetizeY(amplitude);
02856 break;
02857 case Z:
02858 getSquid().getDegausser().demagnetizeZ(amplitude);
02859 break;
02860 default:
02861 System.err.println("Invalid axel: " + axel);
02862 assert false;
02863 break;
02864 }
02865 fireMeasurementEvent(currentStep, DEMAGNETIZE_END);
02866
02867 setState(IDLE);
02868 }
02869 }
02870 }