diff --git a/.project b/.project index 9ee4af40..48129c11 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - PamGuard Main DG + PamGuard Main Tethys diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs index ad634f29..4df196f4 100644 --- a/.settings/org.eclipse.core.resources.prefs +++ b/.settings/org.eclipse.core.resources.prefs @@ -1,2 +1,4 @@ eclipse.preferences.version=1 encoding//src/rawDeepLearningClassifer/segmenter/SegmenterProcess.java=UTF-8 +encoding/=UTF-8 +encoding/src=UTF-8 diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index fa93561f..84337666 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ org.pamguard Pamguard Pamguard Java12+ - 2.02.09e + 2.02.09f Pamguard for Java 12+, using Maven to control dependcies www.pamguard.org @@ -17,6 +17,7 @@ src + META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA **/*.java jars/*.* @@ -196,6 +197,10 @@ 11 11 + UTF-8 16 + 2.4.0-b180830.0438 + 2.4.0-b180830.0438 + 2.4.0-b180830.0359 diff --git a/pom.xml b/pom.xml index 8c39e533..2a1ff678 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,10 @@ - - 4.0.0 - org.pamguard - Pamguard - 2.02.09e - Pamguard Java12+ - Pamguard for Java 12+, using Maven to control dependcies + + 4.0.0 + org.pamguard + Pamguard + 2.02.09f + Pamguard Java12+ + Pamguard for Java 12+, using Maven to control dependcies www.pamguard.org Sea Mammal Research Unit, University of St. Andrews @@ -14,27 +12,33 @@ - - 16 - 11 - 11 - + + 16 + 11 + 11 + UTF-8 + 2.4.0-b180830.0438 + 2.4.0-b180830.0359 + 2.4.0-b180830.0438 + - - src - - - src - - **/*.java - jars/*.* - - - - - - - + jars/*.* + + + + + + + + - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - - 11 - jdt - - .settings/org.eclipse.jdt.core.prefs - - - - - - - org.eclipse.tycho - tycho-compiler-jdt - 1.5.1 - - - - - - - org.openjfx - javafx-maven-plugin - 0.0.6 - - 17 - 17 - 17 - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.1 - - - - - - - - package - - shade - - - - - - pamguard.Pamguard - . - Resources/pgBlankSplash.png - - - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - + --> + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + - - - com.github.marschall - jdeps-maven-plugin - 0.5.1 - + + 11 + jdt + + .settings/org.eclipse.jdt.core.prefs + + - - - org.apache.maven.plugins - maven-dependency-plugin - 3.1.1 - - - copy-dependencies - package - - copy-dependencies - - - ${project.build.directory}/tempDependencies - false - false - true - - - - + + org.eclipse.tycho + tycho-compiler-jdt + 1.5.1 + + + + + + + org.openjfx + javafx-maven-plugin + 0.0.6 + + 17 + 17 + 17 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.1 + + + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + package + + shade + + + + + + pamguard.Pamguard + . + Resources/pgBlankSplash.png + + + + + + + + + + + + com.github.marschall + jdeps-maven-plugin + 0.5.1 + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/tempDependencies + false + false + true + + + + - - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.apache.maven.plugins - + maven-dependency-plugin - + [3.1.1,) - - + + purge-local-repository - - - - - - - - - - - - - - - - - - com.github.marschall - jdeps-maven-plugin - 0.5.1 - - - - - - - - + + + + + + + + + + + + + + + + + + com.github.marschall + jdeps-maven-plugin + 0.5.1 + + + + + + + + @@ -246,35 +253,35 @@ file://${project.basedir}/repo - - - + - - - - - - - - - - - - - false - - unidata-all - Unidata netCDF - https://artifacts.unidata.ucar.edu/repository/unidata-all/ - - - + + + + + + + + + + + + false + + unidata-all + Unidata netCDF + https://artifacts.unidata.ucar.edu/repository/unidata-all/ + + + - - - - - false - - bedatadriven - bedatadriven_renjin - https://nexus.bedatadriven.com/content/groups/public/ - - - - - false - - talan - talan - https://nexus.talanlabs.com/content/repositories/releases/ - - - - central - https://repo1.maven.org/maven2 - - + + + + + false + + bedatadriven + bedatadriven_renjin + https://nexus.bedatadriven.com/content/groups/public/ + + + + + false + + talan + talan + https://nexus.talanlabs.com/content/repositories/releases/ + + + + central + https://repo1.maven.org/maven2 + + - - + + - - - io.github.macster110 - jpamutils - 0.0.56 - + + + io.github.macster110 + jpamutils + 0.0.56 + - - - io.github.macster110 - jdl4pam - 0.0.94 - - - - - gov.nist.math - jama - 1.0.3 - - - - - - org.openjfx - javafx-controls - ${javafx.version} - + + io.github.macster110 + jdl4pam + 0.0.94 + - - - - org.openjfx - javafx-swing - ${javafx.version} - - - - - - org.openjfx - javafx-media - ${javafx.version} - + + + gov.nist.math + jama + 1.0.3 + - - + - - org.openjfx - javafx-web - ${javafx.version} - - - - - net.synedra - validatorfx - 0.4.0 - - - - - org.apache.commons - commons-compress - 1.19 - + + org.openjfx + javafx-controls + ${javafx.version} + - - - org.apache.commons - commons-csv - 1.7 - - - - - commons-io - commons-io - 2.6 - - - - - org.apache.commons - commons-lang3 - 3.9 - - - - - org.apache.commons - commons-math3 - 3.6.1 - - - - - org.apache.commons - commons-math - 2.2 - - - - - commons-net - commons-net - 3.6 - - - - - org.controlsfx - controlsfx - 11.0.0 - - - org.openjfx - javafx-base - - - org.openjfx - javafx-controls - - - org.openjfx - javafx-graphics - - - org.openjfx - javafx-media - - - org.openjfx - javafx-web - - - - - - + + + org.openjfx + javafx-swing + ${javafx.version} + + + + + + org.openjfx + javafx-media + ${javafx.version} + + + + + + org.openjfx + javafx-web + ${javafx.version} + + + + + net.synedra + validatorfx + 0.4.0 + + + + + org.apache.commons + commons-compress + 1.19 + + + + + org.apache.commons + commons-csv + 1.7 + + + + + commons-io + commons-io + 2.6 + + + + + org.apache.commons + commons-lang3 + 3.9 + + + + + org.apache.commons + commons-math3 + 3.6.1 + + + + + org.apache.commons + commons-math + 2.2 + + + + + commons-net + commons-net + 3.6 + + + + + org.controlsfx + controlsfx + 11.0.0 + + + org.openjfx + javafx-base + + + org.openjfx + javafx-controls + + + org.openjfx + javafx-graphics + + + org.openjfx + javafx-media + + + org.openjfx + javafx-web + + + + + + - - org.kordamp.ikonli - ikonli-javafx - 12.2.0 - - - - + - - - - org.kordamp.ikonli - ikonli-materialdesign2-pack - 12.2.0 - - - - - net.sf.geographiclib - GeographicLib-Java - 1.50 - - - - - org.jogamp.gluegen - gluegen-rt-main - 2.3.2 - - - - - - - - com.healthmarketscience.jackcess - jackcess - 3.0.1 - - - - - com.fasterxml.jackson.core - jackson-databind - 2.10.1 - - - - - org.jogamp.jogl - jogl-all-main - 2.3.2 - - - + + org.kordamp.ikonli + ikonli-materialdesign2-pack + 12.2.0 + + + + + net.sf.geographiclib + GeographicLib-Java + 1.50 + + + + + org.jogamp.gluegen + gluegen-rt-main + 2.3.2 + + + + + + + + + com.healthmarketscience.jackcess + jackcess + 3.0.1 + + + + + com.fasterxml.jackson.core + jackson-databind + 2.10.1 + + + + + org.jogamp.jogl + jogl-all-main + 2.3.2 + + + - - - - org.jflac - jflac-codec - 1.5.2 - - - - - javax.help - javahelp - 2.0.05 - - - - - net.java.dev.jna - jna - 5.5.0 - - + + + + org.jflac + jflac-codec + 1.5.2 + + + + + javax.help + javahelp + 2.0.05 + + + + + net.java.dev.jna + jna + 5.5.0 + + - - net.java.dev.jna - jna-platform - 5.5.0 - - - - - com.jcraft - jsch - 0.1.55 - - - - - com.fazecast - jSerialComm - 2.5.3 - + + net.java.dev.jna + jna-platform + 5.5.0 + - - - edu.emory.mathcs - JTransforms - 2.4 - + + + com.jcraft + jsch + 0.1.55 + - - - com.sun.mail - javax.mail - 1.6.2 - + + + com.fazecast + jSerialComm + 2.5.3 + - - - com.diffplug.matsim - matfilerw - 3.1.1 - + + + edu.emory.mathcs + JTransforms + 2.4 + - - - com.drewnoakes - metadata-extractor - 2.12.0 - + + + com.sun.mail + javax.mail + 1.6.2 + - - - mysql - mysql-connector-java - 8.0.18 - + + + com.diffplug.matsim + matfilerw + 3.1.1 + - - - + + com.drewnoakes + metadata-extractor + 2.12.0 + + + + + mysql + mysql-connector-java + 8.0.18 + + + + + - - com.google.protobuf - protobuf-java - 3.17.0 - - - - - - edu.ucar - netcdfAll - 4.6.14 - - + com.google.protobuf protobuf-java - - - com.google.protobuf - protobuf-java-util - - - compile - + 3.17.0 + - - - com.opencsv - opencsv - 5.0 - + + + + edu.ucar + netcdfAll + 4.6.14 + + + com.google.protobuf + protobuf-java + + + com.google.protobuf + protobuf-java-util + + + compile + - + + + com.opencsv + opencsv + 5.0 + - - - org.postgresql - postgresql - 42.2.24 - + - - - org.renjin - renjin-script-engine - 0.9.2725 - - - + + org.postgresql + postgresql + 42.2.24 + + + + + org.renjin + renjin-script-engine + 0.9.2725 + + + - - org.slf4j - slf4j-api - 1.8.0-beta4 - - - - - - - org.slf4j - slf4j-nop - 1.8.0-beta4 - - - + + org.slf4j + slf4j-api + 1.8.0-beta4 + - - + + org.slf4j + slf4j-nop + 1.8.0-beta4 + + + + + - - - org.docx4j - docx4j-JAXB-ReferenceImpl - 11.1.3 - - + - - - org.xerial - sqlite-jdbc - 3.28.0 - + + + org.xerial + sqlite-jdbc + 3.28.0 + - - - net.sf.ucanaccess - ucanaccess - 4.0.4 - + + + net.sf.ucanaccess + ucanaccess + 4.0.4 + - - - nz.ac.waikato.cms.weka - weka-dev - 3.7.7 - + + + nz.ac.waikato.cms.weka + weka-dev + 3.7.7 + - - - javax.vecmath - vecmath - 1.5.2 - + + + javax.vecmath + vecmath + 1.5.2 + - - - - + + org.eclipse.persistence + org.eclipse.persistence.moxy + 2.5.0 + + + javax.xml.bind + jaxb-api + ${jaxb.api.version} + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb.runtime.version} + + + org.glassfish.jaxb + jaxb-xjc + ${jaxb.xjc.version} + + + + com.sun.jersey.contribs + jersey-multipart + 1.18.1 + + + commons-cli + commons-cli + 1.2 + + + org.apache.poi + poi + 3.10-beta1 + + + com.sun.jersey + jersey-client + 1.18.1 + + + com.sun.jersey.contribs + jersey-apache-client + 1.18.1 + + + com.miglayout + miglayout + 3.7.4 + + + ca.juliusdavies + not-yet-commons-ssl + 0.3.11 + + + javax.ws.rs + javax.ws.rs-api + 2.1.1 + + + javax.xml.bind + jaxb-api + 2.2.11 + + + com.sun.xml.bind + jaxb-impl + 2.2.11 + + + javax.activation + activation + 1.1 + + + org.glassfish.jaxb + jaxb-core + 2.2.11 + + + org.glassfish.jersey.core + jersey-common + 2.2 + + + org.apache.commons + commons-text + 1.9 + + + + - - pamguard.org - x3 - 2.2.6 - + + pamguard.org + x3 + 2.2.6 + + + + + + tethys.org + nilus + 3.0 + + + + tethys.org + javaclient + 3.0 + + - - - it.sauronsoftware - jave - 1.0.2 - - - - - com.synthbot - jasiohost - 1.0.0 - + + it.sauronsoftware + jave + 1.0.2 + - - + + com.synthbot + jasiohost + 1.0.0 + + + + - - - - org.springframework - spring-core - 5.2.3.RELEASE - - - - - - com.1stleg - jnativehook - 2.1.0 - - - - - - org.swinglabs.swingx - swingx-all - 1.6.5-1 - - - - io.github.mkpaz - atlantafx-base - 1.0.0 - - - - + + + org.springframework + spring-core + 5.2.3.RELEASE + + + + + + com.1stleg + jnativehook + 2.1.0 + + + + + + org.swinglabs.swingx + swingx-all + 1.6.5-1 + + + + + io.github.mkpaz + atlantafx-base + 1.0.0 + + + + \ No newline at end of file diff --git a/repo/tethys/org/javaclient/3.0/_remote.repositories b/repo/tethys/org/javaclient/3.0/_remote.repositories new file mode 100644 index 00000000..432cee9e --- /dev/null +++ b/repo/tethys/org/javaclient/3.0/_remote.repositories @@ -0,0 +1,4 @@ +#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 11:13:37 GMT 2023 +javaclient-3.0.jar>= +javaclient-3.0.pom>= diff --git a/repo/tethys/org/javaclient/3.0/javaclient-3.0.jar b/repo/tethys/org/javaclient/3.0/javaclient-3.0.jar new file mode 100644 index 00000000..d1654195 Binary files /dev/null and b/repo/tethys/org/javaclient/3.0/javaclient-3.0.jar differ diff --git a/repo/tethys/org/javaclient/3.0/javaclient-3.0.pom b/repo/tethys/org/javaclient/3.0/javaclient-3.0.pom new file mode 100644 index 00000000..80fee21c --- /dev/null +++ b/repo/tethys/org/javaclient/3.0/javaclient-3.0.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + tethys.org + javaclient + 3.0 + POM was created from install:install-file + diff --git a/repo/tethys/org/javaclient/maven-metadata-local.xml b/repo/tethys/org/javaclient/maven-metadata-local.xml new file mode 100644 index 00000000..629dfa04 --- /dev/null +++ b/repo/tethys/org/javaclient/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + tethys.org + javaclient + + 3.0 + + 3.0 + + 20231221111337 + + diff --git a/repo/tethys/org/nilus/3.0/_remote.repositories b/repo/tethys/org/nilus/3.0/_remote.repositories new file mode 100644 index 00000000..a5060b8b --- /dev/null +++ b/repo/tethys/org/nilus/3.0/_remote.repositories @@ -0,0 +1,4 @@ +#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 11:14:13 GMT 2023 +nilus-3.0.pom>= +nilus-3.0.jar>= diff --git a/repo/tethys/org/nilus/3.0/m2e-lastUpdated.properties b/repo/tethys/org/nilus/3.0/m2e-lastUpdated.properties new file mode 100644 index 00000000..8382f138 --- /dev/null +++ b/repo/tethys/org/nilus/3.0/m2e-lastUpdated.properties @@ -0,0 +1,11 @@ +#Thu Dec 21 16:45:12 GMT 2023 +bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|javadoc=1703177112968 +talan|https\://nexus.talanlabs.com/content/repositories/releases/|javadoc=1703177112968 +repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo|javadoc=1703177112968 +central|https\://repo1.maven.org/maven2|sources=1703157324238 +unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|javadoc=1703177112968 +repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo|sources=1703157324238 +talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1703157324238 +bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1703157324238 +unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1703157324238 +central|https\://repo1.maven.org/maven2|javadoc=1703177112968 diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0-javadoc.jar.lastUpdated b/repo/tethys/org/nilus/3.0/nilus-3.0-javadoc.jar.lastUpdated new file mode 100644 index 00000000..34e39dc5 --- /dev/null +++ b/repo/tethys/org/nilus/3.0/nilus-3.0-javadoc.jar.lastUpdated @@ -0,0 +1,12 @@ +#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 16:45:12 GMT 2023 +@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1703177112601 +https\://repo1.maven.org/maven2/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1703177110940 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error= +https\://nexus.bedatadriven.com/content/groups/public/.error= +https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1703177112519 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1703177112101 +https\://repo1.maven.org/maven2/.lastUpdated=1703177112965 +https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:nilus\:jar\:javadoc\:3.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0-sources.jar.lastUpdated b/repo/tethys/org/nilus/3.0/nilus-3.0-sources.jar.lastUpdated new file mode 100644 index 00000000..8ceb547f --- /dev/null +++ b/repo/tethys/org/nilus/3.0/nilus-3.0-sources.jar.lastUpdated @@ -0,0 +1,12 @@ +#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice. +#Thu Dec 21 11:15:24 GMT 2023 +@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1703157323819 +https\://repo1.maven.org/maven2/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error= +file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1703157322932 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error= +https\://nexus.bedatadriven.com/content/groups/public/.error= +https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1703157323770 +https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1703157323508 +https\://repo1.maven.org/maven2/.lastUpdated=1703157324237 +https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:nilus\:jar\:sources\:3.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0.jar b/repo/tethys/org/nilus/3.0/nilus-3.0.jar new file mode 100644 index 00000000..195d268e Binary files /dev/null and b/repo/tethys/org/nilus/3.0/nilus-3.0.jar differ diff --git a/repo/tethys/org/nilus/3.0/nilus-3.0.pom b/repo/tethys/org/nilus/3.0/nilus-3.0.pom new file mode 100644 index 00000000..ba47dee9 --- /dev/null +++ b/repo/tethys/org/nilus/3.0/nilus-3.0.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + tethys.org + nilus + 3.0 + POM was created from install:install-file + diff --git a/repo/tethys/org/nilus/maven-metadata-local.xml b/repo/tethys/org/nilus/maven-metadata-local.xml new file mode 100644 index 00000000..d053c39d --- /dev/null +++ b/repo/tethys/org/nilus/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + tethys.org + nilus + + 3.0 + + 3.0 + + 20231221111413 + + diff --git a/src/AIS/AISParameters.java b/src/AIS/AISParameters.java index 982b5763..2f902b44 100644 --- a/src/AIS/AISParameters.java +++ b/src/AIS/AISParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class AISParameters implements Serializable, Cloneable, ManagedParameters { @@ -51,7 +52,7 @@ public class AISParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("nmeaSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/AIS/AISPositionReport.java b/src/AIS/AISPositionReport.java index fda5b10f..ca23ad50 100644 --- a/src/AIS/AISPositionReport.java +++ b/src/AIS/AISPositionReport.java @@ -5,6 +5,7 @@ import java.io.Serializable; import NMEA.NMEABitArray; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.LatLong; /** @@ -160,7 +161,7 @@ sensor. @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/AIS/AISStaticData.java b/src/AIS/AISStaticData.java index 7ca318c5..cbf891dc 100644 --- a/src/AIS/AISStaticData.java +++ b/src/AIS/AISStaticData.java @@ -6,6 +6,7 @@ import java.util.Calendar; import NMEA.NMEABitArray; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; public class AISStaticData extends AISReport implements Serializable, ManagedParameters{ @@ -393,7 +394,7 @@ public class AISStaticData extends AISReport implements Serializable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/Acquisition/AcquisitionControl.java b/src/Acquisition/AcquisitionControl.java index 6ef615fb..b9410172 100644 --- a/src/Acquisition/AcquisitionControl.java +++ b/src/Acquisition/AcquisitionControl.java @@ -283,6 +283,16 @@ public class AcquisitionControl extends RawInputControlledUnit implements PamSet return daqControllers; } + @Override + public String getDataLocation() { + if (offlineFileServer == null) { + return null; + } + else { + return offlineFileServer.getDataLocation(); + } + } + public AcquisitionProcess getDaqProcess() { return acquisitionProcess; } diff --git a/src/Acquisition/AcquisitionDialog.java b/src/Acquisition/AcquisitionDialog.java index 50e0d977..cb739bb2 100644 --- a/src/Acquisition/AcquisitionDialog.java +++ b/src/Acquisition/AcquisitionDialog.java @@ -151,6 +151,7 @@ public class AcquisitionDialog extends PamDialog { acquisitionParameters = oldParams.clone(); acquisitionControl = daqControl; +// singleInstance = null; if (singleInstance == null || singleInstance.getOwner() != parentFrame) { singleInstance = new AcquisitionDialog(parentFrame); diff --git a/src/Acquisition/AcquisitionParameters.java b/src/Acquisition/AcquisitionParameters.java index fd79799e..a9c02698 100644 --- a/src/Acquisition/AcquisitionParameters.java +++ b/src/Acquisition/AcquisitionParameters.java @@ -10,6 +10,7 @@ import Array.Preamplifier; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamConstants; @@ -320,7 +321,7 @@ public class AcquisitionParameters implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("channelList"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Acquisition/DaqStatusModuleHeader.java b/src/Acquisition/DaqStatusModuleHeader.java index 5af44a54..5a548a6a 100644 --- a/src/Acquisition/DaqStatusModuleHeader.java +++ b/src/Acquisition/DaqStatusModuleHeader.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; @@ -30,7 +31,7 @@ class DaqStatusModuleHeader extends ModuleHeader implements Serializable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("daqName"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Acquisition/FileInputParameters.java b/src/Acquisition/FileInputParameters.java index 6453b2f1..9a3f114d 100644 --- a/src/Acquisition/FileInputParameters.java +++ b/src/Acquisition/FileInputParameters.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Used by FileInputSystem @@ -78,7 +79,7 @@ public class FileInputParameters implements Serializable, Cloneable, ManagedPara return null; } - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/Acquisition/FolderInputSystem.java b/src/Acquisition/FolderInputSystem.java index 93107b31..7b20311e 100644 --- a/src/Acquisition/FolderInputSystem.java +++ b/src/Acquisition/FolderInputSystem.java @@ -700,7 +700,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D if (currentFile > 0 && currentFile >= allFiles.size()) { fileListComplete(); } -// System.out.println("FolderinputSytem: daqHasEnded"); + System.out.println("FolderinputSytem: daqHasEnded"); } private void setFolderProgress() { diff --git a/src/Acquisition/SoundCardParameters.java b/src/Acquisition/SoundCardParameters.java index e962db72..a54b62b4 100644 --- a/src/Acquisition/SoundCardParameters.java +++ b/src/Acquisition/SoundCardParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import simulatedAcquisition.SimProcess; /** @@ -47,7 +48,7 @@ public class SoundCardParameters implements Serializable, Cloneable, ManagedPara return null; } - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/Acquisition/filedate/StandardFileDateSettings.java b/src/Acquisition/filedate/StandardFileDateSettings.java index 074540f1..b699ca9a 100644 --- a/src/Acquisition/filedate/StandardFileDateSettings.java +++ b/src/Acquisition/filedate/StandardFileDateSettings.java @@ -6,6 +6,7 @@ import java.util.TimeZone; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import soundtrap.STXMLFile; public class StandardFileDateSettings implements Serializable, Cloneable, ManagedParameters { @@ -150,7 +151,7 @@ public class StandardFileDateSettings implements Serializable, Cloneable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } } diff --git a/src/Acquisition/gpstiming/PPSParameters.java b/src/Acquisition/gpstiming/PPSParameters.java index 76bdd012..478d7728 100644 --- a/src/Acquisition/gpstiming/PPSParameters.java +++ b/src/Acquisition/gpstiming/PPSParameters.java @@ -6,6 +6,7 @@ import Acquisition.AcquisitionControl; import Acquisition.AcquisitionDialog; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class PPSParameters implements Cloneable, Serializable, ManagedParameters { @@ -36,7 +37,7 @@ public class PPSParameters implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/AirgunDisplay/AirgunParameters.java b/src/AirgunDisplay/AirgunParameters.java index fe779657..5fae8317 100644 --- a/src/AirgunDisplay/AirgunParameters.java +++ b/src/AirgunDisplay/AirgunParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; @@ -95,7 +96,7 @@ public class AirgunParameters implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("dimE"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/ArrayDialog.java b/src/Array/ArrayDialog.java index 3469b1a2..4475d7bb 100644 --- a/src/Array/ArrayDialog.java +++ b/src/Array/ArrayDialog.java @@ -44,6 +44,8 @@ public class ArrayDialog extends PamDialog implements ActionListener { private EnvironmentPanel environmentPanel; private HydrophoneDiagram hydrophoneDiagram; + + private InstrumentIdentityPanel instrumentIdentityPanel; private JButton okButton, cancelButton; @@ -69,11 +71,14 @@ public class ArrayDialog extends PamDialog implements ActionListener { eastPanel.add(channelPanel.getChannelPanel()); environmentPanel = new EnvironmentPanel(this); + instrumentIdentityPanel = new InstrumentIdentityPanel(); + // eastPanel.add(environmentPanel.getEnvironmentPanel()); hydrophoneDiagram = new HydrophoneDiagram(this); JPanel westPanel = new JPanel(new BorderLayout()); westPanel.add(BorderLayout.CENTER, hydrophoneDiagram.getPlotPanel()); westPanel.add(BorderLayout.SOUTH, environmentPanel.getEnvironmentPanel()); + westPanel.add(BorderLayout.NORTH, instrumentIdentityPanel.getComponent()); splitPanel.add(westPanel); @@ -144,6 +149,7 @@ public class ArrayDialog extends PamDialog implements ActionListener { hydrophoneDialogPanel.setParams(selArray); channelPanel.setParams(); hydrophoneDiagram.rePaint(); + instrumentIdentityPanel.setParams(selArray); if (selArray != null) { environmentPanel.setNewSpeed(selArray.getSpeedOfSound()); } @@ -171,6 +177,7 @@ public class ArrayDialog extends PamDialog implements ActionListener { array.setSpeedOfSound(environmentPanel.getNewSpeed()); array.setSpeedOfSoundError(environmentPanel.getNewError()); hydrophoneDialogPanel.getParams(); + instrumentIdentityPanel.getParams(array); if (checkDaqChannels(array) == false) { return false; @@ -250,6 +257,7 @@ public class ArrayDialog extends PamDialog implements ActionListener { environmentPanel.setNewSpeed(currentArray.getSpeedOfSound()); environmentPanel.setNewError(currentArray.getSpeedOfSoundError()); } + instrumentIdentityPanel.setParams(currentArray); } void newChannelSelection() { diff --git a/src/Array/Hydrophone.java b/src/Array/Hydrophone.java index ffbda1ac..c2f82bd5 100644 --- a/src/Array/Hydrophone.java +++ b/src/Array/Hydrophone.java @@ -28,6 +28,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import pamMaths.PamVector; import PamView.PamSymbol; @@ -158,7 +159,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { return sensitivity; } - protected void setSensitivity(double sensitivity) { + public void setSensitivity(double sensitivity) { this.sensitivity = sensitivity; } @@ -333,7 +334,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { /** * @return Returns the coordinate. */ - protected double[] getCoordinates() { + public double[] getCoordinates() { return Arrays.copyOf(coordinate,3); } @@ -364,7 +365,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { /** * @param preampGain The preampGain to set. */ - protected void setPreampGain(double preampGain) { + public void setPreampGain(double preampGain) { this.preampGain = preampGain; } @@ -478,7 +479,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet pps = PamParameterSet.autoGenerate(this); + PamParameterSet pps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); Field f; try { f = this.getClass().getDeclaredField("coordinate"); diff --git a/src/Array/HydrophoneLocator.java b/src/Array/HydrophoneLocator.java index d51fafbb..5d6c9d7c 100644 --- a/src/Array/HydrophoneLocator.java +++ b/src/Array/HydrophoneLocator.java @@ -7,6 +7,7 @@ import Array.streamerOrigin.StreamerDataIterator; import GPS.GpsData; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; import PamguardMVC.PamDataBlock; @@ -225,7 +226,7 @@ abstract public class HydrophoneLocator implements Serializable, Cloneable, Mana */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("pamArray"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/InstrumentIdentityPanel.java b/src/Array/InstrumentIdentityPanel.java new file mode 100644 index 00000000..b8f21137 --- /dev/null +++ b/src/Array/InstrumentIdentityPanel.java @@ -0,0 +1,72 @@ +package Array; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; + +import PamView.dialog.PamGridBagContraints; +import PamView.panel.WestAlignedPanel; + +/** + * Instrument identity panel, contrians additional fields required by Tethys. + * @author dg50 + * + */ +public class InstrumentIdentityPanel { + + private JPanel mainPanel; + + private JTextField instrumentId; + + private JTextField instrumentType; + + public InstrumentIdentityPanel() { + mainPanel = new WestAlignedPanel(); + mainPanel.setBorder(new TitledBorder("Instrument information")); + mainPanel.setLayout(new GridBagLayout()); + GridBagConstraints c = new PamGridBagContraints(); + mainPanel.add(new JLabel("Instrument Type ", JLabel.RIGHT), c); + c.gridx++; + mainPanel.add(instrumentType = new JTextField(20), c); + c.gridx = 0; + c.gridy++; + mainPanel.add(new JLabel("Instrument Id ", JLabel.RIGHT), c); + c.gridx++; + mainPanel.add(instrumentId = new JTextField(20), c); + + instrumentType.setToolTipText("Instrument type, e.g. Towed array, HARP, EAR, Popup, DMON, Rock Hopper, etc."); + instrumentId.setToolTipText("Instrument identifier, e.g. serial number"); + + } + + public JComponent getComponent() { + return mainPanel; + } + + public void setParams(PamArray currentArray) { + if (currentArray == null) { + currentArray = ArrayManager.getArrayManager().getCurrentArray(); + } + if (currentArray == null) { + return; + } + instrumentType.setText(currentArray.getInstrumentType()); + instrumentId.setText(currentArray.getInstrumentId()); + } + + public void getParams(PamArray currentArray) { + if (currentArray == null) { + currentArray = ArrayManager.getArrayManager().getCurrentArray(); + } + if (currentArray == null) { + return; + } + currentArray.setInstrumentType(instrumentType.getText()); + currentArray.setInstrumentId(instrumentId.getText()); + } +} diff --git a/src/Array/MovingHydrophoneLocator.java b/src/Array/MovingHydrophoneLocator.java index 2c17059f..faf88005 100644 --- a/src/Array/MovingHydrophoneLocator.java +++ b/src/Array/MovingHydrophoneLocator.java @@ -16,5 +16,10 @@ abstract public class MovingHydrophoneLocator extends SimpleHydrophoneLocator { super(pamArray, streamer); } + @Override + public boolean isChangeable() { + return true; + } + } diff --git a/src/Array/PamArray.java b/src/Array/PamArray.java index a351e47d..a116108d 100644 --- a/src/Array/PamArray.java +++ b/src/Array/PamArray.java @@ -35,6 +35,7 @@ import Array.streamerOrigin.StreamerDataIterator; import GPS.GpsData; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; import PamUtils.PamArrayUtils; @@ -90,6 +91,33 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters { private String arrayName; private String arrayFile; + + /** + * Type, used for Tethys and other meta data control + */ + private String instrumentType; + + /** + * Array Id. Can be anything. Compulsory for Tethys. + */ + private String instrumentId; + + public String getInstrumentType() { + return instrumentType; + } + + public void setInstrumentType(String instrumentType) { + this.instrumentType = instrumentType; + } + + public String getInstrumentId() { + return instrumentId; + } + + public void setInstrumentId(String instrumentId) { + this.instrumentId = instrumentId; + } + // private int originInterpolation = ORIGIN_USE_LATEST; private int originInterpolation = ORIGIN_USE_PRECEEDING; @@ -1574,7 +1602,7 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("streamers"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/Preamplifier.java b/src/Array/Preamplifier.java index 37e77cfe..20a7dc18 100644 --- a/src/Array/Preamplifier.java +++ b/src/Array/Preamplifier.java @@ -25,6 +25,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @@ -79,7 +80,7 @@ public class Preamplifier implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Array/Streamer.java b/src/Array/Streamer.java index 90f69f10..7910da0f 100644 --- a/src/Array/Streamer.java +++ b/src/Array/Streamer.java @@ -17,6 +17,7 @@ import PamController.PamController; import PamController.masterReference.MasterReferencePoint; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.LatLong; import PamUtils.PamCalendar; @@ -767,7 +768,7 @@ public class Streamer implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("coordinate"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Array/StreamerDialog.java b/src/Array/StreamerDialog.java index e629b142..73a81469 100644 --- a/src/Array/StreamerDialog.java +++ b/src/Array/StreamerDialog.java @@ -259,6 +259,7 @@ public class StreamerDialog extends PamDialog { // } singleInstance.currentArray = currentArray; singleInstance.defaultStreamer = streamer;//.clone(); +// singleInstance.st singleInstance.setParams(); singleInstance.setVisible(true); return singleInstance.defaultStreamer; @@ -549,6 +550,17 @@ public class StreamerDialog extends PamDialog { pack(); } } + + try { + OriginSettings os = defaultStreamer.getOriginSettings(currentOriginMethod.getClass()); + if (os != null) { + currentOriginMethod.setOriginSettings(os); + } + } + catch (Exception e) { + // will throw if it tries to set the wrong type of settings. + } + enableControls(); } diff --git a/src/Array/streamerOrigin/OriginSettings.java b/src/Array/streamerOrigin/OriginSettings.java index 1beab0f7..9565ea57 100644 --- a/src/Array/streamerOrigin/OriginSettings.java +++ b/src/Array/streamerOrigin/OriginSettings.java @@ -3,6 +3,7 @@ package Array.streamerOrigin; import PamController.SettingsObject; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Class to hold settings for the different origin methods. @@ -47,7 +48,7 @@ public abstract class OriginSettings implements SettingsObject, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/ArrayAccelerometer/ArrayAccelParams.java b/src/ArrayAccelerometer/ArrayAccelParams.java index fdf107d5..7ce91290 100644 --- a/src/ArrayAccelerometer/ArrayAccelParams.java +++ b/src/ArrayAccelerometer/ArrayAccelParams.java @@ -5,6 +5,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import mcc.MccJniInterface; import mcc.mccjna.MCCConstants; @@ -67,7 +68,7 @@ public class ArrayAccelParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Azigram/AzigramParameters.java b/src/Azigram/AzigramParameters.java index 94cf50c7..f0f88c71 100644 --- a/src/Azigram/AzigramParameters.java +++ b/src/Azigram/AzigramParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.GroupedSourceParameters; import PamguardMVC.PamConstants; @@ -44,7 +45,7 @@ public class AzigramParameters implements Serializable, ManagedParameters, Clone @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("name"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Filters/FilterParameters_2.java b/src/Filters/FilterParameters_2.java index 0169f6d1..788db4d8 100644 --- a/src/Filters/FilterParameters_2.java +++ b/src/Filters/FilterParameters_2.java @@ -7,6 +7,7 @@ import org.w3c.dom.Element; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * FilterPArameters for use when the filter is on it's own (within a FilterController) @@ -39,7 +40,7 @@ public class FilterParameters_2 implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Filters/FilterParams.java b/src/Filters/FilterParams.java index 0b8f487c..f8260f44 100644 --- a/src/Filters/FilterParams.java +++ b/src/Filters/FilterParams.java @@ -30,6 +30,7 @@ import org.w3c.dom.Element; import PamController.PamControlledUnit; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.FrequencyFormat; /** @@ -358,7 +359,7 @@ public class FilterParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/GPS/GPSParameters.java b/src/GPS/GPSParameters.java index 719a59ca..d907ba75 100644 --- a/src/GPS/GPSParameters.java +++ b/src/GPS/GPSParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class GPSParameters implements Serializable, Cloneable, ManagedParameters { @@ -175,7 +176,7 @@ public class GPSParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("nmeaSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/GPS/GpsDataUnit.java b/src/GPS/GpsDataUnit.java index 914920b5..8d6433ca 100644 --- a/src/GPS/GpsDataUnit.java +++ b/src/GPS/GpsDataUnit.java @@ -1,5 +1,6 @@ package GPS; +import PamUtils.PamCalendar; import PamguardMVC.PamDataUnit; public class GpsDataUnit extends PamDataUnit { @@ -52,12 +53,18 @@ public class GpsDataUnit extends PamDataUnit { */ @Override public String getSummaryString() { - // TODO Auto-generated method stub - String str = super.getSummaryString(); +// String str = super.getSummaryString(); + String str = String.format("%s
UID:%d, Database: %d
%s
", + "GPS Data", getUID(), getDatabaseIndex(), PamCalendar.formatDBDateTime(getTimeMilliseconds(), true)); if (gpsData != null) { str += gpsData.summaryString(); } return str; } + @Override + public double[] getFrequency() { + return null; + } + } diff --git a/src/GPS/GpsLogger.java b/src/GPS/GpsLogger.java index b02c32e6..f0f990c8 100644 --- a/src/GPS/GpsLogger.java +++ b/src/GPS/GpsLogger.java @@ -295,7 +295,8 @@ public class GpsLogger extends SQLLogging { * time from the UTC column which is NOT the GpsData time which was the real GPS time. */ int gpsIntTimeVal = gpsTime.getIntegerValue(); - Object ts = getTableDefinition().getTimeStampItem().getValue(); + PamTableDefinition pamTableDef = (PamTableDefinition) getTableDefinition(); + Object ts = pamTableDef.getTimeStampItem().getValue(); long gpsDate = sqlTypes.millisFromTimeStamp(ts); if (gpsDate%1000 == 0) { // some databases may have stored the milliseconds, in which diff --git a/src/IshmaelDetector/IshDetParams.java b/src/IshmaelDetector/IshDetParams.java index d79b8d60..f8d4c2a9 100644 --- a/src/IshmaelDetector/IshDetParams.java +++ b/src/IshmaelDetector/IshDetParams.java @@ -17,6 +17,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.GroupedSourceParameters; public class IshDetParams implements Serializable, Cloneable, ManagedParameters { @@ -96,7 +97,7 @@ public class IshDetParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("inputDataSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/IshmaelDetector/IshDisplayParams.java b/src/IshmaelDetector/IshDisplayParams.java index 609f9c2b..a0dea6aa 100644 --- a/src/IshmaelDetector/IshDisplayParams.java +++ b/src/IshmaelDetector/IshDisplayParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Ishamel display parameters for the Spectrogram plug in. @@ -42,7 +43,7 @@ public class IshDisplayParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/IshmaelDetector/IshLogger.java b/src/IshmaelDetector/IshLogger.java index c9abdcfe..6bd47109 100644 --- a/src/IshmaelDetector/IshLogger.java +++ b/src/IshmaelDetector/IshLogger.java @@ -8,14 +8,13 @@ import java.sql.Types; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; - +import generalDatabase.EmptyTableDefinition; //import pamDatabase.SQLLogging; //import PamguardMVC.RecyclingDataBlock; import generalDatabase.PamDetectionLogging; public class IshLogger extends PamDetectionLogging { IshDetControl ishDetControl; - PamTableDefinition tableDefinition; PamTableItem systemDate, durationSecs, secSinceStart, peakHeight; // Peak is more important than start time for matched filter & spectrogram correlation PamTableItem peakSample, peakDelaySecs; @@ -25,7 +24,7 @@ public class IshLogger extends PamDetectionLogging { super(pamDataBlock, UPDATE_POLICY_WRITENEW); this.ishDetControl = ishDetControl; - tableDefinition = getTableDefinition(); + EmptyTableDefinition tableDefinition = getTableDefinition(); // PamTableItem tableItem; // setUpdatePolicy(UPDATE_POLICY_WRITENEW); diff --git a/src/IshmaelLocator/IshLocSqlLogging.java b/src/IshmaelLocator/IshLocSqlLogging.java index 0b95afe3..c43539d0 100644 --- a/src/IshmaelLocator/IshLocSqlLogging.java +++ b/src/IshmaelLocator/IshLocSqlLogging.java @@ -14,14 +14,13 @@ import IshmaelDetector.IshDetection; import PamUtils.LatLong; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; - +import generalDatabase.EmptyTableDefinition; //import pamDatabase.SQLLogging; //import PamguardMVC.RecyclingDataBlock; import generalDatabase.PamDetectionLogging; public class IshLocSqlLogging extends PamDetectionLogging { IshLocControl ishLocControl; - PamTableDefinition tableDefinition; PamTableItem systemDate, durationSecs, secSinceStart, peakHeight; private PamTableItem latitude, longitude, refLatitude, refLongitude, x, y, z; @@ -30,7 +29,7 @@ public class IshLocSqlLogging extends PamDetectionLogging { super(pamDataBlock, UPDATE_POLICY_WRITENEW); this.ishLocControl = ishDetControl; - tableDefinition = getTableDefinition(); + EmptyTableDefinition tableDefinition = getTableDefinition(); tableDefinition.addTableItem(latitude = new PamTableItem("Latitude", Types.DOUBLE)); tableDefinition.addTableItem(longitude = new PamTableItem("Longitude", Types.DOUBLE)); tableDefinition.addTableItem(refLatitude = new PamTableItem("ReferenceLatitude", Types.DOUBLE)); diff --git a/src/KernelSmoothing/KernelSmoothingParameters.java b/src/KernelSmoothing/KernelSmoothingParameters.java index 8b5f010c..6ddd593b 100644 --- a/src/KernelSmoothing/KernelSmoothingParameters.java +++ b/src/KernelSmoothing/KernelSmoothingParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class KernelSmoothingParameters implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class KernelSmoothingParameters implements Serializable, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/DelayMeasurementParams.java b/src/Localiser/DelayMeasurementParams.java index dc92235d..4a232970 100644 --- a/src/Localiser/DelayMeasurementParams.java +++ b/src/Localiser/DelayMeasurementParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import fftFilter.FFTFilterParams; /** @@ -157,7 +158,7 @@ public class DelayMeasurementParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java b/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java index 1a170d0b..de0c0280 100644 --- a/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java +++ b/src/Localiser/algorithms/genericLocaliser/MCMC/MCMCParams2.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MCMCParams2 implements Serializable, Cloneable, ManagedParameters { @@ -126,7 +127,7 @@ public class MCMCParams2 implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java b/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java index bc3983b6..214f337c 100644 --- a/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java +++ b/src/Localiser/algorithms/genericLocaliser/MCMC/old/MCMCParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MCMCParams implements Serializable, Cloneable, ManagedParameters { @@ -64,7 +65,7 @@ public class MCMCParams implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java b/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java index d7cdc11f..d012bfdb 100644 --- a/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java +++ b/src/Localiser/algorithms/timeDelayLocalisers/hyperbolic/HyperbolicParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** @@ -69,7 +70,7 @@ public class HyperbolicParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Localiser/controls/RawOrFFTParams.java b/src/Localiser/controls/RawOrFFTParams.java index 0545ea90..9df83a54 100644 --- a/src/Localiser/controls/RawOrFFTParams.java +++ b/src/Localiser/controls/RawOrFFTParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import Spectrogram.WindowFunction; /** @@ -104,7 +105,7 @@ public class RawOrFFTParams implements Serializable, Cloneable, RawOrFFTParamsIn @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/Map/GebcoMapFile.java b/src/Map/GebcoMapFile.java index befe7d3a..acb2112c 100644 --- a/src/Map/GebcoMapFile.java +++ b/src/Map/GebcoMapFile.java @@ -85,7 +85,15 @@ public class GebcoMapFile implements MapFileManager { * @see Map.MapFile#readFileData(java.io.File) */ public boolean readFileData(File file) { - return readMapFile(file, true); + try { + return readMapFile(file, true); + } + catch (Exception e) { + // trap error someone reported at end November 22. Suspect it was their corrupt map file causing problems. + String err = String.format("Map file %s is missing or corrupt and cannot be loaded", file.getName()); + WarnOnce.showWarning("Map File Error", err, WarnOnce.OK_OPTION); + return false; + } } private boolean readMapFile(File gebcoFile, boolean readContours) { diff --git a/src/Map/MapDetectionsParameters.java b/src/Map/MapDetectionsParameters.java index a52aff72..bfc72e9b 100644 --- a/src/Map/MapDetectionsParameters.java +++ b/src/Map/MapDetectionsParameters.java @@ -7,6 +7,7 @@ import java.util.ListIterator; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * PArameters for MapDetectionsManager which @@ -65,7 +66,7 @@ public class MapDetectionsParameters implements Serializable, Cloneable, Managed @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/Map/MapParameters.java b/src/Map/MapParameters.java index b0eee649..11baeb07 100644 --- a/src/Map/MapParameters.java +++ b/src/Map/MapParameters.java @@ -27,6 +27,7 @@ import java.lang.reflect.Field; import Array.Hydrophone; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class MapParameters implements Serializable, Cloneable, ManagedParameters { @@ -301,7 +302,7 @@ public class MapParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/Map/MapRectProjector.java b/src/Map/MapRectProjector.java index dd402886..0b7e45a3 100644 --- a/src/Map/MapRectProjector.java +++ b/src/Map/MapRectProjector.java @@ -20,9 +20,15 @@ */ package Map; +import java.awt.Point; import java.awt.event.MouseMotionAdapter; import java.awt.geom.AffineTransform; +import java.util.ListIterator; +import GPS.GPSControl; +import GPS.GPSDataBlock; +import GPS.GpsDataUnit; +import PamController.PamController; import PamUtils.Coordinate3d; import PamUtils.LatLong; import PamUtils.PamCoordinate; @@ -385,6 +391,45 @@ public class MapRectProjector extends MapProjector { return xTrans; } + @Override + public String getHoverText(Point mousePoint, int ploNumberMatch) { + String text = super.getHoverText(mousePoint, ploNumberMatch); + if (text == null) { + return findGpsTrackText(mousePoint, ploNumberMatch); + } + else { + return text; + } + } + + private String findGpsTrackText(Point mousePoint, int ploNumberMatch) { + GPSControl gpsControl = GPSControl.getGpsControl(); + if (gpsControl == null) { + return null; + } + LatLong currentPos = getDataPosition(new Coordinate3d(mousePoint.x, mousePoint.y)); + GPSDataBlock gpsDataBlock = gpsControl.getGpsDataBlock(); + double dist = Double.MAX_VALUE; + GpsDataUnit closest = null; + ListIterator it = gpsDataBlock.getListIterator(0); + while (it.hasNext()) { + GpsDataUnit gpsUnit = it.next(); + double r = gpsUnit.getGpsData().distanceToMetres(currentPos); + if (r < dist) { + dist = r; + closest = gpsUnit; + } + } + if (closest == null) { + return null; + } + double rPix = dist*this.pixelsPerMetre; + if (rPix > 20) { + return null; + } + return closest.getSummaryString(); + } + } diff --git a/src/Map/gridbaselayer/GridbaseParameters.java b/src/Map/gridbaselayer/GridbaseParameters.java index 2af62e75..fe608b8d 100644 --- a/src/Map/gridbaselayer/GridbaseParameters.java +++ b/src/Map/gridbaselayer/GridbaseParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class GridbaseParameters implements Cloneable, Serializable, ManagedParameters { @@ -25,7 +26,7 @@ public class GridbaseParameters implements Cloneable, Serializable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/NMEA/NMEAParameters.java b/src/NMEA/NMEAParameters.java index 42393be3..9da8c22c 100644 --- a/src/NMEA/NMEAParameters.java +++ b/src/NMEA/NMEAParameters.java @@ -24,6 +24,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import serialComms.jserialcomm.PJSerialComm; public class NMEAParameters implements Serializable, Cloneable, ManagedParameters { @@ -149,7 +150,7 @@ public class NMEAParameters implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamController/OfflineDataStore.java b/src/PamController/OfflineDataStore.java index 52e64150..20a34041 100644 --- a/src/PamController/OfflineDataStore.java +++ b/src/PamController/OfflineDataStore.java @@ -33,6 +33,13 @@ public interface OfflineDataStore { */ public String getDataSourceName(); + /** + * Get the data location. This may be a specific file, or might be a folder + * if data are in many files, a URI, etc. + * @return store locations + */ + public String getDataLocation(); + /** * Load data for a given datablock between two time limits. * @param dataBlock datablock owner of the data diff --git a/src/PamController/PamControlledUnit.java b/src/PamController/PamControlledUnit.java index f1962ca8..9b9eae63 100644 --- a/src/PamController/PamControlledUnit.java +++ b/src/PamController/PamControlledUnit.java @@ -23,6 +23,7 @@ package PamController; import java.awt.Component; import java.awt.Frame; import java.util.ArrayList; +import java.util.List; import javax.swing.JFrame; import javax.swing.JMenu; @@ -39,7 +40,9 @@ import org.w3c.dom.Element; import PamController.status.ModuleStatus; import PamController.status.ModuleStatusManager; import PamController.status.ProcessCheck; +import PamModel.PamModel; import PamModel.PamModuleInfo; +import PamModel.PamPluginInterface; import PamView.ClipboardCopier; import PamView.PamGui; import PamView.PamSidePanel; @@ -880,6 +883,23 @@ public abstract class PamControlledUnit implements SettingsNameProvider { public int getInstanceIndex() { return instanceIndex; } + + /** + * Get detail if this is a plugin. + * @return plugin detail, or null if it's not a plugin. + */ + public PamPluginInterface getPlugin() { + List pluginList = ((PamModel) PamController.getInstance().getModelInterface()).getPluginList(); + if (pluginList == null) { + return null; + } + for (PamPluginInterface plugin : pluginList) { + if (plugin.getClassName().equals(this.getClass().getName())) { + return plugin; + } + } + return null; + } /** * The PamConfiguration holds the master list of modules which form part of a diff --git a/src/PamController/PamControlledUnitSettings.java b/src/PamController/PamControlledUnitSettings.java index ccdc18bf..6522884f 100644 --- a/src/PamController/PamControlledUnitSettings.java +++ b/src/PamController/PamControlledUnitSettings.java @@ -36,6 +36,7 @@ import org.apache.commons.io.input.ClassLoaderObjectInputStream; import PamModel.PamModel; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.dialog.warn.WarnOnce; @@ -398,7 +399,7 @@ public class PamControlledUnitSettings implements Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamController/PamController.java b/src/PamController/PamController.java index 93dc4205..244be71a 100644 --- a/src/PamController/PamController.java +++ b/src/PamController/PamController.java @@ -57,6 +57,7 @@ import fftManager.FFTDataUnit; import generalDatabase.DBControlUnit; import javafx.application.Platform; import javafx.stage.Stage; +import metadata.MetaDataContol; import Array.ArrayManager; import PamController.command.MulticastController; import PamController.command.NetworkController; @@ -452,6 +453,7 @@ public class PamController implements PamControllerInterface, PamSettings { System.out.println(""); System.out.println("Note - ignore the following SLF4J warn/error messages, they are not applicable to this application"); ArrayManager.getArrayManager(); // create the array manager so that it get's it's settings + MetaDataContol.getMetaDataControl(); /** * Check for archived files and unpack automatically. @@ -1161,6 +1163,8 @@ public class PamController implements PamControllerInterface, PamSettings { } if (saveSettings) { + startTime = PamCalendar.getSessionStartTime(); +// System.out.printf("Saving settings for start time %s\n", PamCalendar.formatDBDateTime(startTime)); saveSettings(PamCalendar.getSessionStartTime()); } @@ -1319,6 +1323,9 @@ public class PamController implements PamControllerInterface, PamSettings { } guiFrameManager.pamEnded(); + long stopTime = PamCalendar.getTimeInMillis(); + saveEndSettings(stopTime); + // no good having this here since it get's called at the end of every file. // if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) { //// can exit here, since we've auto started, can auto exit. @@ -1437,6 +1444,26 @@ public class PamController implements PamControllerInterface, PamSettings { pamConfiguration.saveSettings(timeNow); } + /** + * Gets called in pamStart and may / will attempt to store all + * PAMGUARD settings via the database and binary storage modules. + */ + private void saveEndSettings(long timeNow) { +// System.out.printf("Updating settings with end time %s\n", PamCalendar.formatDBDateTime(timeNow)); + ArrayList pamControlledUnits = pamConfiguration.getPamControlledUnits(); + PamControlledUnit pcu; + PamSettingsSource settingsSource; + for (int iU = 0; iU < pamControlledUnits.size(); iU++) { + pcu = pamControlledUnits.get(iU); + if (PamSettingsSource.class.isAssignableFrom(pcu.getClass())) { + settingsSource = (PamSettingsSource) pcu; + settingsSource.saveEndSettings(timeNow); + } + } + } + + + /** * Export configuration into an XML file * @param parentFrame @@ -2407,7 +2434,7 @@ public class PamController implements PamControllerInterface, PamSettings { if (dbc == null) { return null; } - return dbc.getDatabaseName(); + return dbc.getLongDatabaseName(); } return null; } diff --git a/src/PamController/PamSensor.java b/src/PamController/PamSensor.java new file mode 100644 index 00000000..03e51efe --- /dev/null +++ b/src/PamController/PamSensor.java @@ -0,0 +1,20 @@ +package PamController; + +/** + * Interface to define modules which can be considered as sensors of some sort. + * e.g. depth and orientation modules and the SoundTrap clickdetecotr + * @author dg50 + * + */ +public interface PamSensor { + + public String getUnitName(); + + public String getUnitType(); + + public String getSensorDescription(); + + public String getSensorId(); + + +} diff --git a/src/PamController/PamSettingManager.java b/src/PamController/PamSettingManager.java index ddd15740..46bc0679 100644 --- a/src/PamController/PamSettingManager.java +++ b/src/PamController/PamSettingManager.java @@ -476,7 +476,7 @@ public class PamSettingManager { */ public PamSettings findSettingsOwner(String unitType, String unitName, String unitClassName) { for (PamSettings owner:owners) { - if (owner.getClass() != null) { + if (owner.getClass() != null && unitClassName != null) { if (owner.getClass().getName().equals(unitClassName) == false) { continue; } diff --git a/src/PamController/PamSettingsSource.java b/src/PamController/PamSettingsSource.java index ed67807a..ba4079cc 100644 --- a/src/PamController/PamSettingsSource.java +++ b/src/PamController/PamSettingsSource.java @@ -20,6 +20,14 @@ public interface PamSettingsSource { */ public boolean saveStartSettings(long timeNow); + /** + * Save settings when processing ends. + * This may just be an update of the settings saves with saveStartSettings, e.g. an end time. + * @param timeNow + * @return true if saved correctly. + */ + public boolean saveEndSettings(long timeNow); + /** * Get the number of different settings * within the settings source. diff --git a/src/PamController/PamguardVersionInfo.java b/src/PamController/PamguardVersionInfo.java index 263632b0..976624fe 100644 --- a/src/PamController/PamguardVersionInfo.java +++ b/src/PamController/PamguardVersionInfo.java @@ -31,7 +31,7 @@ public class PamguardVersionInfo { * Version number, major version.minorversion.sub-release. * Note: can't go higher than sub-release 'f' */ - static public final String version = "2.02.09e"; + static public final String version = "2.02.09f"; /** * Release date diff --git a/src/PamController/UsedModuleInfo.java b/src/PamController/UsedModuleInfo.java index 88756866..1170027a 100644 --- a/src/PamController/UsedModuleInfo.java +++ b/src/PamController/UsedModuleInfo.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Very simple class used in an ArrayList of used modules that @@ -54,8 +55,16 @@ public class UsedModuleInfo implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } + /** + * Get the unit name of the module being imported. + * @return + */ + public String getUnitName() { + return unitName; + } + } diff --git a/src/PamController/settings/SettingsImport.java b/src/PamController/settings/SettingsImport.java index 0c52fb31..16e23f35 100644 --- a/src/PamController/settings/SettingsImport.java +++ b/src/PamController/settings/SettingsImport.java @@ -116,14 +116,16 @@ public class SettingsImport { */ private PamControlledUnit importReplace(SettingsImportGroup importGroup, String replaceModule) { PamControlledUnitSettings mainSet = importGroup.getMainSettings(); - PamControlledUnit unit = PamController.getInstance().findControlledUnit(mainSet.getUnitType(), replaceModule); + UsedModuleInfo importInfo = importGroup.getUsedModuleInfo(); + PamControlledUnit unit = PamController.getInstance().findControlledUnit(importInfo.getUnitType(), replaceModule); if (unit == null) { - System.out.println("Unable to find " + mainSet.getUnitType() + " " + mainSet.getUnitName() + " for settings replacement"); + System.out.println("Unable to find " + importInfo.getUnitType() + " " + importInfo.getUnitName() + " for settings replacement"); return null; } // check we can cast it to PamSettings - if (PamSettings.class.isAssignableFrom(unit.getClass())) { + if (PamSettings.class.isAssignableFrom(unit.getClass()) && mainSet != null) { try { + mainSet.setUnitName(replaceModule); ((PamSettings) unit).restoreSettings(mainSet); } catch (Exception e) { @@ -132,7 +134,7 @@ public class SettingsImport { System.err.println(e.getMessage()); } } - loadSubUnitSettings(importGroup, mainSet.getUnitName()); + loadSubUnitSettings(importGroup, replaceModule); return unit; } @@ -149,7 +151,15 @@ public class SettingsImport { } PamSettingManager setManager = PamSettingManager.getInstance(); for (PamControlledUnitSettings pamSettings:subSets) { - PamSettings owner = setManager.findSettingsOwner(pamSettings.getUnitType(), unitName, pamSettings.getOwnerClassName()); + /* + * class name in pamSettings is no longer correct, so cannot use pamSettings.getOwnerClassName(). + * but the classnames of all the sub modules are unknown (and will be different form the unit class name + * which can be got from importGroup.getPamModuleInfo().getClassName + * so will have to do this only on the unit type and name and hope for no conflicts (catch exception). + */ +// PamModuleInfo moduleInfo = importGroup.getPamModuleInfo(); +// String className = moduleInfo.getClassName(); + PamSettings owner = setManager.findSettingsOwner(pamSettings.getUnitType(), unitName, null); if (owner == null) { System.out.println(String.format("Cannot find settings owner for %s %s in current model", pamSettings.getUnitType(), unitName)); continue; @@ -168,7 +178,8 @@ public class SettingsImport { private PamControlledUnit importNew(SettingsImportGroup importGroup) { PamControlledUnitSettings mainSet = importGroup.getMainSettings(); - String moduleName = mainSet.getUnitName(); + UsedModuleInfo importInfo = importGroup.getUsedModuleInfo(); + String moduleName = importInfo.unitName; // check we've got a name that doesnt' exist and replace it if if does. // int startChar = 0; @@ -199,11 +210,11 @@ public class SettingsImport { PamControlledUnit unit = PamController.getInstance().addModule(PamController.getMainFrame(), moduleInfo); if (unit == null) { - System.out.println("Unable to find " + mainSet.getUnitType() + " " + mainSet.getUnitName() + " for settings replacement"); + System.out.println("Unable to find " + importInfo.getUnitType() + " " + importInfo.getUnitName() + " for settings replacement"); return null; } // check we can cast it to PamSettings - if (PamSettings.class.isAssignableFrom(unit.getClass())) { + if (PamSettings.class.isAssignableFrom(unit.getClass()) && mainSet != null) { try { mainSet.setUnitName(unit.getUnitName()); // need to force the unit name for some modules. ((PamSettings) unit).restoreSettings(mainSet); diff --git a/src/PamController/settings/SettingsImportDialog.java b/src/PamController/settings/SettingsImportDialog.java index 6f6621e6..4241a0cf 100644 --- a/src/PamController/settings/SettingsImportDialog.java +++ b/src/PamController/settings/SettingsImportDialog.java @@ -195,12 +195,14 @@ public class SettingsImportDialog extends PamDialog { @Override public Object getValueAt(int rowIndex, int columnIndex) { SettingsImportGroup set = groupedSettings.get(rowIndex); - PamControlledUnitSettings mainSet = set.getMainSettings(); +// PamControlledUnitSettings mainSet = set.getMainSettings(); switch (columnIndex) { case 0: - return mainSet.getUnitType(); + return set.getUsedModuleInfo().getUnitType(); +// return mainSet.getUnitType(); case 1: - return mainSet.getUnitName(); + return set.getUsedModuleInfo().unitName; +// return mainSet.getUnitName(); case 2: // return choiceBoxes[rowIndex].getSelectedItem().toString(); return set.getImportChoice().toString(); diff --git a/src/PamController/settings/SettingsImportGroup.java b/src/PamController/settings/SettingsImportGroup.java index a74a6885..98bf1e4f 100644 --- a/src/PamController/settings/SettingsImportGroup.java +++ b/src/PamController/settings/SettingsImportGroup.java @@ -82,8 +82,10 @@ public class SettingsImportGroup { try { ownerClass = Class.forName(usedModuleInfo.className); } catch (ClassNotFoundException e) { + + System.out.println("Unknown class in loaded settings: " + usedModuleInfo.className); // TODO Auto-generated catch block - e.printStackTrace(); +// e.printStackTrace(); } ArrayList existingModules = PamController.getInstance().findControlledUnits(ownerClass); diff --git a/src/PamController/settings/output/xml/PamguardXMLWriter.java b/src/PamController/settings/output/xml/PamguardXMLWriter.java index 6b42c4e7..f74edce0 100644 --- a/src/PamController/settings/output/xml/PamguardXMLWriter.java +++ b/src/PamController/settings/output/xml/PamguardXMLWriter.java @@ -29,6 +29,7 @@ import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; import com.sun.javafx.runtime.VersionInfo; @@ -42,12 +43,14 @@ import PamController.PamguardVersionInfo; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; import PamUtils.XMLUtils; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import PamguardMVC.PamProcess; import binaryFileStorage.BinaryStore; +import tethys.TethysControl; /** * Class for writing XML configuration output to a file. @@ -62,6 +65,8 @@ public class PamguardXMLWriter implements PamSettings { private static final Set> WRAPPER_TYPES = getWrapperTypes(); private XMLWriterSettings writerSettings = new XMLWriterSettings(); + private boolean excludeDisplaySettings; +// private String xmlNameSpace; private static PamguardXMLWriter singleInstance; @@ -83,6 +88,19 @@ public class PamguardXMLWriter implements PamSettings { } return singleInstance; } + + /** + * Recursively walk the tree and add a namespace to every + * single element. + * @param doc + * @param nameSpace + * @return + */ + public boolean addNameSpaceToElements(Document doc, Element el, String nameSpace) { +// el.setAttributeNS(nameSpace, nameSpace, nameSpace); + NamedNodeMap attributes = el.getAttributes(); + return true; + } /** * Make a document with the options specified in writerSettings. @@ -371,6 +389,32 @@ public class PamguardXMLWriter implements PamSettings { * @return xml content as a a string. */ public String getAsString(Document doc) { + return getAsString(doc, true); +// try { +// DOMSource domSource = new DOMSource(doc); +// StringWriter writer = new StringWriter(); +// StreamResult result = new StreamResult(writer); +// TransformerFactory tf = TransformerFactory.newInstance(); +// Transformer transformer = tf.newTransformer(); +// transformer.setOutputProperty(OutputKeys.METHOD, "xml"); +// transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); +//// transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); +// transformer.setOutputProperty(OutputKeys.INDENT, "yes"); +// transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); +// transformer.transform(domSource, result); +// return writer.toString(); +// } catch (TransformerException e) { +// e.printStackTrace(); +// return null; +// } + } + /** + * Get the xml document as a String. + * @param doc xml document + * @param indent Indent / format the document. + * @return xml content as a a string. + */ + public String getAsString(Document doc, boolean indent) { try { DOMSource domSource = new DOMSource(doc); StringWriter writer = new StringWriter(); @@ -380,7 +424,7 @@ public class PamguardXMLWriter implements PamSettings { transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1"); // transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); transformer.transform(domSource, result); return writer.toString(); @@ -411,8 +455,7 @@ public class PamguardXMLWriter implements PamSettings { * @param pamSettingsUnit * @return xml element */ - private Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit) { - + public Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit) { int[] settingInds = findSettings(null, pamSettingsUnit.getUnitName()); PamSettings[] settingsObjects = null; if (settingInds != null) { @@ -436,7 +479,7 @@ public class PamguardXMLWriter implements PamSettings { * can be temporary settings objects when writing temporary settings from dialogs. * @return new XML element. */ - private Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit, PamSettings[] toWrite) { + public Element writeUnitSettings(Document doc, Element parent, PamSettings pamSettingsUnit, PamSettings[] toWrite) { Element moduleData = doc.createElement("MODULE"); moduleData.setAttribute("Java.class", pamSettingsUnit.getClass().getName()); moduleData.setAttribute("UnitType", pamSettingsUnit.getUnitType()); @@ -457,6 +500,9 @@ public class PamguardXMLWriter implements PamSettings { Element settingEl = doc.createElement("CONFIGURATION"); moduleData.appendChild(settingEl); for (int i = 0; i < toWrite.length; i++) { + if (wantObject(toWrite[i]) == false) { + continue; + } Element setEl = writeSettings(doc, toWrite[i], new ArrayList()); if (setEl != null) { settingEl.appendChild(setEl); @@ -467,6 +513,32 @@ public class PamguardXMLWriter implements PamSettings { return moduleData; } + /** + * USed by the Tethys writer to avoid writing display settings. + * @param pamSettings + * @return + */ + private boolean wantObject(PamSettings pamSettings) { + if (excludeDisplaySettings == false) { + return true; + } + Object obj = pamSettings.getSettingsReference(); + if (obj == null) { + return false; + } + if (obj instanceof ManagedParameters) { + ManagedParameters managedParams = (ManagedParameters) obj; + PamParameterSet paramSet = managedParams.getParameterSet(); + if (paramSet == null) { + return false; + } + if (paramSet.getParameterSetType() == ParameterSetType.DISPLAY && excludeDisplaySettings) { + return false; + } + } + return true; + } + /** * Write settings for a settings object, using the standard retreived object * from the settings. @@ -478,6 +550,14 @@ public class PamguardXMLWriter implements PamSettings { private Element writeSettings(Document doc, PamSettings pamSettings, ArrayList objectHierarchy) { return writeSettings(doc, pamSettings, pamSettings.getSettingsReference(), objectHierarchy); } + + public Document writeOneObject(Object data) { + Document doc = XMLUtils.createBlankDoc(); + Element el = doc.createElement("Settings"); + Element newel = writeObjectData(doc, el, data, new ArrayList()); + doc.appendChild(newel); + return doc; + } /** * Write settings using an object of choice instead of the standard one from PamSettings. @@ -489,6 +569,7 @@ public class PamguardXMLWriter implements PamSettings { * @return */ private Element writeSettings(Document doc, PamSettings pamSettings, Object data, ArrayList objectHierarchy) { + Element el = doc.createElement("SETTINGS"); el.setAttribute("Type", pamSettings.getUnitType()); el.setAttribute("Name", pamSettings.getUnitName()); @@ -500,10 +581,13 @@ public class PamguardXMLWriter implements PamSettings { return el; } - private Element writeObjectData(Document doc, Element el, Object data, ArrayList objectHierarchy) { + public Element writeObjectData(Document doc, Element el, Object data, ArrayList objectHierarchy) { if (data == null) { return null; } + if (objectHierarchy == null) { + objectHierarchy = new ArrayList<>(); + } if (objectHierarchy.contains(data)) { // just write the reference, but nothing else or we'll end up in an infinite loop of objects. Element e = doc.createElement("Object"); @@ -525,8 +609,10 @@ public class PamguardXMLWriter implements PamSettings { if (parameterSet == null) { return null; } - - objectHierarchy.add(data); + + if (objectHierarchy != null) { + objectHierarchy.add(data); + } for (PamParameterData pamParam:parameterSet.getParameterCollection()) { try { Object paramData = pamParam.getData(); @@ -765,9 +851,10 @@ public class PamguardXMLWriter implements PamSettings { processData.setAttribute("Name", process.getProcessName()); PamDataBlock source = process.getParentDataBlock(); if (source != null) { - Element inputEl = doc.createElement("Input"); - inputEl.setAttribute("Name", source.getLongDataName()); - inputEl.setAttribute("Channels", String.format("0x%X", source.getChannelMap())); + Element inputEl = source.getDataBlockXML(doc); +// Element inputEl = doc.createElement("Input"); +// inputEl.setAttribute("Name", source.getLongDataName()); +// inputEl.setAttribute("Channels", String.format("0x%X", source.getChannelMap())); processData.appendChild(inputEl); } int nOut = process.getNumOutputDataBlocks(); @@ -798,7 +885,16 @@ public class PamguardXMLWriter implements PamSettings { */ private int[] findSettings(String type, String name) { if (settingsSets == null) { - return null; + makeSettingsList(); + if (settingsSets == null) { + return null; + } + } + if (usedSettingsSets == null) { + usedSettingsSets = new boolean[settingsSets.size()]; + } + else if (usedSettingsSets.length < settingsSets.size()) { + usedSettingsSets = Arrays.copyOf(usedSettingsSets, settingsSets.size()); } int[] found = new int[settingsSets.size()]; int nFound = 0; @@ -818,7 +914,7 @@ public class PamguardXMLWriter implements PamSettings { return Arrays.copyOf(found, nFound); } - private ArrayList makeSettingsList() { + public ArrayList makeSettingsList() { PamSettingManager settingsManager = PamSettingManager.getInstance(); settingsSets = settingsManager.getOwners(); if (settingsSets == null) { @@ -850,6 +946,14 @@ public class PamguardXMLWriter implements PamSettings { return doc; } + /** + * Is this element a writable type ? Basically, this means + * that it's a primitive of some sort. Otherwise it's + * probably an object and may even be a list in which case + * it will need treating differently. + * @param clazz + * @return + */ public static boolean isWritableType(Class clazz) { if (clazz.isEnum()) return true; @@ -940,5 +1044,23 @@ public class PamguardXMLWriter implements PamSettings { return true; } + /** + * @return the excludeDisplaySettings + */ + public boolean isExcludeDisplaySettings() { + return excludeDisplaySettings; + } + + /** + * @param excludeDisplaySettings the excludeDisplaySettings to set + */ + public void setExcludeDisplaySettings(boolean excludeDisplaySettings) { + this.excludeDisplaySettings = excludeDisplaySettings; + } + +// public void setStaticNameSpace(String xmlNameSpace) { +// this.xmlNameSpace = xmlNameSpace; +// } + } diff --git a/src/PamController/settings/output/xml/XMLWriterSettings.java b/src/PamController/settings/output/xml/XMLWriterSettings.java index 8e5d0969..dcd60b83 100644 --- a/src/PamController/settings/output/xml/XMLWriterSettings.java +++ b/src/PamController/settings/output/xml/XMLWriterSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class XMLWriterSettings implements Serializable, Cloneable, ManagedParameters { @@ -34,7 +35,7 @@ public class XMLWriterSettings implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamController/soundMedium/GlobalMediumParams.java b/src/PamController/soundMedium/GlobalMediumParams.java index 0a52ac83..8bf10f27 100644 --- a/src/PamController/soundMedium/GlobalMediumParams.java +++ b/src/PamController/soundMedium/GlobalMediumParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.soundMedium.GlobalMedium.SoundMedium; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Stores parameters for the current medium. @@ -41,7 +42,7 @@ public class GlobalMediumParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamModel/PamModel.java b/src/PamModel/PamModel.java index 9cdb9992..ff425f38 100644 --- a/src/PamModel/PamModel.java +++ b/src/PamModel/PamModel.java @@ -44,11 +44,15 @@ import whistlesAndMoans.AbstractWhistleDataUnit; import fftManager.FFTDataUnit; import fftManager.PamFFTControl; import group3dlocaliser.Group3DLocaliserControl; +import metadata.MetaDataContol; import meygenturbine.MeygenTurbine; import printscreen.PrintScreenControl; import rockBlock.RockBlockControl; +import tethys.TethysControl; import turbineops.TurbineOperationControl; import GPS.GpsDataUnit; +import Map.MapController; +import Map.gridbaselayer.GridbaseControl; import NMEA.NMEADataUnit; import PamController.PamControlledUnitSettings; import PamController.PamController; @@ -62,6 +66,7 @@ import PamguardMVC.PamDataBlock; import analogarraysensor.ArraySensorControl; import backupmanager.BackupManager; import beamformer.continuous.BeamFormerControl; +import beamformer.localiser.BeamFormLocaliserControl; import bearinglocaliser.BearingLocaliserControl; import binaryFileStorage.SecondaryBinaryStore; import cepstrum.CepstrumControl; @@ -454,6 +459,19 @@ final public class PamModel implements PamSettings { mi.setToolTipText("Manage automated data backups"); mi.setModulesMenuGroup(utilitiesGroup); mi.setMaxNumber(1); + + +// mi = PamModuleInfo.registerControlledUnit(MetaDataContol.class.getName(), MetaDataContol.unitType); +// mi.setToolTipText("Project Meta Data"); +// mi.setModulesMenuGroup(utilitiesGroup); +// mi.setMaxNumber(1); + + if (isViewer) { + mi = PamModuleInfo.registerControlledUnit(TethysControl.class.getName(), TethysControl.defaultName); + mi.setToolTipText("Interface to Tethys Database"); + mi.setModulesMenuGroup(utilitiesGroup); + mi.setMaxNumber(1); + } /* * ************* End Utilities Group ******************* @@ -1061,7 +1079,7 @@ final public class PamModel implements PamSettings { // clear the current list pluginList.clear(); daqList.clear(); - + /* * If developing a new PAMPlugin in eclipse, the easiest way to do it is to make a new * Eclipse project for your plugin code. Within that project, copy this PamModel class @@ -1076,6 +1094,8 @@ final public class PamModel implements PamSettings { * When you export the code for your plugin to a jar file, remember to NOT inlcude the copy of * PamModel ! */ + +// pluginList.add(new MorlaisWP1aPlugin()); // Load up whatever default classloader was used to create this class. Must use the same classloader // for all plugins, or else we will not be able to create proper dependencies between them or be able @@ -1143,11 +1163,30 @@ final public class PamModel implements PamSettings { // to add that URL to the default classloader path. URL newURL = jarList.get(i).toURI().toURL(); + // original method +// Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); +// method.setAccessible(true); +// method.invoke(cl, newURL); + + // first fix attempt - create a brand new URLClassLoader. As expected, we get a ClassCastException when trying + // to load the parameters so we can't save params using this method +// URL[] newURLArray = new URL[1]; +// newURLArray[0] = newURL; +// cl = new URLClassLoader(newURLArray); // second attempt - custom class loader with the system app loader specified as the parent. Loads controlled unit, but // as before it doesn't load the parameters classLoader.addURL(newURL); + // third attempt +// Class genericClass = cl.getClass(); +// Method method = genericClass.getSuperclass().getDeclaredMethod("addURL", new Class[] {URL.class}); +// method.setAccessible(true); +// method.invoke(cl, new Object[] {newURL}); + + + + // Save the name of the class to the global pluginBeingLoaded variable, and load the class. this.setPluginBeingLoaded(className); // Class c = cl.loadClass(className); @@ -1228,8 +1267,9 @@ final public class PamModel implements PamSettings { "for help.

" + "This plug-in will not be available for loading"; String help = null; - int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); + int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); System.err.println("Exception while loading " + className); + System.err.println(e1.getMessage()); continue; } } @@ -1242,7 +1282,7 @@ final public class PamModel implements PamSettings { "for help.

" + "This plug-in will not be available for loading"; String help = null; - int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, ex); + int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, ex); System.err.println("Exception while loading " + jarList.get(i).getName()); continue; } @@ -1267,7 +1307,7 @@ final public class PamModel implements PamSettings { // instantiate the plugin control class using the custom class loader try { -// File classFile = new File(pf.getJarFile()); + File classFile = new File(pf.getJarFile()); //URLClassLoader cl = new URLClassLoader(new URL[]{classFile.toURI().toURL()}); // mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),cl); mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),classLoader); @@ -1333,7 +1373,7 @@ final public class PamModel implements PamSettings { "for help.

" + "This plug-in will not be available for loading"; String help = null; - int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); + int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); System.err.println("Exception while loading " + pf.getDefaultName()); pluginList.remove(pf); continue; diff --git a/src/PamModel/PamModelSettings.java b/src/PamModel/PamModelSettings.java index 9e4b0632..667747b8 100644 --- a/src/PamModel/PamModelSettings.java +++ b/src/PamModel/PamModelSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class PamModelSettings implements Cloneable, Serializable, ManagedParameters { @@ -74,7 +75,7 @@ public class PamModelSettings implements Cloneable, Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamModel/parametermanager/PamParameterData.java b/src/PamModel/parametermanager/PamParameterData.java index a15a3c15..79944a90 100644 --- a/src/PamModel/parametermanager/PamParameterData.java +++ b/src/PamModel/parametermanager/PamParameterData.java @@ -34,6 +34,11 @@ abstract public class PamParameterData { */ private String postTitle; + /** + * field length for automatic dialogs. + */ + private int fieldLength; + /** * @param parentObject @@ -45,6 +50,21 @@ abstract public class PamParameterData { this.field = field; } + /** + * @param parentObject + * @param field + * @param shortName + * @param toolTip + * @param fieldLength length of text in automatic dialogs. + */ + public PamParameterData(Object parentObject, Field field, String shortName, String toolTip, int fieldLength) { + super(); + this.field = field; + this.shortName = shortName; + this.toolTip = toolTip; + this.fieldLength = fieldLength; + } + /** * @param parentObject * @param field @@ -58,7 +78,6 @@ abstract public class PamParameterData { this.toolTip = toolTip; } - /** * @param shortName the shortName to set */ @@ -66,6 +85,20 @@ abstract public class PamParameterData { this.shortName = shortName; } + /** + * Set info about a parameter + * @param shortName short name, e.g. to use in a dialog + * @param postTitle post title, e.g. text coming after a data entry field in a dialog + * @param toolTip tool tip to display over the component in a dialog. + * @param fieldLength length of text in automatic dialogs. + */ + public void setInfo(String shortName, String postTitle, String toolTip, int fieldLength) { + this.shortName = shortName; + this.postTitle = postTitle; + this.toolTip = toolTip; + this.fieldLength = fieldLength; + } + /** * Set info about a parameter * @param shortName short name, e.g. to use in a dialog @@ -136,6 +169,9 @@ abstract public class PamParameterData { * @return a short name for the field, suitable for use in dialogs. */ public String getShortName() { + if (shortName == null) { + return getFieldName(); + } return shortName; } @@ -166,5 +202,19 @@ abstract public class PamParameterData { return String.format("Param %s class %s", getFieldName(), getDataClass()); } + /** + * @return the fieldLength + */ + public int getFieldLength() { + return fieldLength; + } + + /** + * @param fieldLength the fieldLength to set + */ + public void setFieldLength(int fieldLength) { + this.fieldLength = fieldLength; + } + } diff --git a/src/PamModel/parametermanager/PamParameterDataGetter.java b/src/PamModel/parametermanager/PamParameterDataGetter.java index 3947f2dc..9a3e99b0 100644 --- a/src/PamModel/parametermanager/PamParameterDataGetter.java +++ b/src/PamModel/parametermanager/PamParameterDataGetter.java @@ -59,9 +59,12 @@ public class PamParameterDataGetter extends PrivatePamParameterData { if (setter == null) { return false; } + // need to convert the type + Object convObj = convertStringType(data); try { - setter.invoke(getParentObject(), data); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + Object parentObj = getParentObject(); + setter.invoke(parentObj, convObj); + } catch (InvocationTargetException e) { e.printStackTrace(); return false; } diff --git a/src/PamModel/parametermanager/PamParameterSet.java b/src/PamModel/parametermanager/PamParameterSet.java index 751f3d27..c7108e0a 100644 --- a/src/PamModel/parametermanager/PamParameterSet.java +++ b/src/PamModel/parametermanager/PamParameterSet.java @@ -29,6 +29,9 @@ public class PamParameterSet { private static boolean printDebug = false; + public enum ParameterSetType {DETECTOR, DISPLAY}; + + private ParameterSetType parameterSetType; /** * Standard modifiers to exclude. This is important for many classes which will tend to * do crazy things such as incorporate ALL of their final fields, e.g. when a Color @@ -55,8 +58,10 @@ public class PamParameterSet { * in the STANDARD_MODIFIER_EXCLUSIONS list (FINAL or STATIC). * @return Created parameter set. */ - public static PamParameterSet autoGenerate(Object parentObject) { - return autoGenerate(parentObject, STANDARD_MODIFIER_EXCLUSIONS); + public static PamParameterSet autoGenerate(Object parentObject, ParameterSetType parameterSetType) { + PamParameterSet paramSet = autoGenerate(parentObject, STANDARD_MODIFIER_EXCLUSIONS); + paramSet.setParameterSetType(parameterSetType); + return paramSet; } /** @@ -286,4 +291,19 @@ public class PamParameterSet { public PamParameterData removeParameterData(String paramName) { return parameterDatas.remove(paramName); } + + /** + * @return the parameterSetType + */ + public ParameterSetType getParameterSetType() { + return parameterSetType; + } + + /** + * @param parameterSetType the parameterSetType to set + */ + public void setParameterSetType(ParameterSetType parameterSetType) { + this.parameterSetType = parameterSetType; + } + } diff --git a/src/PamModel/parametermanager/ParameterSetManager.java b/src/PamModel/parametermanager/ParameterSetManager.java new file mode 100644 index 00000000..3420a7c4 --- /dev/null +++ b/src/PamModel/parametermanager/ParameterSetManager.java @@ -0,0 +1,73 @@ +package PamModel.parametermanager; + +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JMenuItem; + +import PamModel.parametermanager.swing.ManagedParameterDialog; +import generalDatabase.parameterstore.ParameterDatabaseStore; + +/** + * Just about everything giving overall control of some managed parameters. + * May be a bit too specific on first cut and need to be abstracted. + * Testing on 'Deployment' data. + * @author dg50 + * + * @param + */ +public class ParameterSetManager { + + private T managedParams; + private String name; + + public ParameterSetManager(T defaultParams, String name) { + setManagedParams(defaultParams); + this.name = name; +// if (managedParams == null) { +// managedParams = new T(); +// } + } + + /** + * @return the managedParams + */ + public T getManagedParams() { + return managedParams; + } + + /** + * @param managedParams the managedParams to set + */ + public void setManagedParams(T managedParams) { + this.managedParams = managedParams; + } + + public JMenuItem getMenuItem(Window parent) { + if (managedParams == null) { + return null; + } + JMenuItem menuItem = new JMenuItem(name + " ..."); + menuItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + showDialog(parent); + } + }); + + return menuItem; + } + + protected void showDialog(Window parent) { + ManagedParameterDialog dialog = new ManagedParameterDialog(parent, name, managedParams); + T newParams = dialog.showDialog(parent, name, managedParams); + + if (newParams != null) { + ParameterDatabaseStore paramDatabase = new ParameterDatabaseStore("MetaData"); + paramDatabase.saveParameterSet(newParams); + } + } + +} diff --git a/src/PamModel/parametermanager/PrivatePamParameterData.java b/src/PamModel/parametermanager/PrivatePamParameterData.java index e3fed547..6b29d9cd 100644 --- a/src/PamModel/parametermanager/PrivatePamParameterData.java +++ b/src/PamModel/parametermanager/PrivatePamParameterData.java @@ -1,6 +1,7 @@ package PamModel.parametermanager; import java.lang.reflect.Field; +import java.lang.reflect.Type; /** * Abstract instance of PamParameterDataInterface which implements everything @@ -36,9 +37,48 @@ public abstract class PrivatePamParameterData extends PamParameterData { * This should really be implemented in every concrete class, but no time to do that now. Aim to delete * this function here, then go through and implement everywhere ... */ - return false; +// return false; + Object convData = convertStringType(data); + getField().set(this, convData); + + return true; } + /** + * convert a string type to a different type appropriate for the field in + * question. + * @param value + * @return + */ + public Object convertStringType(Object value) { + if (value == null) { + return null; + } + if (value instanceof String == false) { + return value; + } + String str = (String) value; + Type type = getField().getGenericType(); + Class cls = getField().getType(); + String clsName = cls.getName(); + switch (clsName) { + case "int": + case "Integer": + return Integer.valueOf(str); + case "double": + case "Double": + return Double.valueOf(str); + case "float": + case "Float": + return Float.valueOf(str); + case "short": + case "Short": + return Short.valueOf(str); + + } + + return value; + } } diff --git a/src/PamModel/parametermanager/swing/ManagedParameterDialog.java b/src/PamModel/parametermanager/swing/ManagedParameterDialog.java new file mode 100644 index 00000000..9a3aa995 --- /dev/null +++ b/src/PamModel/parametermanager/swing/ManagedParameterDialog.java @@ -0,0 +1,49 @@ +package PamModel.parametermanager.swing; + +import java.awt.Window; + +import PamModel.parametermanager.ManagedParameters; +import PamView.dialog.PamDialog; + +public class ManagedParameterDialog extends PamDialog { + + private T params; + + private ManagedParameterPanel parameterPanel; + + public ManagedParameterDialog(Window parentFrame, String title, T params) { + super(parentFrame, title, false); + parameterPanel = new ManagedParameterPanel(params); + setDialogComponent(parameterPanel.getPanel()); + } + + public T showDialog(Window parentFrame, String title, T parameters) { +// ManagedParameterDialog dialog = new ManagedParameterDialog<>(parentFrame, title, parameters); + setParams(parameters); + setVisible(true); + + return params; + } + + private void setParams(T params) { + this.params = params; + this.parameterPanel.setParams(params); + } + + @Override + public boolean getParams() { + return parameterPanel.getParams(params); + } + + @Override + public void cancelButtonPressed() { + params = null; + } + + @Override + public void restoreDefaultSettings() { + // TODO Auto-generated method stub + + } + +} diff --git a/src/PamModel/parametermanager/swing/ManagedParameterPanel.java b/src/PamModel/parametermanager/swing/ManagedParameterPanel.java new file mode 100644 index 00000000..416bef77 --- /dev/null +++ b/src/PamModel/parametermanager/swing/ManagedParameterPanel.java @@ -0,0 +1,149 @@ +package PamModel.parametermanager.swing; + +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.Collection; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.text.JTextComponent; + +import PamModel.parametermanager.FieldNotFoundException; +import PamModel.parametermanager.ManagedParameters; +import PamModel.parametermanager.PamParameterData; +import PamModel.parametermanager.PamParameterSet; +import PamView.dialog.PamDialog; +import PamView.dialog.PamGridBagContraints; + +public class ManagedParameterPanel { + + private JPanel mainPanel; + private Collection parameterSet; + + private static final int DEFAULT_TEXT_LENGTH = 6; + private static final int MAX_SINGLE_LINE_LENGTH = 40; + + private JTextComponent[] textComponents; + + public ManagedParameterPanel(T parameterExample) { + + mainPanel = new JPanel(new GridBagLayout()); + GridBagConstraints c = new PamGridBagContraints(); + PamParameterSet exampleSet = parameterExample.getParameterSet(); + parameterSet = exampleSet.getParameterCollection(); + int n = parameterSet.size(); + textComponents = new JTextComponent[n]; + int i = 0; + for (PamParameterData paramData : parameterSet) { + textComponents[i] = createComponent(paramData); + c.gridx = 0; + c.fill = GridBagConstraints.NONE; + c.anchor = GridBagConstraints.NORTHEAST; + mainPanel.add(new JLabel(paramData.getShortName(), JLabel.RIGHT), c); + c.gridx++; + if (textComponents[i] instanceof JTextArea) { + c.fill = GridBagConstraints.HORIZONTAL; + } + else { + c.fill = GridBagConstraints.NONE; + } + c.anchor = GridBagConstraints.WEST; + mainPanel.add(textComponents[i], c); + + textComponents[i].setToolTipText(getTipText(paramData)); + + c.gridy++; + i++; + } + } + + private String getTipText(PamParameterData paramData) { + String tip = paramData.getToolTip(); + if (tip != null) { + return tip; + } + else { + return paramData.getFieldName(); + } + } + + private JTextComponent createComponent(PamParameterData paramData) { + int textLen = paramData.getFieldLength(); + if (textLen == 0) { + textLen = DEFAULT_TEXT_LENGTH; + } + if (textLen <= MAX_SINGLE_LINE_LENGTH) { + return new JTextField(textLen); + } + else { + JTextField dummyField = new JTextField(2); +// dummyField.getBorder(). + JTextArea textArea = new JTextArea(textLen/MAX_SINGLE_LINE_LENGTH+1, MAX_SINGLE_LINE_LENGTH); + textArea.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); + return textArea; + } + } + + public JComponent getPanel() { + return mainPanel; + } + + public void setParams(T params) { + int i = 0; + PamParameterData newParamData = null; + Object data = null; + for (PamParameterData paramData : this.parameterSet) { + // find the parameter in the new parameters (parameterSet is just a formatting placeholder) + try { + newParamData = params.getParameterSet().findParameterData(paramData.getFieldName()); + } catch (FieldNotFoundException e) { + e.printStackTrace(); + } + try { + data = newParamData.getData(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + if (data != null) { + textComponents[i].setText(data.toString()); + } + else { + textComponents[i].setText(null); + } + i++; + } + } + + public boolean getParams(T params) { + int i = 0; + PamParameterData newParamData = null; + Object data = null; + for (PamParameterData paramData : this.parameterSet) { + // find the parameter in the new parameters (parameterSet is just a formatting placeholder) + try { + newParamData = params.getParameterSet().findParameterData(paramData.getFieldName()); + } catch (FieldNotFoundException e) { + e.printStackTrace(); + } + String txt = textComponents[i].getText(); + try { + newParamData.setData(txt); + } catch (IllegalArgumentException | IllegalAccessException e) { + String msg = "Invalid parameter. Data type should be " + paramData.getField().getType().getName(); + return PamDialog.showWarning(null, newParamData.getShortName(), msg); + } + + i++; + } + + return true; + } + +} diff --git a/src/PamUtils/Coordinate3d.java b/src/PamUtils/Coordinate3d.java index 57a859f4..a8b6d156 100644 --- a/src/PamUtils/Coordinate3d.java +++ b/src/PamUtils/Coordinate3d.java @@ -26,6 +26,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Class definition for a x,y coordinate number type. @@ -168,7 +169,7 @@ public class Coordinate3d implements Serializable , Cloneable, PamCoordinate, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamUtils/LatLong.java b/src/PamUtils/LatLong.java index 6b8f9df9..6d465ee6 100644 --- a/src/PamUtils/LatLong.java +++ b/src/PamUtils/LatLong.java @@ -15,6 +15,7 @@ import java.text.NumberFormat; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.PamConstants; import net.sf.geographiclib.Geodesic; import net.sf.geographiclib.PolygonArea; @@ -833,7 +834,7 @@ public class LatLong implements Serializable, Cloneable, Transferable, PamCoordi */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("height"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamUtils/PamCalendar.java b/src/PamUtils/PamCalendar.java index 452e06e5..7c4c3eb8 100644 --- a/src/PamUtils/PamCalendar.java +++ b/src/PamUtils/PamCalendar.java @@ -47,10 +47,7 @@ public class PamCalendar { public static TimeZone defaultTimeZone = TimeZone.getTimeZone("UTC"); - /* - * Not used: all now handled in PamCalendar. - */ -// private static TimeZone localTimeZone = defaultTimeZone;// TimeZone.getDefault(); + private static TimeZone localTimeZone = defaultTimeZone;// TimeZone.getDefault(); public static final long millisPerDay = 1000L*24L*3600L; @@ -63,7 +60,7 @@ public class PamCalendar { private static boolean soundFile; /** - * time from the start of the file to the current moment. + * time from the start of the file to the currentmoment. * This is updated every time data re read from the file, so is * accurate to about 1/10 second. * For accurate timing within detectors, always try to use sample number @@ -180,44 +177,8 @@ public class PamCalendar { public static TimeZone getDisplayTimeZone(boolean useLocal) { // return TimeZone.getTimeZone("UTC"); - return useLocal ? CalendarControl.getInstance().getChosenTimeZone() : defaultTimeZone; -// return useLocal ? localTimeZone : defaultTimeZone; - } - - /** - * Get the display time zone offset in milliseconds. - * @param useLocal - * @return - */ - public static long getDisplayTimeZoneOffest(boolean useLocal) { - TimeZone tz = getDisplayTimeZone(useLocal); - return tz.getOffset(getTimeInMillis()); - } - - /** - * Get a short string describing the time zone. This should be less than - * 10 characters. So if the full name of the TZ is long, then write it - * in the format "UTC+..." - * @param useLocal - * @return - */ - public static String getShortDisplayTimeZoneString(boolean useLocal) { - TimeZone tz = getDisplayTimeZone(useLocal); - String str = tz.getDisplayName(); - str = CalendarControl.getInstance().getTZCode(true); - if (str.length() <= 10) { - return str; - } - // otherwise make up a string. - long offset = getDisplayTimeZoneOffest(useLocal) / 1000; - boolean isInt = offset % 3600 == 0; - if (isInt) { - str = String.format("UTC%+d", offset/3600); - } - else { - str = String.format("UTC%+3.1f", (double) offset/3600.); - } - return str; +// return useLocal ? CalendarControl.getInstance().getChosenTimeZone() : defaultTimeZone; + return useLocal ? localTimeZone : defaultTimeZone; } public static String formatDateTime(Date date) { @@ -430,13 +391,8 @@ public class PamCalendar { public static String formatDBStyleTime(long timeInMillis, boolean showMillis, boolean useLocal) { Calendar c = Calendar.getInstance(); - TimeZone tz = getDisplayTimeZone(useLocal); -// if (tz != null) { -// long offs = tz.getOffset(timeInMillis); -// timeInMillis += tz.getOffset(timeInMillis); -// } c.setTimeInMillis(timeInMillis); - c.setTimeZone(tz); + c.setTimeZone(getDisplayTimeZone(useLocal)); DateFormat df; if (showMillis) { df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @@ -444,7 +400,7 @@ public class PamCalendar { else { df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } - df.setTimeZone(tz); + df.setTimeZone(getDisplayTimeZone(useLocal)); Date d = c.getTime(); // return String.format("%tY-% { JComponent toolTipComponent; + /** + * Gets an adapter that can provide tooltips automatically based on plotted data units. + * @param component + * @return + */ public MouseHoverAdapter getMouseHoverAdapter(JComponent component) { ToolTipManager tt = ToolTipManager.sharedInstance(); tt.registerComponent(component); @@ -384,7 +389,9 @@ public abstract class GeneralProjector { } String hintText = dataBlock.getHoverText(this, hoveredDataUnit, hoverData.get(unitIndex).getAmbiguity()); - if (hintText == null) return null; + if (hintText == null) { + return null; + } // System.out.println(hintText); return hintText; } diff --git a/src/PamView/GroupedSourceParameters.java b/src/PamView/GroupedSourceParameters.java index f26cdafd..fb0b7509 100644 --- a/src/PamView/GroupedSourceParameters.java +++ b/src/PamView/GroupedSourceParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import PamView.dialog.GroupedSourcePanel; @@ -210,7 +211,7 @@ public class GroupedSourceParameters implements Serializable, Cloneable, Managed */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamView/GuiFrameSettings.java b/src/PamView/GuiFrameSettings.java index d367c1e3..3445c790 100644 --- a/src/PamView/GuiFrameSettings.java +++ b/src/PamView/GuiFrameSettings.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamController.PamControlledUnit; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -55,7 +56,7 @@ public class GuiFrameSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("unitFrameInfo"); ps.put(new PrivatePamParameterData(this, field) { @@ -89,7 +90,7 @@ public class GuiFrameSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("guiFrame"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamView/PamGui.java b/src/PamView/PamGui.java index bbb4fc73..b5d91e8f 100644 --- a/src/PamView/PamGui.java +++ b/src/PamView/PamGui.java @@ -61,6 +61,7 @@ import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JRootPane; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.Timer; @@ -73,6 +74,7 @@ import javax.swing.event.MenuListener; import Acquisition.DaqSystemInterface; import annotation.tasks.AnnotationManager; +import metadata.MetaDataContol; import performanceTests.PerformanceDialog; import tipOfTheDay.TipOfTheDayManager; import Array.ArrayManager; @@ -601,6 +603,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings { fileMenu.add(menuItem); } + // if (SMRUEnable.isEnable()) { menuItem = new JMenuItem("Import PAMGuard Modules"); menuItem.setToolTipText("Import module settings from a different PAMGuard configuration (psfx files only"); menuItem.addActionListener(new ActionListener() { @@ -610,6 +613,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings { } }); fileMenu.add(menuItem); +// } fileMenu.addSeparator(); @@ -759,6 +763,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings { //for changing "hydrophones" to "microphone" and vice versa if medium changes. menu.addMenuListener(new SettingsMenuListener()); + menu.add(MetaDataContol.getMetaDataControl().createMenu(frame)); menu.addSeparator(); @@ -1664,10 +1669,10 @@ public class PamGui extends PamView implements WindowListener, PamSettings { protected void getGuiParameters() { guiParameters.extendedState = frame.getExtendedState(); guiParameters.state = frame.getState(); - if (guiParameters.state != Frame.MAXIMIZED_BOTH) { +// if (guiParameters.state != Frame.MAXIMIZED_BOTH) { guiParameters.size = frame.getSize(); guiParameters.bounds = frame.getBounds(); - } +// } } /** @@ -1982,6 +1987,30 @@ public class PamGui extends PamView implements WindowListener, PamSettings { public PamTabbedPane getTabbedPane() { return this.mainTab; } + + /** + * find a parent window for a JComponent. This can be useful in + * finding windows to open child dialogs when the object holding + * the component may not have a direct reference back to it's dialog. + * @param component any Swing component + * @return parent Window (or frame) if it can be found + */ + public static Window findComponentWindow(JComponent component) { + if (component == null) { + return null; + } + JRootPane root = component.getRootPane(); + if (root == null) { + return null; + } + Container rootP = root.getParent(); + if (rootP instanceof Window) { + return (Window) rootP; + } + else { + return null; + } + } } \ No newline at end of file diff --git a/src/PamView/PamSymbol.java b/src/PamView/PamSymbol.java index 00c471f6..2a4f4061 100644 --- a/src/PamView/PamSymbol.java +++ b/src/PamView/PamSymbol.java @@ -38,6 +38,7 @@ import javax.swing.JPanel; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.PamColors.PamColor; import PamView.symbol.SymbolData; @@ -808,7 +809,7 @@ public class PamSymbol extends PamSymbolBase implements Serializable, Icon, Clon @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamView/dialog/warn/WarnOnce.java b/src/PamView/dialog/warn/WarnOnce.java index 93ed4618..cd7ad08d 100644 --- a/src/PamView/dialog/warn/WarnOnce.java +++ b/src/PamView/dialog/warn/WarnOnce.java @@ -48,6 +48,7 @@ public class WarnOnce implements PamSettings { int ans = showWarning(parent, "Warning Messages", "Show all PAMGuard warning messages", WarnOnce.OK_CANCEL_OPTION); if (ans == WarnOnce.CANCEL_OPTION) return; singleInstance.warnOnceList.clearList(); + singleInstance.showThisSess.clear(); } @Override diff --git a/src/PamView/paneloverlay/OverlayDataInfo.java b/src/PamView/paneloverlay/OverlayDataInfo.java index 3c3ed86b..fd590d82 100644 --- a/src/PamView/paneloverlay/OverlayDataInfo.java +++ b/src/PamView/paneloverlay/OverlayDataInfo.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OverlayDataInfo implements Serializable, Cloneable, ManagedParameters { @@ -31,7 +32,7 @@ public class OverlayDataInfo implements Serializable, Cloneable, ManagedParamete */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java b/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java index f6c8d446..ae081fc1 100644 --- a/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java +++ b/src/PamView/paneloverlay/overlaymark/MarkDataSelectorParams.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamDataBlock; @@ -73,7 +74,7 @@ public class MarkDataSelectorParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("overlayChoices"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamView/symbol/ManagedSymbolData.java b/src/PamView/symbol/ManagedSymbolData.java index 23bb555d..19789f61 100644 --- a/src/PamView/symbol/ManagedSymbolData.java +++ b/src/PamView/symbol/ManagedSymbolData.java @@ -3,7 +3,11 @@ package PamView.symbol; import java.io.Serializable; import java.util.Hashtable; -public class ManagedSymbolData implements Cloneable, Serializable { +import PamModel.parametermanager.ManagedParameters; +import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; + +public class ManagedSymbolData implements Cloneable, Serializable, ManagedParameters { public static final long serialVersionUID = 1L; @@ -34,5 +38,10 @@ public class ManagedSymbolData implements Cloneable, Serializable { return symbolOptions; } + @Override + public PamParameterSet getParameterSet() { + return PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); + } + } diff --git a/src/PamView/wizard/PamWizard.java b/src/PamView/wizard/PamWizard.java new file mode 100644 index 00000000..9ba67e01 --- /dev/null +++ b/src/PamView/wizard/PamWizard.java @@ -0,0 +1,160 @@ +package PamView.wizard; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +import javax.swing.JButton; +import javax.swing.JPanel; + +import PamView.dialog.PamDialog; +import tethys.swing.export.ExportStreamInfoPanel; +import tethys.swing.export.ExportWizardCard; + +abstract public class PamWizard extends PamDialog { + + private static final long serialVersionUID = 1L; + + private JPanel cardPanel; + + private CardLayout cardLayout; + + private JPanel mainPanel; + + private JButton prevButton; + + private ArrayList wizardCards = new ArrayList(); + + public PamWizard(Window parentFrame, String title) { + super(parentFrame, title, false); + + cardLayout = new CardLayout(); + mainPanel = new JPanel(new BorderLayout()); + cardPanel = new JPanel(cardLayout); + mainPanel.add(BorderLayout.CENTER, cardPanel); + + setDialogComponent(mainPanel); + + getOkButton().setText("Finish"); + prevButton = new JButton("Previous"); + getButtonPanel().add(prevButton, 0); + prevButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + previousButton(); + } + }); + + setResizable(true); + } + + public void addCard(PamWizardCard wizPanel) { + cardPanel.add(wizPanel, wizPanel.getTitle()); + wizardCards.add(wizPanel); + } + + /** + * Get the main panel. This is the main dialog panel and uses a borderlayout + * with the cards in the CENTER of the panel. Additional information panels + * (generally fixed and not changing with the dialog) can be added NORTH, SOUTH, WEST and EAST. + * @return main Panel. + */ + public JPanel getMainPanel() { + return mainPanel; + } + + /** + * Called when 'previous' button is clicked. + */ + protected void previousButton() { + cardLayout.previous(cardPanel); + enableControls(); + } + + public void enableControls() { + int iCard = getCardIndex(); + prevButton.setEnabled(iCard > 0); + boolean isLast = iCard == wizardCards.size()-1; +// getOkButton().setEnabled(!isLast); + getOkButton().setText(isLast ? "Finish" : "Next"); + } + + private boolean checkCurrentCard() { + int iCard = getCardIndex(); + if (iCard < 0) { + return true; + } + return getCardParams(wizardCards.get(iCard)); + } + + abstract public void setCardParams(PamWizardCard wizardCard); + + abstract public boolean getCardParams(PamWizardCard wizardCard); + + public int getCardIndex() { + for (int i = 0; i < cardPanel.getComponentCount(); i++) { + Component component = cardPanel.getComponent(i); + if (component.isVisible()) { + return i; + } + } + return -1; + } + + public JButton getPreviousButton() { + return prevButton; + } + + public void setParams() { + for (PamWizardCard wizCard : wizardCards) { + setCardParams(wizCard); + } + enableControls(); + } + + @Override + public boolean getParams() { + /** + * This is the OK button, so we need to NOT return OK, which would close the + * dialog until we're on the last card. + */ + if (checkCurrentCard() == false) { + return false; + } + int iCard = getCardIndex(); + if (iCard < wizardCards.size()-1) { + cardLayout.next(cardPanel); + enableControls(); + return false; + } + + return true; + } + + + + @Override + public void restoreDefaultSettings() { + // TODO Auto-generated method stub + + } + + /** + * Move to the first card in the stack + */ + public void moveFirst() { + cardLayout.first(cardPanel); + } + + /** + * Move to the last card in the stack + */ + public void moveLast() { + cardLayout.last(cardPanel); + } + +} diff --git a/src/PamView/wizard/PamWizardCard.java b/src/PamView/wizard/PamWizardCard.java new file mode 100644 index 00000000..bc0d9e14 --- /dev/null +++ b/src/PamView/wizard/PamWizardCard.java @@ -0,0 +1,45 @@ +package PamView.wizard; + +import java.io.Serializable; + +import javax.swing.JPanel; + + +/** + * Base class for PAMGuard wizard cards. + * @author dg50 + * + * @param class type for parameters to set and get. + */ +abstract public class PamWizardCard extends JPanel { + + private static final long serialVersionUID = 1L; + + private String title; + + private PamWizard pamWizard; + + /** + * @param title + */ + public PamWizardCard(PamWizard pamWizard, String title) { + this.pamWizard = pamWizard; + this.title = title; + } + + public abstract boolean getParams(T cardParams); + + public abstract void setParams(T cardParams); + + public String getTitle() { + return title; + } + + /** + * @return the pamWizard + */ + public PamWizard getPamWizard() { + return pamWizard; + } + +} diff --git a/src/PamguardMVC/AcousticDataBlock.java b/src/PamguardMVC/AcousticDataBlock.java index ec7477c1..f7fb5c8e 100644 --- a/src/PamguardMVC/AcousticDataBlock.java +++ b/src/PamguardMVC/AcousticDataBlock.java @@ -1,5 +1,8 @@ package PamguardMVC; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + import PamController.PamControllerInterface; import PamguardMVC.nanotime.NanosFromSamples; @@ -90,5 +93,12 @@ abstract public class AcousticDataBlock extends PamD return parentSourceData; } + @Override + public Element getDataBlockXML(Document doc) { + Element el = super.getDataBlockXML(doc); + el.setAttribute("SampleRate", String.format("%3.1f", getSampleRate())); + return el; + } + } diff --git a/src/PamguardMVC/DataAutomation.java b/src/PamguardMVC/DataAutomation.java new file mode 100644 index 00000000..cd424c60 --- /dev/null +++ b/src/PamguardMVC/DataAutomation.java @@ -0,0 +1,29 @@ +package PamguardMVC; + +/** + * @author dg50 + * Levels of automation for the various datas in PAMGuard. + * Should be used within DataAutomationInfo to perhaps combine with other info in the future. + * + */ +public enum DataAutomation { + + AUTOMATIC, MANUAL, MANUALANDAUTOMATIC; + + @Override + public String toString() { + switch (this) { + case AUTOMATIC: + return "Automatic"; + case MANUAL: + return "Manual"; + case MANUALANDAUTOMATIC: + return "Manual and automatic"; + default: + break; + + } + return null; + } + +} diff --git a/src/PamguardMVC/DataAutomationInfo.java b/src/PamguardMVC/DataAutomationInfo.java new file mode 100644 index 00000000..42c7e42d --- /dev/null +++ b/src/PamguardMVC/DataAutomationInfo.java @@ -0,0 +1,44 @@ +package PamguardMVC; + +/** + * Returned by datablocks, though default is null, to give information on how + * automatic the process was. + * @author dg50 + * + */ +public class DataAutomationInfo { + + + private DataAutomation automation; + + /** + * @param automation + */ + public DataAutomationInfo(DataAutomation automation) { + this.setAutomation(automation); + } + + /** + * @return the automation + */ + public DataAutomation getAutomation() { + return automation; + } + + /** + * @param automation the automation to set + */ + public void setAutomation(DataAutomation automation) { + this.automation = automation; + } + + @Override + public String toString() { + if (automation == null) { + return "Unknown data automation"; + } + return automation.toString(); + } + + +} diff --git a/src/PamguardMVC/DataBlock2D.java b/src/PamguardMVC/DataBlock2D.java index beae1e15..89eb0ec9 100644 --- a/src/PamguardMVC/DataBlock2D.java +++ b/src/PamguardMVC/DataBlock2D.java @@ -1,5 +1,8 @@ package PamguardMVC; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + import dataPlotsFX.data.DataTypeInfo; abstract public class DataBlock2D extends AcousticDataBlock { @@ -39,4 +42,18 @@ abstract public class DataBlock2D extends AcousticDat * @return data type information. */ abstract public DataTypeInfo getScaleInfo(); + + public Element getDataBlockXML(Document doc) { + Element el = super.getDataBlockXML(doc); + DataTypeInfo dti = getScaleInfo(); + if (dti != null) { + if (dti.dataType != null) { + el.setAttribute("DataType", dti.dataType.toString()); + } + if (dti.dataUnits != null) { + el.setAttribute("DataUnits", dti.dataUnits.toString()); + } + } + return el; + } } diff --git a/src/PamguardMVC/PamDataBlock.java b/src/PamguardMVC/PamDataBlock.java index 97bd709c..b865d572 100644 --- a/src/PamguardMVC/PamDataBlock.java +++ b/src/PamguardMVC/PamDataBlock.java @@ -44,10 +44,16 @@ import javax.swing.Timer; import javax.swing.border.EmptyBorder; import org.springframework.core.GenericTypeResolver; +import org.w3c.dom.Document; +import org.w3c.dom.Element; import Acquisition.AcquisitionControl; import Acquisition.AcquisitionProcess; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.AutoTethysProvider; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; import dataGram.DatagramProvider; import dataMap.BespokeDataMapGraphic; import dataMap.OfflineDataMap; @@ -62,6 +68,7 @@ import PamController.PamController; import PamController.PamControllerInterface; import PamDetection.LocContents; import PamDetection.LocalisationInfo; +import PamDetection.PamDetection; import PamUtils.PamCalendar; import PamUtils.PamUtils; import PamView.symbol.PamSymbolManager; @@ -69,8 +76,10 @@ import PamguardMVC.background.BackgroundDataBlock; import PamguardMVC.background.BackgroundManager; import PamguardMVC.dataOffline.OfflineDataLoadInfo; import PamguardMVC.dataOffline.OfflineDataLoading; +import PamguardMVC.dataSelector.DataSelectParams; import PamguardMVC.dataSelector.DataSelector; import PamguardMVC.dataSelector.DataSelectorCreator; +import PamguardMVC.dataSelector.DataSelectorSettings; import PamguardMVC.dataSelector.NullDataSelectorCreator; import PamguardMVC.datamenus.DataMenuParent; import PamguardMVC.nanotime.NanoTimeCalculator; @@ -2833,7 +2842,7 @@ public class PamDataBlock extends PamObservable { * @return temporary copy of the data */ public ArrayList getDataCopy(long t1, long t2, boolean assumeOrder, DataSelector dataSelector) { - if (dataSelector == null) { + if (dataSelector == null || dataSelector.getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) { return getDataCopy(t1, t2, assumeOrder); } else { @@ -2865,6 +2874,7 @@ public class PamDataBlock extends PamObservable { private SQLLogging logging; private JSONObjectDataSource jsonDataSource; + public Vector getProcessAnnotations() { return processAannotations; @@ -3074,6 +3084,34 @@ public class PamDataBlock extends PamObservable { public SQLLogging getLogging() { return logging; } + + /** + * Gets a data provider for Tethys. These will probably need + * to be bespoke, but for now will autogenerate based on the SQLLogging information. + * @return the tethysDataProvider + */ + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + return null; + } + + /** + * Get the level of automation employed by the generation of these data. + * Should ideally be completed for everything providing data to Tethys. + * @return level of automation for this data block. + */ + public DataAutomationInfo getDataAutomationInfo() { + return null; + } + + /** + * Get information about species types that may occur within this data + * block. Primarily for conversion into Tethys compatible data, but may + * prove to have other uses. + * @return Types of species information available within this datablock. + */ + public DataBlockSpeciesManager getDatablockSpeciesManager() { + return null; + } final public boolean getCanLog() { return (logging != null); @@ -4229,4 +4267,23 @@ public class PamDataBlock extends PamObservable { public void setBackgroundManager(BackgroundManager backgroundManager) { this.backgroundManager = backgroundManager; } + + /** + * Get a brief summary of datablock to include in XML descriptions. + * Basic output is very simple. Expect other datablock to extend this by + * adding additional attributes. + * @param doc + * @return XML element with description of data. + */ + public Element getDataBlockXML(Document doc) { + Element inputEl = doc.createElement("Input"); + if (getParentProcess() != null && getParentProcess().getPamControlledUnit() != null) { + PamControlledUnit pcu = getParentProcess().getPamControlledUnit(); + inputEl.setAttribute("ModuleType", pcu.getUnitType()); + inputEl.setAttribute("ModuleName", pcu.getUnitName()); + } + inputEl.setAttribute("Name", getLongDataName()); + inputEl.setAttribute("Channels", String.format("0x%X", getChannelMap())); + return inputEl; + } } diff --git a/src/PamguardMVC/PamDataUnit.java b/src/PamguardMVC/PamDataUnit.java index 3295381f..8630a7d1 100644 --- a/src/PamguardMVC/PamDataUnit.java +++ b/src/PamguardMVC/PamDataUnit.java @@ -974,8 +974,13 @@ abstract public class PamDataUnit // add frequency and amplitude information - str += "Frequency: " + FrequencyFormat.formatFrequencyRange(this.getFrequency(), true) + "
"; - str += String.format("Amplitude: %3.1fdB
", getAmplitudeDB()); + double[] frequency = this.getFrequency(); + if (frequency != null) { + str += "Frequency: " + FrequencyFormat.formatFrequencyRange(this.getFrequency(), true) + "
"; + } + if (getAmplitudeDB() != 0) { + str += String.format("Amplitude: %3.1fdB
", getAmplitudeDB()); + } if (getSignalSPL() != null) { str += String.format("SPL: %3.1fdBre1uPa
",linAmplitudeToDB(getSignalSPL())); } diff --git a/src/PamguardMVC/RawDataDisplayOptions.java b/src/PamguardMVC/RawDataDisplayOptions.java index 9ed8355c..6ff49562 100644 --- a/src/PamguardMVC/RawDataDisplayOptions.java +++ b/src/PamguardMVC/RawDataDisplayOptions.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class RawDataDisplayOptions implements Serializable, Cloneable, ManagedParameters { @@ -13,7 +14,7 @@ public class RawDataDisplayOptions implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/PamguardMVC/RawDataUnavailableException.java b/src/PamguardMVC/RawDataUnavailableException.java index 581f981d..37e4275a 100644 --- a/src/PamguardMVC/RawDataUnavailableException.java +++ b/src/PamguardMVC/RawDataUnavailableException.java @@ -61,7 +61,7 @@ public class RawDataUnavailableException extends Exception { return String.format("Samples %d length %d requested from %s have not yet arrived", startSample, duration, rawDataBlock.getDataName()); case INVALID_CHANNEL_LIST: - return String.format("Samples %d length %d requested from %s do not contain the reqeusted channels %s", + return String.format("Samples %d length %d requested from %s do not contain the reqeusted channels", startSample, duration, rawDataBlock.getDataName()); case NEGATIVE_DURATION: return String.format("Negative data duration request for %d samples" , duration); diff --git a/src/PamguardMVC/blockprocess/PamBlockParams.java b/src/PamguardMVC/blockprocess/PamBlockParams.java index 249d98e1..aaaed713 100644 --- a/src/PamguardMVC/blockprocess/PamBlockParams.java +++ b/src/PamguardMVC/blockprocess/PamBlockParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import gpl.GPLParameters; /** @@ -44,7 +45,7 @@ public class PamBlockParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamguardMVC/dataSelector/DataSelectParams.java b/src/PamguardMVC/dataSelector/DataSelectParams.java index da0f5e74..0d4af3fb 100644 --- a/src/PamguardMVC/dataSelector/DataSelectParams.java +++ b/src/PamguardMVC/dataSelector/DataSelectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Data select parameters. @@ -53,7 +54,7 @@ abstract public class DataSelectParams implements Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/PamguardMVC/dataSelector/DataSelector.java b/src/PamguardMVC/dataSelector/DataSelector.java index 0503479f..b033976c 100644 --- a/src/PamguardMVC/dataSelector/DataSelector.java +++ b/src/PamguardMVC/dataSelector/DataSelector.java @@ -9,7 +9,10 @@ import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JMenuItem; +import org.w3c.dom.Document; + import PamController.PamController; +import PamController.settings.output.xml.PamguardXMLWriter; import PamView.dialog.PamDialogPanel; import PamView.dialog.SettingsButton; import PamguardMVC.PamDataBlock; @@ -39,7 +42,7 @@ public abstract class DataSelector { private String selectorTitle; private boolean allowScores; - + /** * Create a data selector for a DataBlock. If allowScores is * true, then the selector MAY (but may not) offer a more complicated @@ -104,18 +107,8 @@ public abstract class DataSelector { if (parentFrame == null) { parentFrame = PamController.getMainFrame(); } - Window localWin = parentFrame; - DataSelectorChangeListener localChangeListener = changeListener; JMenuItem menuItem = new JMenuItem("Data selection ..."); - menuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - boolean ok = showSelectDialog(localWin); - if (ok && changeListener != null) { - changeListener.selectorChange(DataSelector.this); - } - } - }); + menuItem.addActionListener(new ShowSettingsButton(parentFrame, changeListener)); return menuItem; } @@ -129,6 +122,24 @@ public abstract class DataSelector { return ok; } + /** + * Get descriptive text about the data selector which can be + * added to dialogs and other information panels. + * @return descriptive text. Default is a xml dump of params. + */ + public String getDescription() { + if (getParams() == null) { + return null; + } + PamguardXMLWriter xmlWriter = PamguardXMLWriter.getXMLWriter(); + Document doc = xmlWriter.writeOneObject(getParams()); + if (doc != null) { + String str = xmlWriter.getAsString(doc, true); + return str; + } + return null; + } + /** * Score a PAMDataUnit. this is used in preference * to a boolean select function so that the user can add different @@ -228,25 +239,40 @@ public abstract class DataSelector { * @param parentWindow */ public JButton getDialogButton(Window parentWindow) { + return getDialogButton(parentWindow, null); + } + /** + * Create a settings type button that can be inserted into a + * larger dialog. + * @param parentWindow + */ + + public JButton getDialogButton(Window parentWindow, DataSelectorChangeListener changeListener) { JButton button = new SettingsButton(); - button.addActionListener(new ShowSettingsButton(parentWindow)); + button.addActionListener(new ShowSettingsButton(parentWindow, changeListener)); button.setToolTipText("Data selection options for " + getSelectorTitle()); return button; } private class ShowSettingsButton implements ActionListener { private Window parentWindow; + private DataSelectorChangeListener changeListener; /** * @param parentWindow + * @param changeListener */ - public ShowSettingsButton(Window parentWindow) { + public ShowSettingsButton(Window parentWindow, DataSelectorChangeListener changeListener) { super(); this.parentWindow = parentWindow; + this.changeListener = changeListener; } @Override public void actionPerformed(ActionEvent e) { - showSelectDialog(parentWindow); + boolean ok = showSelectDialog(parentWindow); + if (ok && changeListener != null) { + changeListener.selectorChange(DataSelector.this); + } } } diff --git a/src/PamguardMVC/dataSelector/DataSelectorSettings.java b/src/PamguardMVC/dataSelector/DataSelectorSettings.java index f29c8103..df66d20e 100644 --- a/src/PamguardMVC/dataSelector/DataSelectorSettings.java +++ b/src/PamguardMVC/dataSelector/DataSelectorSettings.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DataSelectorSettings implements Serializable, ManagedParameters { @@ -42,7 +43,7 @@ public class DataSelectorSettings implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("selectorParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamguardMVC/datakeeper/DataKeeperSettings.java b/src/PamguardMVC/datakeeper/DataKeeperSettings.java index 446669c6..3765ef72 100644 --- a/src/PamguardMVC/datakeeper/DataKeeperSettings.java +++ b/src/PamguardMVC/datakeeper/DataKeeperSettings.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DataKeeperSettings implements Serializable, Cloneable, ManagedParameters { @@ -51,7 +52,7 @@ public class DataKeeperSettings implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("keepTimeData"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/PamguardMVC/toad/GenericTOADSourceParams.java b/src/PamguardMVC/toad/GenericTOADSourceParams.java index e0c2237c..cd12140a 100644 --- a/src/PamguardMVC/toad/GenericTOADSourceParams.java +++ b/src/PamguardMVC/toad/GenericTOADSourceParams.java @@ -6,6 +6,7 @@ import Localiser.DelayMeasurementParams; import Localiser.controls.RawOrFFTParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * General parameters for detection TOAD measurement. Is split @@ -67,7 +68,7 @@ public class GenericTOADSourceParams implements Cloneable, Serializable, Managed @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java b/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java index c08a3f68..3b7546c2 100644 --- a/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java +++ b/src/RightWhaleEdgeDetector/RWEBinaryDataSource.java @@ -218,7 +218,7 @@ public class RWEBinaryDataSource extends BinaryDataSource { binaryObjectData.getDataUnitBaseData().setSampleDuration(duration); // rweDataUnit = new RWEDataUnit(aSound.timeMilliseconds, channelMap, // startSample, duration, aSound); - rweDataUnit = new RWEDataUnit(binaryObjectData.getDataUnitBaseData(), aSound); + rweDataUnit = new RWEDataUnit(rweProcess, binaryObjectData.getDataUnitBaseData(), aSound); rweDataUnit.setSequenceBitmap(sequenceMap); double f[] = new double[2]; f[0] = aSound.minFreq * rweDataBlock.getSampleRate()/rweDataBlock.getFftLength(); diff --git a/src/RightWhaleEdgeDetector/RWEDataBlock.java b/src/RightWhaleEdgeDetector/RWEDataBlock.java index 1969bca0..90c9a616 100644 --- a/src/RightWhaleEdgeDetector/RWEDataBlock.java +++ b/src/RightWhaleEdgeDetector/RWEDataBlock.java @@ -2,19 +2,29 @@ package RightWhaleEdgeDetector; import PamView.GroupedDataSource; import PamView.GroupedSourceParameters; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.PamProcess; import PamguardMVC.dataOffline.OfflineDataLoadInfo; import PamguardMVC.dataSelector.DataSelectorCreator; import RightWhaleEdgeDetector.datasel.RWDataSelCreator; +import RightWhaleEdgeDetector.species.RWSpeciesManager; +import RightWhaleEdgeDetector.species.RWTethysDataProvider; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; import whistlesAndMoans.AbstractWhistleDataBlock; -public class RWEDataBlock extends AbstractWhistleDataBlock implements GroupedDataSource { +public class RWEDataBlock extends AbstractWhistleDataBlock implements GroupedDataSource { private double[] rwFreqRange = {50., 250.}; private RWEControl rweControl; private RWEProcess rweProcess; private RWDataSelCreator dataSelCreator; + + private RWSpeciesManager rwSpeciesManager; + private RWTethysDataProvider rwTethysDataProvider; public RWEDataBlock(RWEControl rweControl, String dataName, RWEProcess rweProcess, int channelMap) { @@ -53,4 +63,25 @@ public class RWEDataBlock extends AbstractWhistleDataBlock implements GroupedDat return dataSelCreator; } + @Override + public DataBlockSpeciesManager getDatablockSpeciesManager() { + if (rwSpeciesManager == null) { + rwSpeciesManager = new RWSpeciesManager(this); + } + return rwSpeciesManager; + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (rwTethysDataProvider == null) { + rwTethysDataProvider = new RWTethysDataProvider(tethysControl, rweProcess.getRweDataBlock()); + } + return rwTethysDataProvider; + } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.AUTOMATIC); + } + } diff --git a/src/RightWhaleEdgeDetector/RWEDataUnit.java b/src/RightWhaleEdgeDetector/RWEDataUnit.java index 226e0f64..c3144ebf 100644 --- a/src/RightWhaleEdgeDetector/RWEDataUnit.java +++ b/src/RightWhaleEdgeDetector/RWEDataUnit.java @@ -6,26 +6,31 @@ import whistlesAndMoans.AbstractWhistleDataUnit; public class RWEDataUnit extends AbstractWhistleDataUnit { public RWESound rweSound; + private RWEProcess rweProcess; - public RWEDataUnit(long timeMilliseconds, int channelBitmap, + public RWEDataUnit(RWEProcess rweProcess, long timeMilliseconds, int channelBitmap, long startSample, long duration, RWESound rweSound) { super(timeMilliseconds, channelBitmap, startSample, duration); this.rweSound = rweSound; + this.rweProcess = rweProcess; // TODO Auto-generated constructor stub } - public RWEDataUnit(DataUnitBaseData basicData, RWESound rweSound) { + public RWEDataUnit(RWEProcess rweProcess, DataUnitBaseData basicData, RWESound rweSound) { super(basicData); this.rweSound = rweSound; + this.rweProcess = rweProcess; } - double[] freqsHz; @Override public double[] getFreqsHz() { - if (freqsHz == null) { - freqsHz = new double[rweSound.sliceCount]; + double[] f = new double[rweSound.sliceCount]; + RWEDataBlock rweDataBlock = rweProcess.getRweDataBlock(); + double binToHz = rweDataBlock.getSampleRate() / rweDataBlock.getFftLength(); + for (int i = 0; i < f.length; i++) { + f[i] = (double) rweSound.peakFreq[i] * binToHz; } - return null; + return f; } @Override @@ -35,8 +40,16 @@ public class RWEDataUnit extends AbstractWhistleDataUnit { @Override public double[] getTimesInSeconds() { - // TODO Auto-generated method stub - return null; + if (rweSound == null) { + return null; + } + double[] t = new double[rweSound.sliceCount]; + RWEDataBlock rweDataBlock = rweProcess.getRweDataBlock(); + double binToT = rweDataBlock.getFftHop() / rweDataBlock.getSampleRate(); + for (int i = 0; i < t.length; i++) { + t[i] = (double) rweSound.sliceList[i] * binToT; + } + return t; } @Override diff --git a/src/RightWhaleEdgeDetector/RWEParameters.java b/src/RightWhaleEdgeDetector/RWEParameters.java index 8bb661a4..4b179378 100644 --- a/src/RightWhaleEdgeDetector/RWEParameters.java +++ b/src/RightWhaleEdgeDetector/RWEParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class RWEParameters implements Serializable, Cloneable, ManagedParameters { @@ -41,7 +42,7 @@ public class RWEParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/RightWhaleEdgeDetector/RWEProcess.java b/src/RightWhaleEdgeDetector/RWEProcess.java index ccc766bb..081489c9 100644 --- a/src/RightWhaleEdgeDetector/RWEProcess.java +++ b/src/RightWhaleEdgeDetector/RWEProcess.java @@ -42,6 +42,10 @@ public class RWEProcess extends PamProcess { private FFTDataBlock sourceDataBlock; private RWEDataBlock rweDataBlock; + public RWEDataBlock getRweDataBlock() { + return rweDataBlock; + } + private Hashtable bearingLocalisers; private StandardSymbolManager symbolManager; /** @@ -212,7 +216,7 @@ public class RWEProcess extends PamProcess { // System.out.println(String.format("Detected sound type %d on channel %d", // soundType, this.iChannel)); duration = sourceDataBlock.getFftHop() * aSound.duration; - rweDataUnit = new RWEDataUnit(aSound.timeMilliseconds, + rweDataUnit = new RWEDataUnit(RWEProcess.this, aSound.timeMilliseconds, 1< { + + private RWSpeciesTypes rwSpeciesTypes = new RWSpeciesTypes(); + + public RWSpeciesManager(PamDataBlock dataBlock) { + super(dataBlock); + setDefaultDefaultSpecies(new SpeciesMapItem(RWSpeciesTypes.eubalaena, RWSpeciesTypes.onlyType, RWSpeciesTypes.defaultName)); + } + + @Override + public DataBlockSpeciesCodes getSpeciesCodes() { + return null; + } + + @Override + public String getSpeciesCode(RWEDataUnit dataUnit) { + return RWSpeciesTypes.defaultName; + } + +} diff --git a/src/RightWhaleEdgeDetector/species/RWSpeciesTypes.java b/src/RightWhaleEdgeDetector/species/RWSpeciesTypes.java new file mode 100644 index 00000000..654fe24c --- /dev/null +++ b/src/RightWhaleEdgeDetector/species/RWSpeciesTypes.java @@ -0,0 +1,17 @@ +package RightWhaleEdgeDetector.species; + +import tethys.species.DataBlockSpeciesCodes; + +public class RWSpeciesTypes extends DataBlockSpeciesCodes { + + public static final String onlyType = "Up call"; + + public static final int eubalaena = 180536; + + public static final String defaultName = "Right Whale"; + + public RWSpeciesTypes() { + super(eubalaena, defaultName, onlyType); + } + +} diff --git a/src/RightWhaleEdgeDetector/species/RWTethysDataProvider.java b/src/RightWhaleEdgeDetector/species/RWTethysDataProvider.java new file mode 100644 index 00000000..3577bd12 --- /dev/null +++ b/src/RightWhaleEdgeDetector/species/RWTethysDataProvider.java @@ -0,0 +1,37 @@ +package RightWhaleEdgeDetector.species; + +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamDataUnit; +import RightWhaleEdgeDetector.RWEDataUnit; +import nilus.Detection; +import nilus.Detection.Parameters; +import tethys.TethysControl; +import tethys.output.StreamExportParams; +import tethys.output.TethysExportParams; +import tethys.pamdata.AutoTethysProvider; + +public class RWTethysDataProvider extends AutoTethysProvider { + + public RWTethysDataProvider(TethysControl tethysControl, PamDataBlock pamDataBlock) { + super(tethysControl, pamDataBlock); + } + + @Override + public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams, + StreamExportParams streamExportParams) { + Detection detection = super.createDetection(dataUnit, tethysExportParams, streamExportParams); + if (detection == null) { + return null; + } + + RWEDataUnit rweDataUnit = (RWEDataUnit) dataUnit; + + Parameters parameters = detection.getParameters(); + parameters.setScore((double) rweDataUnit.rweSound.soundType); + double snr = 20.*Math.log10(rweDataUnit.rweSound.signal/rweDataUnit.rweSound.noise); + parameters.setSNRDB(snr); + + return detection; + } + +} diff --git a/src/SoundRecorder/RecorderSettings.java b/src/SoundRecorder/RecorderSettings.java index 72c9576d..4fcd6eec 100644 --- a/src/SoundRecorder/RecorderSettings.java +++ b/src/SoundRecorder/RecorderSettings.java @@ -16,6 +16,7 @@ import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import PamguardMVC.PamRawDataBlock; import SoundRecorder.trigger.RecorderTrigger; @@ -443,7 +444,7 @@ public class RecorderSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("channelBitmap"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/SoundRecorder/trigger/RecorderTriggerData.java b/src/SoundRecorder/trigger/RecorderTriggerData.java index 2192afc9..9b0cb32c 100644 --- a/src/SoundRecorder/trigger/RecorderTriggerData.java +++ b/src/SoundRecorder/trigger/RecorderTriggerData.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Information for triggered recordings to tell each recorder how long @@ -271,7 +272,7 @@ public class RecorderTriggerData implements Serializable, Cloneable, ManagedPara */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("lastTriggerStart"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/Spectrogram/SpectrogramDisplay.java b/src/Spectrogram/SpectrogramDisplay.java index dd2536d6..0f90919d 100644 --- a/src/Spectrogram/SpectrogramDisplay.java +++ b/src/Spectrogram/SpectrogramDisplay.java @@ -1642,6 +1642,9 @@ InternalFrameListener, DisplayPanelContainer, SpectrogramParametersUser, PamSett return; } long t1 = dataUnit.getTimeMilliseconds()-viewerScroller.getValueMillis(); + if (timeAxis == null) { + return; + } int x1 = (int) Math.floor(timeAxis.getPosition(t1/1000)); int x2 = x1; if (dataUnit.getDurationInMilliseconds() != null) { diff --git a/src/alarm/AlarmParameters.java b/src/alarm/AlarmParameters.java index df89b940..0694adfc 100644 --- a/src/alarm/AlarmParameters.java +++ b/src/alarm/AlarmParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class AlarmParameters implements Serializable, Cloneable, ManagedParameters { @@ -103,7 +104,7 @@ public class AlarmParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("hadHold"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/alarm/actions/email/SendEmailSettings.java b/src/alarm/actions/email/SendEmailSettings.java index dcd4dc0b..da558c85 100644 --- a/src/alarm/actions/email/SendEmailSettings.java +++ b/src/alarm/actions/email/SendEmailSettings.java @@ -28,6 +28,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import alarm.actions.serial.AlarmSerialSettings; /** @@ -158,7 +159,7 @@ public class SendEmailSettings implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/alarm/actions/serial/AlarmSerialSettings.java b/src/alarm/actions/serial/AlarmSerialSettings.java index b14e785c..801cc765 100644 --- a/src/alarm/actions/serial/AlarmSerialSettings.java +++ b/src/alarm/actions/serial/AlarmSerialSettings.java @@ -8,6 +8,7 @@ import com.fazecast.jSerialComm.SerialPort; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import serialComms.SerialPortConstants; import serialComms.jserialcomm.PJSerialComm; @@ -68,7 +69,7 @@ public class AlarmSerialSettings implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/alarm/actions/sound/PlaySoundParams.java b/src/alarm/actions/sound/PlaySoundParams.java index c9f97970..6481e41d 100644 --- a/src/alarm/actions/sound/PlaySoundParams.java +++ b/src/alarm/actions/sound/PlaySoundParams.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import alarm.AlarmParameters; public class PlaySoundParams implements Cloneable, Serializable, ManagedParameters { @@ -33,7 +34,7 @@ public class PlaySoundParams implements Cloneable, Serializable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/alarm/actions/udp/AlarmUDPParams.java b/src/alarm/actions/udp/AlarmUDPParams.java index 10728bb2..7a7bfa61 100644 --- a/src/alarm/actions/udp/AlarmUDPParams.java +++ b/src/alarm/actions/udp/AlarmUDPParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AlarmUDPParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class AlarmUDPParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/amplifier/AmpParameters.java b/src/amplifier/AmpParameters.java index 98e52a63..89aac38c 100644 --- a/src/amplifier/AmpParameters.java +++ b/src/amplifier/AmpParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamConstants; @@ -41,7 +42,7 @@ public class AmpParameters implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("rawDataSource"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/analogarraysensor/ArraySensorLogging.java b/src/analogarraysensor/ArraySensorLogging.java index e4eba2e9..ca13752a 100644 --- a/src/analogarraysensor/ArraySensorLogging.java +++ b/src/analogarraysensor/ArraySensorLogging.java @@ -56,7 +56,8 @@ public class ArraySensorLogging extends SQLLogging { AnalogSensorData aData = new AnalogSensorData(rawValue, calValue); sensorData[i] = aData; } - int chanMap = getTableDefinition().getChannelBitmap().getIntegerValue(); + PamTableDefinition pamTableDef = (PamTableDefinition) getTableDefinition(); + int chanMap = pamTableDef.getChannelBitmap().getIntegerValue(); int streamer = PamUtils.getSingleChannel(chanMap); if (streamer < 0) streamer = 0; AnalogArraySensorDataUnit asdu = new AnalogArraySensorDataUnit(timeMilliseconds, streamer, sensorData); diff --git a/src/analogarraysensor/ArraySensorParams.java b/src/analogarraysensor/ArraySensorParams.java index c59d31eb..b84081a6 100644 --- a/src/analogarraysensor/ArraySensorParams.java +++ b/src/analogarraysensor/ArraySensorParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import Array.sensors.ArrayDisplayParameters; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ArraySensorParams implements Serializable, Cloneable, ManagedParameters { @@ -47,7 +48,7 @@ public class ArraySensorParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/analoginput/AnalogDeviceParams.java b/src/analoginput/AnalogDeviceParams.java index 1b43c7b9..cae97232 100644 --- a/src/analoginput/AnalogDeviceParams.java +++ b/src/analoginput/AnalogDeviceParams.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import analoginput.calibration.CalibrationData; @@ -63,7 +64,7 @@ public class AnalogDeviceParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("calibrationTable"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/analoginput/AnalogInputParams.java b/src/analoginput/AnalogInputParams.java index acd041e4..a64d51ba 100644 --- a/src/analoginput/AnalogInputParams.java +++ b/src/analoginput/AnalogInputParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AnalogInputParams implements Serializable, Cloneable, ManagedParameters { @@ -13,7 +14,7 @@ public class AnalogInputParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/analoginput/AnalogRangeData.java b/src/analoginput/AnalogRangeData.java index 00043994..7a7d7109 100644 --- a/src/analoginput/AnalogRangeData.java +++ b/src/analoginput/AnalogRangeData.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AnalogRangeData implements Serializable, Cloneable, Comparable, ManagedParameters { @@ -119,7 +120,7 @@ public class AnalogRangeData implements Serializable, Cloneable, Comparable 0) { diff --git a/src/annotation/timestamp/TimestampSQLLogging.java b/src/annotation/timestamp/TimestampSQLLogging.java index fd1d7be6..2f6b0728 100644 --- a/src/annotation/timestamp/TimestampSQLLogging.java +++ b/src/annotation/timestamp/TimestampSQLLogging.java @@ -3,6 +3,7 @@ package annotation.timestamp; import java.sql.Types; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -22,12 +23,12 @@ public class TimestampSQLLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(timestamp); } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { TimestampAnnotation timestampAnnotation = (TimestampAnnotation) pamDataUnit.findDataAnnotation(TimestampAnnotation.class, timestampAnnotationType.getAnnotationName()); if (timestampAnnotation == null) { @@ -40,7 +41,7 @@ public class TimestampSQLLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { try { TimestampAnnotation timestampAnnotation = new TimestampAnnotation(timestampAnnotationType); Long note = sqlTypes.millisFromTimeStamp(timestamp.getValue()); diff --git a/src/annotation/userforms/UserFormSQLAddon.java b/src/annotation/userforms/UserFormSQLAddon.java index fb5a20f0..8156bfda 100644 --- a/src/annotation/userforms/UserFormSQLAddon.java +++ b/src/annotation/userforms/UserFormSQLAddon.java @@ -3,6 +3,7 @@ package annotation.userforms; import java.util.ArrayList; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -32,7 +33,7 @@ public class UserFormSQLAddon implements SQLLoggingAddon { @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { loggerTableItems.clear(); FormDescription formDescription = userFormAnnotationType.findFormDescription(); if (formDescription == null) { @@ -58,7 +59,7 @@ public class UserFormSQLAddon implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { if (pamDataUnit == null) { clearTableItems(); return false; @@ -103,7 +104,7 @@ public class UserFormSQLAddon implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { FormDescription formDescription = userFormAnnotationType.findFormDescription(); if (formDescription == null) { return false; diff --git a/src/annotationMark/spectrogram/SpectrogramMarkParams.java b/src/annotationMark/spectrogram/SpectrogramMarkParams.java index 0d65e6e4..89540c01 100644 --- a/src/annotationMark/spectrogram/SpectrogramMarkParams.java +++ b/src/annotationMark/spectrogram/SpectrogramMarkParams.java @@ -5,6 +5,7 @@ import java.util.List; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import annotation.DataAnnotationType; import annotation.handler.AnnotationChoices; @@ -31,7 +32,7 @@ public class SpectrogramMarkParams implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/backupmanager/FileLocation.java b/src/backupmanager/FileLocation.java index 1508125a..6557821d 100644 --- a/src/backupmanager/FileLocation.java +++ b/src/backupmanager/FileLocation.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Information on a file path or folder path that can be used with the @@ -42,7 +43,7 @@ public class FileLocation implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/backupmanager/settings/BackupSettings.java b/src/backupmanager/settings/BackupSettings.java index 71b90fda..bc9ac14c 100644 --- a/src/backupmanager/settings/BackupSettings.java +++ b/src/backupmanager/settings/BackupSettings.java @@ -6,6 +6,7 @@ import java.util.List; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public abstract class BackupSettings implements Serializable, Cloneable, ManagedParameters { @@ -40,7 +41,7 @@ public abstract class BackupSettings implements Serializable, Cloneable, Managed @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/beamformer/BeamAlgorithmParams.java b/src/beamformer/BeamAlgorithmParams.java index 7cde91b4..eabdb943 100644 --- a/src/beamformer/BeamAlgorithmParams.java +++ b/src/beamformer/BeamAlgorithmParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import beamformer.algorithms.basicFreqDomain.BasicFreqDomParams; /* @@ -336,7 +337,7 @@ public abstract class BeamAlgorithmParams implements Serializable, Cloneable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/beamformer/BeamFormerParams.java b/src/beamformer/BeamFormerParams.java index f5cc3f5d..d6082a1d 100644 --- a/src/beamformer/BeamFormerParams.java +++ b/src/beamformer/BeamFormerParams.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.HashMap; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.DeepCloner; import PamView.GroupedSourceParameters; @@ -325,7 +326,7 @@ public class BeamFormerParams implements Cloneable, Serializable, ManagedParamet */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("algorithmParamsTable"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/beamformer/annotation/BFAnnotationLogging.java b/src/beamformer/annotation/BFAnnotationLogging.java index 83d7641a..ba9bed54 100644 --- a/src/beamformer/annotation/BFAnnotationLogging.java +++ b/src/beamformer/annotation/BFAnnotationLogging.java @@ -6,6 +6,7 @@ import PamDetection.LocContents; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import beamformer.loc.BeamFormerLocalisation; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -29,7 +30,7 @@ public class BFAnnotationLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(bfPhones); pamTableDefinition.addTableItem(bfArrayType); pamTableDefinition.addTableItem(bfContents); @@ -38,7 +39,7 @@ public class BFAnnotationLogging implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { bfPhones.setValue(null); bfArrayType.setValue(null); bfContents.setValue(null); @@ -64,7 +65,7 @@ public class BFAnnotationLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { Float[] Angles = new Float[2]; for (int i = 0; i < 2; i++) { Angles[i] = (Float) angle[i].getFloatValue(); diff --git a/src/bearinglocaliser/BearingLocaliserParams.java b/src/bearinglocaliser/BearingLocaliserParams.java index 277c8e5d..d697781c 100644 --- a/src/bearinglocaliser/BearingLocaliserParams.java +++ b/src/bearinglocaliser/BearingLocaliserParams.java @@ -8,6 +8,7 @@ import java.util.HashMap; import Localiser.controls.RawOrFFTParamsInterface; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.GroupedSourceParameters; import bearinglocaliser.algorithms.BearingAlgorithmParams; @@ -188,7 +189,7 @@ public class BearingLocaliserParams implements Serializable, Cloneable, RawOrFFT @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("algorithmParamsTable"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java b/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java index 3b6c0bed..cea3e25f 100644 --- a/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java +++ b/src/bearinglocaliser/algorithms/BearingAlgorithmParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class BearingAlgorithmParams implements Serializable, Cloneable, ManagedParameters { @@ -60,7 +61,7 @@ public class BearingAlgorithmParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/bearinglocaliser/annotation/BearingAnnotationSQL.java b/src/bearinglocaliser/annotation/BearingAnnotationSQL.java index bc4b88bb..d56e8be7 100644 --- a/src/bearinglocaliser/annotation/BearingAnnotationSQL.java +++ b/src/bearinglocaliser/annotation/BearingAnnotationSQL.java @@ -4,6 +4,7 @@ import java.sql.Types; import PamguardMVC.PamDataUnit; import bearinglocaliser.BearingLocalisation; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -34,7 +35,7 @@ public class BearingAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(algoName); pamTableDefinition.addTableItem(bfPhones); pamTableDefinition.addTableItem(bfArrayType); @@ -48,7 +49,7 @@ public class BearingAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { algoName.setValue(null); bfPhones.setValue(null); bfArrayType.setValue(null); @@ -96,7 +97,7 @@ public class BearingAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { Float[] Angles = new Float[2]; int nNans = 0; for (int i = 0; i < 2; i++) { diff --git a/src/binaryFileStorage/BinaryFooter.java b/src/binaryFileStorage/BinaryFooter.java index 98142a16..f410998b 100644 --- a/src/binaryFileStorage/BinaryFooter.java +++ b/src/binaryFileStorage/BinaryFooter.java @@ -7,6 +7,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; public class BinaryFooter implements Serializable, ManagedParameters { @@ -230,7 +231,7 @@ public class BinaryFooter implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/binaryFileStorage/BinaryHeader.java b/src/binaryFileStorage/BinaryHeader.java index b27652ec..b1d7a986 100644 --- a/src/binaryFileStorage/BinaryHeader.java +++ b/src/binaryFileStorage/BinaryHeader.java @@ -9,6 +9,7 @@ import java.lang.reflect.Field; import PamController.PamguardVersionInfo; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.PamCalendar; @@ -289,7 +290,7 @@ public class BinaryHeader implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("pamguard"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/binaryFileStorage/BinarySettingsStorage.java b/src/binaryFileStorage/BinarySettingsStorage.java index 48278c1d..c59992d8 100644 --- a/src/binaryFileStorage/BinarySettingsStorage.java +++ b/src/binaryFileStorage/BinarySettingsStorage.java @@ -110,6 +110,12 @@ public class BinarySettingsStorage implements PamSettingsSource { return false;*/ } + @Override + public boolean saveEndSettings(long timeNow) { + // do nothing at the end of a run with binary store. + return true; + } + // private boolean writeData(DataOutputStream dos, int objectId, byte[] data) { // int totalLen = data.length + 16; // int dataLen = data.length; diff --git a/src/binaryFileStorage/BinaryStore.java b/src/binaryFileStorage/BinaryStore.java index 4369c0f7..39dbb8b4 100644 --- a/src/binaryFileStorage/BinaryStore.java +++ b/src/binaryFileStorage/BinaryStore.java @@ -540,6 +540,12 @@ PamSettingsSource, DataOutputStore { return binarySettingsStorage.saveStartSettings(timeNow); } + @Override + public boolean saveEndSettings(long timeNow) { + // TODO Auto-generated method stub + return false; + } + @Override public int getNumSettings() { if (binarySettingsStorage == null) { @@ -2547,5 +2553,9 @@ PamSettingsSource, DataOutputStore { BinaryStoreDeleter storeDeleter = new BinaryStoreDeleter(this); return storeDeleter.deleteDataFrom(timeMillis); } + @Override + public String getDataLocation() { + return binaryStoreSettings.getStoreLocation(); + } } diff --git a/src/binaryFileStorage/BinaryStoreSettings.java b/src/binaryFileStorage/BinaryStoreSettings.java index 441baddd..78c42e99 100644 --- a/src/binaryFileStorage/BinaryStoreSettings.java +++ b/src/binaryFileStorage/BinaryStoreSettings.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamController.PamFolders; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class BinaryStoreSettings implements Serializable, Cloneable, ManagedParameters { @@ -90,7 +91,7 @@ public class BinaryStoreSettings implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/cepstrum/CepstrumParams.java b/src/cepstrum/CepstrumParams.java index a24fab3a..59f6fbb9 100644 --- a/src/cepstrum/CepstrumParams.java +++ b/src/cepstrum/CepstrumParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class CepstrumParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class CepstrumParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/clickDetector/BTDisplayParameters.java b/src/clickDetector/BTDisplayParameters.java index 143b3eab..bf9604f7 100644 --- a/src/clickDetector/BTDisplayParameters.java +++ b/src/clickDetector/BTDisplayParameters.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import clickDetector.tdPlots.ClickSymbolOptions; @@ -137,7 +138,7 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("showSpeciesList"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/BasicClickIdParameters.java b/src/clickDetector/BasicClickIdParameters.java index feeefb67..6cc5925c 100644 --- a/src/clickDetector/BasicClickIdParameters.java +++ b/src/clickDetector/BasicClickIdParameters.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; @@ -83,7 +84,7 @@ public class BasicClickIdParameters implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/ClickAlarm.java b/src/clickDetector/ClickAlarm.java index f9459296..515945ab 100644 --- a/src/clickDetector/ClickAlarm.java +++ b/src/clickDetector/ClickAlarm.java @@ -33,6 +33,7 @@ import javax.sound.sampled.Clip; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -209,7 +210,7 @@ public class ClickAlarm implements Comparable, Serializable, Cloneab @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fileIsLoaded"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickBinaryModuleFooter.java b/src/clickDetector/ClickBinaryModuleFooter.java index 35718e17..f24ed53c 100644 --- a/src/clickDetector/ClickBinaryModuleFooter.java +++ b/src/clickDetector/ClickBinaryModuleFooter.java @@ -12,6 +12,7 @@ import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; import binaryFileStorage.ModuleFooter; @@ -128,7 +129,7 @@ public class ClickBinaryModuleFooter extends ModuleFooter implements ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("clickDetectorName"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickBinaryModuleHeader.java b/src/clickDetector/ClickBinaryModuleHeader.java index 1cb7f8d8..f36f7854 100644 --- a/src/clickDetector/ClickBinaryModuleHeader.java +++ b/src/clickDetector/ClickBinaryModuleHeader.java @@ -2,6 +2,7 @@ package clickDetector; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; import binaryFileStorage.ModuleHeader; @@ -28,7 +29,7 @@ public class ClickBinaryModuleHeader extends ModuleHeader implements ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/clickDetector/ClickClassifiers/ClickBlockSpeciesManager.java b/src/clickDetector/ClickClassifiers/ClickBlockSpeciesManager.java new file mode 100644 index 00000000..89812008 --- /dev/null +++ b/src/clickDetector/ClickClassifiers/ClickBlockSpeciesManager.java @@ -0,0 +1,52 @@ +package clickDetector.ClickClassifiers; + +import clickDetector.ClickControl; +import clickDetector.ClickDataBlock; +import clickDetector.ClickDetection; +import tethys.species.DataBlockSpeciesManager; +import tethys.species.DataBlockSpeciesCodes; +import tethys.species.ITISTypes; +import tethys.species.SpeciesMapItem; + +public class ClickBlockSpeciesManager extends DataBlockSpeciesManager { + + private ClickControl clickControl; + + public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) { + super(clickDataBlock); + this.clickControl = clickControl; + setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.UNKNOWN, "Unknown", "Unknown")); + setDefaultSpeciesCode("Unknown"); + } + + @Override + public DataBlockSpeciesCodes getSpeciesCodes() { + ClickTypeMasterManager masterManager = clickControl.getClickTypeMasterManager(); + if (masterManager == null) { + return null; + } + String[] speciesList = masterManager.getSpeciesList(); + // add the default + String[] fullList = new String[speciesList.length+1]; + fullList[0] = getDefaultSpeciesCode(); + for (int i = 0; i < speciesList.length; i++) { + fullList[i+1] = speciesList[i]; + } + + return new DataBlockSpeciesCodes("Click", fullList); + } + + @Override + public String getSpeciesCode(ClickDetection dataUnit) { + ClickTypeMasterManager masterManager = clickControl.getClickTypeMasterManager(); + if (masterManager == null) { + return null; + } + int listIndex = masterManager.codeToListIndex(dataUnit.getClickType()); + if (listIndex < 0) { + return null; + } + return masterManager.getSpeciesList()[listIndex]; + } + +} diff --git a/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java b/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java index d937b164..78b56316 100644 --- a/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java +++ b/src/clickDetector/ClickClassifiers/ClickTypeCommonParams.java @@ -28,6 +28,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Superclass for click parameters, including the ClickTypeParms and @@ -191,7 +192,7 @@ abstract public class ClickTypeCommonParams implements Cloneable, Serializable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java b/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java index baa057ac..840d2086 100644 --- a/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java +++ b/src/clickDetector/ClickClassifiers/annotation/ClickAnnotationSQL.java @@ -3,6 +3,7 @@ package clickDetector.ClickClassifiers.annotation; import java.sql.Types; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -33,12 +34,12 @@ public class ClickAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(classifierSetTable); } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { ClickClassifierAnnotation clickAnnotation = (ClickClassifierAnnotation) pamDataUnit.findDataAnnotation(ClickClassificationType.class); //create a comma delimited string @@ -53,7 +54,7 @@ public class ClickAnnotationSQL implements SQLLoggingAddon { @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { String array = classifierSetTable.getDeblankedStringValue(); //read in the classification set. This a list of all the classifiers the clicks passed. diff --git a/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java b/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java index 9c925607..6cc4f1b5 100644 --- a/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java +++ b/src/clickDetector/ClickClassifiers/basicSweep/SweepClassifierParameters.java @@ -7,6 +7,7 @@ import java.util.Vector; import PamModel.SMRUEnable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class SweepClassifierParameters implements Serializable, Cloneable, ManagedParameters { @@ -72,7 +73,7 @@ public class SweepClassifierParameters implements Serializable, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("classifierSets"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickDataBlock.java b/src/clickDetector/ClickDataBlock.java index 3e650b85..5536aa79 100644 --- a/src/clickDetector/ClickDataBlock.java +++ b/src/clickDetector/ClickDataBlock.java @@ -3,6 +3,9 @@ package clickDetector; import java.util.ListIterator; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; //import staticLocaliser.StaticLocaliserControl; //import staticLocaliser.StaticLocaliserProvider; //import staticLocaliser.panels.AbstractLocaliserControl; @@ -10,8 +13,10 @@ import pamScrollSystem.ViewLoadObserver; import alarm.AlarmCounterProvider; import alarm.AlarmDataSource; import binaryFileStorage.BinaryStore; +import clickDetector.ClickClassifiers.ClickBlockSpeciesManager; import clickDetector.dataSelector.ClickDataSelectCreator; import clickDetector.offlineFuncs.OfflineClickLogging; +import clickDetector.tethys.ClickTethysDataProvider; import clickDetector.toad.ClickTOADCalculator; import dataMap.OfflineDataMap; import fftManager.fftorganiser.FFTDataOrganiser; @@ -24,6 +29,8 @@ import PamUtils.PamUtils; import PamView.GroupedDataSource; import PamView.GroupedSourceParameters; import PamguardMVC.AcousticDataBlock; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.FFTDataHolderBlock; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; @@ -41,6 +48,8 @@ public class ClickDataBlock extends AcousticDataBlock implement private boolean isViewer; + private ClickBlockSpeciesManager clickBlockSpeciesManager; + public ClickDataBlock(ClickControl clickControl, PamProcess parentProcess, int channelMap) { @@ -65,6 +74,8 @@ public class ClickDataBlock extends AcousticDataBlock implement private ClickTOADCalculator clickTOADCalculator; + private ClickTethysDataProvider clickTethysDataProvider; + /** * Click detector loading has to be a bit different to normal - first * data are loaded from the binary store, then a subset of these data @@ -304,5 +315,26 @@ public class ClickDataBlock extends AcousticDataBlock implement } } + @Override + public DataBlockSpeciesManager getDatablockSpeciesManager() { + if (clickBlockSpeciesManager == null) { + clickBlockSpeciesManager = new ClickBlockSpeciesManager(clickControl, this); + } + return clickBlockSpeciesManager; + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (clickTethysDataProvider == null) { + clickTethysDataProvider = new ClickTethysDataProvider(tethysControl, this); + } + return clickTethysDataProvider; + } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.AUTOMATIC); + } + } diff --git a/src/clickDetector/ClickDisplayManager.java b/src/clickDetector/ClickDisplayManager.java index f46aeca8..f992ef2d 100644 --- a/src/clickDetector/ClickDisplayManager.java +++ b/src/clickDetector/ClickDisplayManager.java @@ -28,6 +28,7 @@ import PamController.PamSettingManager; import PamController.PamSettings; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.MenuItemEnabler; @@ -302,7 +303,7 @@ public class ClickDisplayManager implements PamSettings { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("className"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickDisplayManagerParameters2.java b/src/clickDetector/ClickDisplayManagerParameters2.java index 86ccbca6..d8fd18cf 100644 --- a/src/clickDetector/ClickDisplayManagerParameters2.java +++ b/src/clickDetector/ClickDisplayManagerParameters2.java @@ -9,6 +9,7 @@ import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ClickDisplayManagerParameters2 implements Cloneable, Serializable, ManagedParameters { @@ -181,7 +182,7 @@ public class ClickDisplayManagerParameters2 implements Cloneable, Serializable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("initialised"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ClickParameters.java b/src/clickDetector/ClickParameters.java index 3146b0e4..118eaf21 100644 --- a/src/clickDetector/ClickParameters.java +++ b/src/clickDetector/ClickParameters.java @@ -38,6 +38,7 @@ import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.GroupedSourceParameters; import PamView.dialog.GroupedSourcePanel; import PamView.paneloverlay.overlaymark.MarkDataSelectorParams; @@ -441,7 +442,7 @@ public class ClickParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { PamParameterData param = ps.findParameterData("dbThreshold"); param.setShortName("Detection Threshold"); diff --git a/src/clickDetector/ClickSpectrumParams.java b/src/clickDetector/ClickSpectrumParams.java index 6784c9fa..d18927e3 100644 --- a/src/clickDetector/ClickSpectrumParams.java +++ b/src/clickDetector/ClickSpectrumParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ClickSpectrumParams implements Serializable, Cloneable, ManagedParameters { @@ -38,7 +39,7 @@ public class ClickSpectrumParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/clickDetector/ClickSpectrumTemplateParams.java b/src/clickDetector/ClickSpectrumTemplateParams.java index ff156b0e..caad2b6e 100644 --- a/src/clickDetector/ClickSpectrumTemplateParams.java +++ b/src/clickDetector/ClickSpectrumTemplateParams.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; @@ -39,7 +40,7 @@ public class ClickSpectrumTemplateParams implements Serializable, Cloneable, Man @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("clickTemplateArray"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/ConcatenatedSpectParams.java b/src/clickDetector/ConcatenatedSpectParams.java index 6bf67108..db3f6a0b 100644 --- a/src/clickDetector/ConcatenatedSpectParams.java +++ b/src/clickDetector/ConcatenatedSpectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.ColourArray.ColourArrayType; public class ConcatenatedSpectParams implements Serializable, Cloneable, ManagedParameters { @@ -44,7 +45,7 @@ public class ConcatenatedSpectParams implements Serializable, Cloneable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/clickDetector/IDI_DisplayParams.java b/src/clickDetector/IDI_DisplayParams.java index 0198fe92..e7641768 100644 --- a/src/clickDetector/IDI_DisplayParams.java +++ b/src/clickDetector/IDI_DisplayParams.java @@ -29,6 +29,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -270,7 +271,7 @@ public class IDI_DisplayParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("saveOutput"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/TrackedClickGroupLogging.java b/src/clickDetector/TrackedClickGroupLogging.java index 6016f704..90e7af9a 100644 --- a/src/clickDetector/TrackedClickGroupLogging.java +++ b/src/clickDetector/TrackedClickGroupLogging.java @@ -1,5 +1,6 @@ package clickDetector; +import generalDatabase.PamTableDefinition; import generalDatabase.SQLTypes; import PamguardMVC.PamDataUnit; import clickDetector.offlineFuncs.OfflineEventDataUnit; @@ -30,7 +31,8 @@ public class TrackedClickGroupLogging extends ClickGroupLogging { boolean isUpdate = true; // Timestamp ts = (Timestamp) getTableDefinition().getTimeStampItem().getValue(); // long t = PamCalendar.millisFromTimeStamp(ts); - int updateIndex = (Integer) getTableDefinition().getUpdateReference().getValue(); + PamTableDefinition tableDef = (PamTableDefinition) getTableDefinition(); + int updateIndex = (Integer) tableDef.getUpdateReference().getValue(); if (updateIndex > 0) { tcg = this.clickGroupDataBlock.findByDatabaseIndex(updateIndex); } diff --git a/src/clickDetector/WignerPlotOptions.java b/src/clickDetector/WignerPlotOptions.java index 0ef46f2e..e05640a6 100644 --- a/src/clickDetector/WignerPlotOptions.java +++ b/src/clickDetector/WignerPlotOptions.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class WignerPlotOptions implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class WignerPlotOptions implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/clickDetector/alarm/ClickAlarmParameters.java b/src/clickDetector/alarm/ClickAlarmParameters.java index 3cc714b2..8bed53c6 100644 --- a/src/clickDetector/alarm/ClickAlarmParameters.java +++ b/src/clickDetector/alarm/ClickAlarmParameters.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.dataSelector.DataSelectParams; @@ -127,7 +128,7 @@ public class ClickAlarmParameters extends DataSelectParams implements Cloneable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("eventTypes"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/clicktrains/ClickTrainIdParams.java b/src/clickDetector/clicktrains/ClickTrainIdParams.java index 9f9b03c2..c6d4746f 100644 --- a/src/clickDetector/clicktrains/ClickTrainIdParams.java +++ b/src/clickDetector/clicktrains/ClickTrainIdParams.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -59,7 +60,7 @@ public class ClickTrainIdParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("dataVersion"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java b/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java index 668fec3e..a8cc198c 100644 --- a/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java +++ b/src/clickDetector/dataSelector/ClickTrainDataSelect2Params.java @@ -8,6 +8,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.dataSelector.DataSelectParams; @@ -91,7 +92,7 @@ public class ClickTrainDataSelect2Params extends DataSelectParams implements Clo @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("wantType"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/dataSelector/ClickTrainDataSelector2.java b/src/clickDetector/dataSelector/ClickTrainDataSelector2.java index 0520b4fb..9bde5123 100644 --- a/src/clickDetector/dataSelector/ClickTrainDataSelector2.java +++ b/src/clickDetector/dataSelector/ClickTrainDataSelector2.java @@ -82,7 +82,7 @@ public class ClickTrainDataSelector2 extends DataSelector { } SQLLogging logging = getPamDataBlock().getLogging(); if (logging == null) return null; //cannot happen! - PamTableDefinition tableDef = logging.getTableDefinition(); + EmptyTableDefinition tableDef = logging.getTableDefinition(); if (params.isIncludeUnclassified()) { return null; } diff --git a/src/clickDetector/dataSelector/ClickTrainSelectParameters.java b/src/clickDetector/dataSelector/ClickTrainSelectParameters.java index 3cfc5189..75462778 100644 --- a/src/clickDetector/dataSelector/ClickTrainSelectParameters.java +++ b/src/clickDetector/dataSelector/ClickTrainSelectParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; import clickDetector.ClickParameters; @@ -32,7 +33,7 @@ public class ClickTrainSelectParameters extends DataSelectParams implements Seri @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/echoDetection/JamieEchoParams.java b/src/clickDetector/echoDetection/JamieEchoParams.java index ec00df42..e3cbadb5 100644 --- a/src/clickDetector/echoDetection/JamieEchoParams.java +++ b/src/clickDetector/echoDetection/JamieEchoParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class JamieEchoParams implements Serializable, Cloneable, ManagedParameters { @@ -31,7 +32,7 @@ public static final long serialVersionUID = 3L; @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/echoDetection/SimpleEchoParams.java b/src/clickDetector/echoDetection/SimpleEchoParams.java index fe5eae8e..eb6095a1 100644 --- a/src/clickDetector/echoDetection/SimpleEchoParams.java +++ b/src/clickDetector/echoDetection/SimpleEchoParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SimpleEchoParams implements Serializable, Cloneable, ManagedParameters { @@ -26,7 +27,7 @@ public class SimpleEchoParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java index e11aec29..a86f27f5 100644 --- a/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java +++ b/src/clickDetector/layoutFX/clickClassifiers/SweepClassifierSetPaneFX.java @@ -1628,8 +1628,6 @@ public class SweepClassifierSetPaneFX extends SettingsPane { p.setLayout(new GridBagLayout()); GridBagConstraints c = new PamGridBagContraints(); - - // c.gridx = 0; // addComponent(p, enableBearings, c); // c.gridx += c.gridwidth; @@ -1736,7 +1734,6 @@ public class SweepClassifierSetPaneFX extends SettingsPane { // } // } // } -// else multiChan = true; // Debug.out.println("Check multi-channel: " + multiChan); return multiChan; diff --git a/src/clickDetector/localisation/ClickLocParams.java b/src/clickDetector/localisation/ClickLocParams.java index fcfaaff6..6a597258 100644 --- a/src/clickDetector/localisation/ClickLocParams.java +++ b/src/clickDetector/localisation/ClickLocParams.java @@ -7,6 +7,7 @@ import java.util.Arrays; import Localiser.detectionGroupLocaliser.DetectionGroupOptions; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class ClickLocParams implements Serializable, Cloneable, DetectionGroupOptions, ManagedParameters { @@ -110,7 +111,7 @@ public class ClickLocParams implements Serializable, Cloneable, DetectionGroupOp @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("internalVersion"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clickDetector/offlineFuncs/DatabaseChecks.java b/src/clickDetector/offlineFuncs/DatabaseChecks.java index 38bfe6a5..585bbf50 100644 --- a/src/clickDetector/offlineFuncs/DatabaseChecks.java +++ b/src/clickDetector/offlineFuncs/DatabaseChecks.java @@ -102,16 +102,17 @@ public class DatabaseChecks { long resultTime; long firstTime = Long.MAX_VALUE; long lastTime = Long.MIN_VALUE; + PamTableDefinition pamTableDef = (PamTableDefinition) clickLogging.getTableDefinition(); try { Statement stmt = con.getConnection().createStatement(); ResultSet result = stmt.executeQuery(sqlStr); while (result.next()) { nClicks++; clickLogging.transferDataFromResult(sqlTypes, result); - ts = clickLogging.getTableDefinition().getTimeStampItem().getValue(); + ts = pamTableDef.getTimeStampItem().getValue(); resultTime = sqlTypes.millisFromTimeStamp(ts); if (resultTime%1000 == 0) { - resultTime += clickLogging.getTableDefinition().getTimeStampMillis().getIntegerValue(); + resultTime += pamTableDef.getTimeStampMillis().getIntegerValue(); } firstTime = Math.min(firstTime, resultTime); lastTime = Math.max(lastTime, resultTime); @@ -188,7 +189,7 @@ public class DatabaseChecks { eventDataBlock.addPamData(event); PamConnection con = DBControlUnit.findConnection(); // now find a cursor and save it. - PamTableDefinition eventTableDef = eventDataBlock.getLogging().getTableDefinition(); + PamTableDefinition eventTableDef = (PamTableDefinition) eventDataBlock.getLogging().getTableDefinition(); PamCursor cursor = eventDataBlock.getLogging().getViewerCursorFinder().getCursor(con, eventTableDef); cursor.immediateInsert(con); int newId = event.getDatabaseIndex(); diff --git a/src/clickDetector/offlineFuncs/OfflineClickLogging.java b/src/clickDetector/offlineFuncs/OfflineClickLogging.java index a75897f7..4b4360dc 100644 --- a/src/clickDetector/offlineFuncs/OfflineClickLogging.java +++ b/src/clickDetector/offlineFuncs/OfflineClickLogging.java @@ -277,13 +277,14 @@ public class OfflineClickLogging extends SQLLogging { Integer millis; Object ts; SQLTypes sqlTypes = dbControl.getConnection().getSqlTypes(); + PamTableDefinition tableDef = (PamTableDefinition) getTableDefinition(); try { while (resultSet.next()) { transferDataFromResult(sqlTypes, resultSet); - ts = getTableDefinition().getTimeStampItem().getValue(); + ts = tableDef.getTimeStampItem().getValue(); long m = SQLTypes.millisFromTimeStamp(ts); if (m%1000 == 0) { - millis = (Integer) getTableDefinition().getTimeStampMillis().getValue(); + millis = (Integer) tableDef.getTimeStampMillis().getValue(); if (millis != null) { m += millis; } diff --git a/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java b/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java index 4af5872b..afc60ec7 100644 --- a/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java +++ b/src/clickDetector/offlineFuncs/OfflineEventDataBlock.java @@ -16,6 +16,10 @@ import PamController.PamViewParameters; import PamUtils.PamCalendar; import PamView.symbol.StandardSymbolManager; import pamScrollSystem.ViewLoadObserver; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; +import clickDetector.ClickDetection; //import staticLocaliser.StaticLocaliserControl; //import staticLocaliser.StaticLocaliserProvider; //import staticLocaliser.panels.AbstractLocaliserControl; @@ -23,7 +27,12 @@ import pamScrollSystem.ViewLoadObserver; import clickDetector.ClickDetector; import clickDetector.ClickTrainDetection; import clickDetector.dataSelector.ClickTrainDataSelectorCreator; +import clickDetector.tethys.ClickEventSpeciesManager; +import clickDetector.tethys.ClickEventTethysDataProvider; +import clickDetector.tethys.ClickTethysDataProvider; import dataMap.OfflineDataMap; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; import PamguardMVC.dataOffline.OfflineDataLoadInfo; @@ -49,6 +58,8 @@ public class OfflineEventDataBlock extends SuperDetDataBlock getDatablockSpeciesManager() { + if (eventSpeciesManager == null) { + eventSpeciesManager = new ClickEventSpeciesManager(clickDetector, this); + } + return eventSpeciesManager; + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (eventTethysDataProvider == null) { + eventTethysDataProvider = new ClickEventTethysDataProvider(tethysControl, this); + } + return eventTethysDataProvider; + } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.MANUALANDAUTOMATIC); + } + } diff --git a/src/clickDetector/offlineFuncs/OfflineParameters.java b/src/clickDetector/offlineFuncs/OfflineParameters.java index 2ab82962..0c4b2c71 100644 --- a/src/clickDetector/offlineFuncs/OfflineParameters.java +++ b/src/clickDetector/offlineFuncs/OfflineParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OfflineParameters implements Serializable, Cloneable, ManagedParameters { @@ -28,7 +29,7 @@ public class OfflineParameters implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java b/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java index d4fb6fb2..0b9b0996 100644 --- a/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java +++ b/src/clickDetector/offlineFuncs/rcImport/RainbowDatabseConverter.java @@ -148,7 +148,7 @@ public class RainbowDatabseConverter { ClickDataBlock clickDataBlock = clickControl.getClickDataBlock(); clickLogging = new ClickImportLogging(clickControl); - PamTableDefinition tableDef = clickLogging.getTableDefinition(); + PamTableDefinition tableDef = (PamTableDefinition) clickLogging.getTableDefinition(); boolean ok = checkTable(pamConnection, tableDef); if (!ok) { System.out.println("Error in Pamguard clicks table"); @@ -156,7 +156,7 @@ public class RainbowDatabseConverter { } eventLogging = new OfflineEventLogging(clickControl, clickControl.getClickDetector().getOfflineEventDataBlock()); - tableDef = eventLogging.getTableDefinition(); + tableDef = (PamTableDefinition) eventLogging.getTableDefinition(); ok = checkTable(pamConnection, tableDef); if (!ok) { System.out.println("Error in Pamguard events table"); diff --git a/src/clickDetector/tethys/ClickEventSpeciesManager.java b/src/clickDetector/tethys/ClickEventSpeciesManager.java new file mode 100644 index 00000000..c0ee92fd --- /dev/null +++ b/src/clickDetector/tethys/ClickEventSpeciesManager.java @@ -0,0 +1,57 @@ +package clickDetector.tethys; + +import java.util.Vector; + +import PamguardMVC.PamDataUnit; +import clickDetector.ClickControl; +import clickDetector.ClickDetector; +import clickDetector.offlineFuncs.ClicksOffline; +import clickDetector.offlineFuncs.OfflineEventDataBlock; +import clickDetector.offlineFuncs.OfflineEventDataUnit; +import generalDatabase.lookupTables.LookUpTables; +import generalDatabase.lookupTables.LookupItem; +import generalDatabase.lookupTables.LookupList; +import tethys.species.DataBlockSpeciesCodes; +import tethys.species.DataBlockSpeciesManager; + +public class ClickEventSpeciesManager extends DataBlockSpeciesManager { + + private OfflineEventDataBlock eventDataBlock; + private ClickDetector clickDetector; + private ClickControl clickControl; + private ClicksOffline clicksOffline; + + public ClickEventSpeciesManager(ClickDetector clickDetector, OfflineEventDataBlock eventDataBlock) { + super(eventDataBlock); + this.clickDetector = clickDetector; + this.eventDataBlock = eventDataBlock; + clickControl = clickDetector.getClickControl(); + clicksOffline = clickControl.getClicksOffline(); + } + + @Override + public DataBlockSpeciesCodes getSpeciesCodes() { + LookupList lutList = LookUpTables.getLookUpTables().getLookupList(ClicksOffline.ClickTypeLookupName); + if (lutList == null || lutList.getLutList().size() == 0) { + return new DataBlockSpeciesCodes("Unknown"); + } + Vector spList = lutList.getLutList(); + String[] spNames = new String[spList.size()]; + int i = 0; + for (LookupItem lItem : spList) { + spNames[i++] = lItem.getCode(); + } + return new DataBlockSpeciesCodes("Unknown", spNames); + } + + @Override + public String getSpeciesCode(PamDataUnit dataUnit) { + OfflineEventDataUnit eventDataUnit = (OfflineEventDataUnit) dataUnit; + String eventType = eventDataUnit.getEventType(); + if (eventType == null) { + eventType = "Unknown"; + } + return eventType; + } + +} diff --git a/src/clickDetector/tethys/ClickEventTethysDataProvider.java b/src/clickDetector/tethys/ClickEventTethysDataProvider.java new file mode 100644 index 00000000..bbc5d1fd --- /dev/null +++ b/src/clickDetector/tethys/ClickEventTethysDataProvider.java @@ -0,0 +1,72 @@ +package clickDetector.tethys; + +import java.math.BigInteger; + +import PamguardMVC.PamDataUnit; +import clickDetector.offlineFuncs.OfflineEventDataBlock; +import clickDetector.offlineFuncs.OfflineEventDataUnit; +import nilus.Detection; +import nilus.GranularityEnumType; +import nilus.Detection.Parameters; +import nilus.Detection.Parameters.UserDefined; +import tethys.TethysControl; +import tethys.output.StreamExportParams; +import tethys.output.TethysExportParams; +import tethys.pamdata.AutoTethysProvider; +import tethys.swing.export.ExportWizardCard; +import tethys.swing.export.GranularityCard; + +public class ClickEventTethysDataProvider extends AutoTethysProvider { + + private OfflineEventDataBlock eventDataBlock; + + public ClickEventTethysDataProvider(TethysControl tethysControl, OfflineEventDataBlock eventDataBlock) { + super(tethysControl, eventDataBlock); + this.eventDataBlock = eventDataBlock; + } + + @Override + public GranularityEnumType[] getAllowedGranularities() { + GranularityEnumType[] allowed = {GranularityEnumType.GROUPED}; + return allowed; + } + @Override + public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams, + StreamExportParams streamExportParams) { + Detection detection = super.createDetection(dataUnit, tethysExportParams, streamExportParams); + if (detection == null) { + return null; + } + OfflineEventDataUnit eventDataUnit = (OfflineEventDataUnit) dataUnit; + detection.setCount(BigInteger.valueOf(eventDataUnit.getSubDetectionsCount())); + String comment = eventDataUnit.getComment(); + if (comment != null && comment.length() > 0) { + detection.setComment(comment); + } + Parameters params = detection.getParameters(); + addUserNumber(params, "MinNumber", eventDataUnit.getMinNumber()); + addUserNumber(params, "BestNumber", eventDataUnit.getBestNumber()); + addUserNumber(params, "MaxNumber", eventDataUnit.getMaxNumber()); + + + return detection; + } + + private void addUserNumber(Parameters params, String numName, Short number) { + if (number == null) { + return; + } + addUserDefined(params, numName, number.toString()); + } + + @Override + public boolean wantExportDialogCard(ExportWizardCard wizPanel) { + if (wizPanel.getClass() == GranularityCard.class) { + return false; + } + else { + return true; + } + } + +} diff --git a/src/clickDetector/tethys/ClickTethysDataProvider.java b/src/clickDetector/tethys/ClickTethysDataProvider.java new file mode 100644 index 00000000..44e1c8c8 --- /dev/null +++ b/src/clickDetector/tethys/ClickTethysDataProvider.java @@ -0,0 +1,22 @@ +package clickDetector.tethys; + +import clickDetector.ClickDataBlock; +import nilus.GranularityEnumType; +import tethys.TethysControl; +import tethys.pamdata.AutoTethysProvider; + +public class ClickTethysDataProvider extends AutoTethysProvider { + + private ClickDataBlock clickDataBlock; + + public ClickTethysDataProvider(TethysControl tethysControl, ClickDataBlock clickDataBlock) { + super(tethysControl, clickDataBlock); + this.clickDataBlock = clickDataBlock; + } + + @Override + public GranularityEnumType[] getAllowedGranularities() { + return GranularityEnumType.values(); // everything ! + } + +} diff --git a/src/clickTrainDetector/ClickTrainParams.java b/src/clickTrainDetector/ClickTrainParams.java index 1200883d..0a3663b9 100644 --- a/src/clickTrainDetector/ClickTrainParams.java +++ b/src/clickTrainDetector/ClickTrainParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import clickTrainDetector.classification.CTClassifierParams; import clickTrainDetector.classification.simplechi2classifier.Chi2ThresholdParams; @@ -127,7 +128,7 @@ public class ClickTrainParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/classification/CTClassifierParams.java b/src/clickTrainDetector/classification/CTClassifierParams.java index 91d4e8a7..64fa96e9 100644 --- a/src/clickTrainDetector/classification/CTClassifierParams.java +++ b/src/clickTrainDetector/classification/CTClassifierParams.java @@ -5,6 +5,7 @@ import java.util.UUID; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; @@ -68,7 +69,7 @@ public class CTClassifierParams implements Cloneable, Serializable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java b/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java index 83a326c8..b3e26d12 100644 --- a/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java +++ b/src/clickTrainDetector/classification/templateClassifier/SpectrumTemplateParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @@ -53,7 +54,7 @@ public class SpectrumTemplateParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java index 499fee9f..046c6478 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTChi2Params.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters class must extend this. @@ -38,7 +39,7 @@ public class MHTChi2Params implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java index 964073dc..d40d95e0 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTKernelParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Options for the MHT algorithm @@ -63,7 +64,7 @@ public class MHTKernelParams implements Cloneable, Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java index 06f6e6f4..cd75fc67 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/MHTParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters for the MHT algorithm, contains two serializable parameter @@ -47,7 +48,7 @@ public class MHTParams implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java index 6a6c3611..8773e368 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/electricalNoiseFilter/SimpleElectricalNoiseParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @@ -29,7 +30,7 @@ public class SimpleElectricalNoiseParams implements Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java b/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java index 94a578df..01b877d5 100644 --- a/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java +++ b/src/clickTrainDetector/clickTrainAlgorithms/mht/mhtvar/SimpleChi2VarParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters class for a simple chi2 variable. Contains the expected error in the @@ -194,7 +195,7 @@ public class SimpleChi2VarParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clickTrainDetector/dataselector/CTSelectParams.java b/src/clickTrainDetector/dataselector/CTSelectParams.java index 5343f020..fa6f26dd 100644 --- a/src/clickTrainDetector/dataselector/CTSelectParams.java +++ b/src/clickTrainDetector/dataselector/CTSelectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; import clickDetector.dataSelector.ClickTrainSelectParameters; @@ -93,7 +94,7 @@ public class CTSelectParams extends DataSelectParams implements Serializable, Cl @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/clipgenerator/ClipGenSetting.java b/src/clipgenerator/ClipGenSetting.java index ee834658..eb0dd0e0 100644 --- a/src/clipgenerator/ClipGenSetting.java +++ b/src/clipgenerator/ClipGenSetting.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -115,7 +116,7 @@ public class ClipGenSetting implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("hadMapLine"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clipgenerator/ClipSettings.java b/src/clipgenerator/ClipSettings.java index 8636600a..aada971c 100644 --- a/src/clipgenerator/ClipSettings.java +++ b/src/clipgenerator/ClipSettings.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -135,7 +136,7 @@ public class ClipSettings implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("clipGenSettings"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/clipgenerator/clipDisplay/ClipDisplayParameters.java b/src/clipgenerator/clipDisplay/ClipDisplayParameters.java index 15571e2d..15858716 100644 --- a/src/clipgenerator/clipDisplay/ClipDisplayParameters.java +++ b/src/clipgenerator/clipDisplay/ClipDisplayParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.ColourArray.ColourArrayType; @@ -88,7 +89,7 @@ public class ClipDisplayParameters implements Cloneable, Serializable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("maxClips"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/crossedbearinglocaliser/CBLocaliserSettngs.java b/src/crossedbearinglocaliser/CBLocaliserSettngs.java index e296f276..a323eee3 100644 --- a/src/crossedbearinglocaliser/CBLocaliserSettngs.java +++ b/src/crossedbearinglocaliser/CBLocaliserSettngs.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.PamDataBlock; import annotation.localise.targetmotion.TMAnnotationOptions; @@ -78,7 +79,7 @@ public class CBLocaliserSettngs implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/d3/D3DataMapPoint.java b/src/d3/D3DataMapPoint.java index c42595f2..78962aa1 100644 --- a/src/d3/D3DataMapPoint.java +++ b/src/d3/D3DataMapPoint.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import fileOfflineData.OfflineFileMapPoint; @@ -30,7 +31,7 @@ public class D3DataMapPoint extends OfflineFileMapPoint implements ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fileOffsetStart"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataGram/Datagram.java b/src/dataGram/Datagram.java index 33b72d42..eaafcf3f 100644 --- a/src/dataGram/Datagram.java +++ b/src/dataGram/Datagram.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryTypes; import dataMap.OfflineDataMapPoint; @@ -175,7 +176,7 @@ public class Datagram implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataGram/DatagramDataPoint.java b/src/dataGram/DatagramDataPoint.java index 92da4033..dc27f4c6 100644 --- a/src/dataGram/DatagramDataPoint.java +++ b/src/dataGram/DatagramDataPoint.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DatagramDataPoint implements Serializable, ManagedParameters { @@ -89,7 +90,7 @@ public class DatagramDataPoint implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("nDataUnits"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataGram/DatagramSettings.java b/src/dataGram/DatagramSettings.java index e466d55d..a3b5a4df 100644 --- a/src/dataGram/DatagramSettings.java +++ b/src/dataGram/DatagramSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DatagramSettings implements Serializable, Cloneable, ManagedParameters { @@ -33,7 +34,7 @@ public class DatagramSettings implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataMap/DataMapParameters.java b/src/dataMap/DataMapParameters.java index 22eed747..cd714199 100644 --- a/src/dataMap/DataMapParameters.java +++ b/src/dataMap/DataMapParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DataMapParameters implements Cloneable, Serializable, ManagedParameters { @@ -36,7 +37,7 @@ public class DataMapParameters implements Cloneable, Serializable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataMap/DataStreamPanel.java b/src/dataMap/DataStreamPanel.java index 957eadfd..275be1f5 100644 --- a/src/dataMap/DataStreamPanel.java +++ b/src/dataMap/DataStreamPanel.java @@ -747,11 +747,20 @@ public class DataStreamPanel extends JPanel implements DataMapObserver { String tipText; if (startTimeArrow != null && startTimeArrow.contains(me.getPoint())) { - tipText = "Data Start: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataStart(), true); + tipText = "Data Start: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataStart(), false); } else if (endTimeArrow != null && endTimeArrow.contains(me.getPoint())) { - tipText = "Data End: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataEnd(), true); + tipText = "Data End: " + PamCalendar.formatDateTime(dataBlock.getCurrentViewDataEnd(), false); } else { - tipText = "Cursor: " + PamCalendar.formatDateTime(tm, true); + OfflineDataMap dMap = dataBlock.getPrimaryDataMap(); + if (dMap != null) { + tipText = String.format("%s Data from

%s to %s

Cursor: %s", dataBlock.getDataName(), + PamCalendar.formatDateTime(dMap.getFirstDataTime(), false), + PamCalendar.formatDateTime(dMap.getLastDataTime(), false), + PamCalendar.formatDateTime(tm, true)); + } + else { + tipText = "Cursor: " + PamCalendar.formatDateTime(tm, true); + } } // tipText += "
Panel height = " + getHeight(); diff --git a/src/dataMap/OfflineDataMap.java b/src/dataMap/OfflineDataMap.java index 2295af01..d51ee120 100644 --- a/src/dataMap/OfflineDataMap.java +++ b/src/dataMap/OfflineDataMap.java @@ -84,6 +84,8 @@ abstract public class OfflineDataMap { public static final int POINT_END = 0x8; // 8 public static final int IN_DATA = 0x10; // 16 public static final int NO_DATA = 0x20; // 32 + + private static final long oneDayInMillis = 3600L*24L*1000L; public OfflineDataMap(OfflineDataStore offlineDataStore, PamDataBlock parentDataBlock) { super(); @@ -145,10 +147,10 @@ abstract public class OfflineDataMap { */ synchronized public void addDataPoint(TmapPoint mapPoint) { boolean first = (mapPoints.size() == 0); - if (mapPoint.getStartTime() > 0) { + if (mapPoint.getStartTime() > oneDayInMillis) { firstDataTime = Math.min(firstDataTime, mapPoint.getStartTime()); } - if (mapPoint.getEndTime() > 0) { + if (mapPoint.getEndTime() > oneDayInMillis) { lastDataTime = Math.max(lastDataTime, mapPoint.getEndTime()); // if (mapPoint.getEndTime() > System.currentTimeMillis()) { // System.out.println("Stupid large data time in " + mapPoint.getName()); @@ -273,10 +275,10 @@ abstract public class OfflineDataMap { while (it.hasNext()) { aPoint = it.next(); - if (aPoint.getStartTime() > 0) { + if (aPoint.getStartTime() > oneDayInMillis) { firstDataTime = Math.min(firstDataTime, aPoint.getStartTime()); } - if (aPoint.getEndTime() > 0) { + if (aPoint.getEndTime() > oneDayInMillis) { lastDataTime = Math.max(lastDataTime, aPoint.getEndTime()); } n = aPoint.getNDatas(); @@ -361,6 +363,28 @@ abstract public class OfflineDataMap { } } + /** + * Get the start time of the first datamap point or Long.minval + * @return + */ + public long getMapStartTime() { + if (mapPoints == null || mapPoints.size() == 0) { + return Long.MIN_VALUE; + } + return mapPoints.get(0).getStartTime(); + } + + /** + * Get the start time of the first datamap point or Long.minval + * @return + */ + public long getMapEndTime() { + if (mapPoints == null || mapPoints.size() == 0) { + return Long.MIN_VALUE; + } + return mapPoints.get(mapPoints.size()-1).getEndTime(); + } + /** * @return the lowestPoint */ diff --git a/src/dataMap/OfflineDataMapPoint.java b/src/dataMap/OfflineDataMapPoint.java index af9e1910..d1e8917c 100644 --- a/src/dataMap/OfflineDataMapPoint.java +++ b/src/dataMap/OfflineDataMapPoint.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; /** @@ -251,7 +252,7 @@ abstract public class OfflineDataMapPoint implements Comparable impl // TODO Auto-generated method stub return "Sound Files"; } + + @Override + public String getDataLocation() { + getOfflineFileParameters(); + return offlineFileParameters.folderName; + } public TmapPoint findFirstMapPoint(Iterator mapIterator, long startMillis, long endMillis) { TmapPoint mapPoint, prevMapPoint = null; diff --git a/src/dataPlots/TDParameters.java b/src/dataPlots/TDParameters.java index 80d67871..bb7f14db 100644 --- a/src/dataPlots/TDParameters.java +++ b/src/dataPlots/TDParameters.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import dataPlots.layout.GraphParameters; import pamScrollSystem.PamScroller; @@ -45,7 +46,7 @@ public class TDParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlots/layout/DataListInfo.java b/src/dataPlots/layout/DataListInfo.java index 05edd3f8..d506fe64 100644 --- a/src/dataPlots/layout/DataListInfo.java +++ b/src/dataPlots/layout/DataListInfo.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * TDDataInfo objects can't be serialised since they contain @@ -44,7 +45,7 @@ public class DataListInfo implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlots/layout/GraphParameters.java b/src/dataPlots/layout/GraphParameters.java index f505422e..5fc3fe2a 100644 --- a/src/dataPlots/layout/GraphParameters.java +++ b/src/dataPlots/layout/GraphParameters.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import dataPlots.data.TDDataInfo; @@ -41,7 +42,7 @@ public class GraphParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("dataListInfos"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataPlotsFX/TDGraphParametersFX.java b/src/dataPlotsFX/TDGraphParametersFX.java index c4d6de46..f3f6c691 100644 --- a/src/dataPlotsFX/TDGraphParametersFX.java +++ b/src/dataPlotsFX/TDGraphParametersFX.java @@ -8,6 +8,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.GeneralProjector.ParameterType; import PamView.GeneralProjector.ParameterUnits; import javafx.scene.paint.Color; @@ -137,7 +138,7 @@ public class TDGraphParametersFX implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("channels"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataPlotsFX/TDParametersFX.java b/src/dataPlotsFX/TDParametersFX.java index c87320bc..8b614dcc 100644 --- a/src/dataPlotsFX/TDParametersFX.java +++ b/src/dataPlotsFX/TDParametersFX.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import javafx.geometry.Orientation; import userDisplayFX.UserDisplayNodeParams; @@ -122,7 +123,7 @@ public class TDParametersFX implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/data/TDScaleInfoData.java b/src/dataPlotsFX/data/TDScaleInfoData.java index a0d54dba..9cd2ea3c 100644 --- a/src/dataPlotsFX/data/TDScaleInfoData.java +++ b/src/dataPlotsFX/data/TDScaleInfoData.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamguardMVC.PamConstants; @@ -105,7 +106,7 @@ public class TDScaleInfoData implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("autoDivisor"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java b/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java index 388ea462..ec6a1030 100644 --- a/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java +++ b/src/dataPlotsFX/rawClipDataPlot/FFTPlotSettings.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; @@ -48,7 +49,7 @@ public class FFTPlotSettings implements ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java b/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java index c39aeb96..de80f049 100644 --- a/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java +++ b/src/dataPlotsFX/scroller/TDAcousticScrollerParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import dataPlotsFX.scrollingPlot2D.StandardPlot2DColours; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; @@ -55,7 +56,7 @@ public class TDAcousticScrollerParams implements Cloneable, Serializable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java b/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java index 159fa2ad..40aed7c7 100644 --- a/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java +++ b/src/dataPlotsFX/scrollingPlot2D/PlotParams2D.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.scene.paint.Color; @@ -156,7 +157,7 @@ public class PlotParams2D implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java b/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java index 7aafc8ad..a8f2faa2 100644 --- a/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java +++ b/src/dataPlotsFX/spectrogramPlotFX/SpectrogramParamsFX.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import dataPlotsFX.scrollingPlot2D.PlotParams2D; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; import javafx.beans.property.DoubleProperty; @@ -125,7 +126,7 @@ public class SpectrogramParamsFX extends PlotParams2D implements Serializable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dbht/DbHtDisplayParams.java b/src/dbht/DbHtDisplayParams.java index 61e8386c..fb7cab16 100644 --- a/src/dbht/DbHtDisplayParams.java +++ b/src/dbht/DbHtDisplayParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DbHtDisplayParams implements Serializable, Cloneable, ManagedParameters { @@ -40,7 +41,7 @@ public class DbHtDisplayParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/dbht/DbHtParameters.java b/src/dbht/DbHtParameters.java index 7ef321f7..2e32bb3e 100644 --- a/src/dbht/DbHtParameters.java +++ b/src/dbht/DbHtParameters.java @@ -9,6 +9,7 @@ import PamModel.parametermanager.FieldNotFoundException; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterData; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DbHtParameters implements Serializable, Cloneable, ManagedParameters { @@ -186,7 +187,7 @@ public class DbHtParameters implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("frequencyPoints"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dbht/alarm/DbHtAlarmParameters.java b/src/dbht/alarm/DbHtAlarmParameters.java index beb98589..5023e1ae 100644 --- a/src/dbht/alarm/DbHtAlarmParameters.java +++ b/src/dbht/alarm/DbHtAlarmParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DbHtAlarmParameters implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class DbHtAlarmParameters implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("returnedMeasure"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/dbht/offline/DbHtSummaryParams.java b/src/dbht/offline/DbHtSummaryParams.java index b77adf17..34c4951a 100644 --- a/src/dbht/offline/DbHtSummaryParams.java +++ b/src/dbht/offline/DbHtSummaryParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DbHtSummaryParams implements Serializable, Cloneable, ManagedParameters { @@ -23,7 +24,7 @@ public class DbHtSummaryParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/decimator/DecimatorControl.java b/src/decimator/DecimatorControl.java index 7bf9f8ac..1b7d2758 100644 --- a/src/decimator/DecimatorControl.java +++ b/src/decimator/DecimatorControl.java @@ -193,6 +193,15 @@ public class DecimatorControl extends PamControlledUnit implements PamSettings, } return offlineFileServer.getDataSourceName(); } + + @Override + public String getDataLocation() { + if (offlineFileServer == null) { + return getUnitName(); + } + return offlineFileServer.getDataLocation(); + } + @Override public boolean loadData(PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) { if (offlineFileServer == null) { diff --git a/src/decimator/DecimatorParams.java b/src/decimator/DecimatorParams.java index 8fe72caf..472d758a 100644 --- a/src/decimator/DecimatorParams.java +++ b/src/decimator/DecimatorParams.java @@ -26,6 +26,7 @@ import Filters.FilterBand; import Filters.FilterParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DecimatorParams implements Serializable, Cloneable, ManagedParameters { @@ -102,7 +103,7 @@ public class DecimatorParams implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/depthReadout/DepthParameters.java b/src/depthReadout/DepthParameters.java index 1e40df4e..99dcdd25 100644 --- a/src/depthReadout/DepthParameters.java +++ b/src/depthReadout/DepthParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DepthParameters implements Serializable, Cloneable, ManagedParameters { @@ -37,7 +38,7 @@ public class DepthParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/depthReadout/MccDepthParameters.java b/src/depthReadout/MccDepthParameters.java index 7859a1a7..d027670a 100644 --- a/src/depthReadout/MccDepthParameters.java +++ b/src/depthReadout/MccDepthParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import mcc.MccJniInterface; import mcc.mccjna.MCCConstants; @@ -44,7 +45,7 @@ public class MccDepthParameters implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } @@ -62,7 +63,7 @@ public class MccDepthParameters implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("mccSensorParameters"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/detectionPlotFX/plots/FFTPlotParams.java b/src/detectionPlotFX/plots/FFTPlotParams.java index 483f9051..3b8a428d 100644 --- a/src/detectionPlotFX/plots/FFTPlotParams.java +++ b/src/detectionPlotFX/plots/FFTPlotParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; public class FFTPlotParams implements Serializable, Cloneable, ManagedParameters { @@ -98,7 +99,7 @@ public class FFTPlotParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectionPlotFX/plots/SpectrumPlotParams.java b/src/detectionPlotFX/plots/SpectrumPlotParams.java index 36d1807e..c0790a9a 100644 --- a/src/detectionPlotFX/plots/SpectrumPlotParams.java +++ b/src/detectionPlotFX/plots/SpectrumPlotParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SpectrumPlotParams implements Serializable, Cloneable, ManagedParameters { @@ -38,7 +39,7 @@ public class SpectrumPlotParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectionPlotFX/plots/WaveformPlotParams.java b/src/detectionPlotFX/plots/WaveformPlotParams.java index 0c631272..fefc68b5 100644 --- a/src/detectionPlotFX/plots/WaveformPlotParams.java +++ b/src/detectionPlotFX/plots/WaveformPlotParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import depthReadout.DepthParameters; import fftFilter.FFTFilterParams; @@ -63,7 +64,7 @@ public class WaveformPlotParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectionPlotFX/plots/WignerPlotParams.java b/src/detectionPlotFX/plots/WignerPlotParams.java index 0dece899..15f38498 100644 --- a/src/detectionPlotFX/plots/WignerPlotParams.java +++ b/src/detectionPlotFX/plots/WignerPlotParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import pamViewFX.fxNodes.utilsFX.ColourArray.ColourArrayType; @@ -51,7 +52,7 @@ public class WignerPlotParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/detectiongrouplocaliser/DetectionGroupSettings.java b/src/detectiongrouplocaliser/DetectionGroupSettings.java index 318d2b8c..3bc28816 100644 --- a/src/detectiongrouplocaliser/DetectionGroupSettings.java +++ b/src/detectiongrouplocaliser/DetectionGroupSettings.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.paneloverlay.overlaymark.OverlayMarkDataInfo; import annotation.handler.AnnotationChoices; @@ -109,7 +110,7 @@ public class DetectionGroupSettings implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("overlayMarkInfo"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/difar/DifarParameters.java b/src/difar/DifarParameters.java index c54774e9..b8b8dc8c 100644 --- a/src/difar/DifarParameters.java +++ b/src/difar/DifarParameters.java @@ -15,6 +15,7 @@ import Filters.FilterType; import PamController.PamController; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamUtils.PamCalendar; import PamView.PamGui; @@ -588,7 +589,7 @@ public class DifarParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } @@ -659,7 +660,7 @@ public class DifarParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } @@ -773,7 +774,7 @@ public class DifarParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("groupList"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/difar/beamforming/BeamformControl.java b/src/difar/beamforming/BeamformControl.java index edf3507b..bf04ea05 100644 --- a/src/difar/beamforming/BeamformControl.java +++ b/src/difar/beamforming/BeamformControl.java @@ -88,6 +88,16 @@ public class BeamformControl extends PamControlledUnit implements PamSettings, O return DifarParameters.serialVersionUID; } + @Override + public String getDataLocation() { + if (offlineFileServer != null) { + return offlineFileServer.getDataLocation(); + } + else { + return null; + } + } + @Override public boolean restoreSettings( PamControlledUnitSettings pamControlledUnitSettings) { diff --git a/src/difar/beamforming/BeamformParameters.java b/src/difar/beamforming/BeamformParameters.java index 6688d309..2d65e576 100644 --- a/src/difar/beamforming/BeamformParameters.java +++ b/src/difar/beamforming/BeamformParameters.java @@ -5,6 +5,8 @@ import Filters.FilterParams; import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; +import PamUtils.DeepCloner; import PamUtils.PamUtils; public class BeamformParameters implements Serializable, Cloneable, ManagedParameters { @@ -110,7 +112,7 @@ public class BeamformParameters implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/difar/dataSelector/DifarSelectParameters.java b/src/difar/dataSelector/DifarSelectParameters.java index bc9814ad..af1c703e 100644 --- a/src/difar/dataSelector/DifarSelectParameters.java +++ b/src/difar/dataSelector/DifarSelectParameters.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamUtils; import PamguardMVC.dataSelector.DataSelectParams; @@ -61,7 +62,7 @@ public class DifarSelectParameters extends DataSelectParams implements Cloneable @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/difar/demux/GreenridgeParams.java b/src/difar/demux/GreenridgeParams.java index d86fa2da..470357df 100644 --- a/src/difar/demux/GreenridgeParams.java +++ b/src/difar/demux/GreenridgeParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class GreenridgeParams implements Serializable, Cloneable, ManagedParameters { @@ -144,7 +145,7 @@ public class GreenridgeParams implements Serializable, Cloneable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/difar/trackedGroups/TrackedGroupSqlLogging.java b/src/difar/trackedGroups/TrackedGroupSqlLogging.java index 54bd708b..e3b8b15b 100644 --- a/src/difar/trackedGroups/TrackedGroupSqlLogging.java +++ b/src/difar/trackedGroups/TrackedGroupSqlLogging.java @@ -125,7 +125,7 @@ public class TrackedGroupSqlLogging extends SQLLogging { */ protected void updateData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) { - PamTableDefinition tableDef = getTableDefinition(); + PamTableDefinition tableDef = (PamTableDefinition) getTableDefinition(); PamTableItem tableItem; tableDef.getIndexItem().setValue(pamDataUnit.getDatabaseIndex()); diff --git a/src/effortmonitor/EffortParams.java b/src/effortmonitor/EffortParams.java index fcd5bcb5..d19d3e36 100644 --- a/src/effortmonitor/EffortParams.java +++ b/src/effortmonitor/EffortParams.java @@ -5,6 +5,7 @@ import java.util.LinkedList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class EffortParams implements Cloneable, Serializable, ManagedParameters { @@ -100,7 +101,7 @@ public class EffortParams implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/effortmonitor/swing/EffortDialog.java b/src/effortmonitor/swing/EffortDialog.java index 4f4d8b7f..6850415f 100644 --- a/src/effortmonitor/swing/EffortDialog.java +++ b/src/effortmonitor/swing/EffortDialog.java @@ -43,7 +43,7 @@ public class EffortDialog extends PamDialog { mainPanel.add(new JLabel("Observer name or initials"), c); c.gridx++; mainPanel.add(observer = new JComboBox(), c); - outerOnly = new JRadioButton("Log uter scroll only"); + outerOnly = new JRadioButton("Log outer scroll only"); allActions = new JRadioButton("Log all scroll actions"); ButtonGroup bg = new ButtonGroup(); bg.add(allActions); diff --git a/src/envelopeTracer/EnvelopeParams.java b/src/envelopeTracer/EnvelopeParams.java index 09b427f9..6076deb9 100644 --- a/src/envelopeTracer/EnvelopeParams.java +++ b/src/envelopeTracer/EnvelopeParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import Filters.FilterParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class EnvelopeParams implements Serializable, Cloneable, ManagedParameters { @@ -34,7 +35,7 @@ public class EnvelopeParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/fftFilter/FFTFilterParams.java b/src/fftFilter/FFTFilterParams.java index dd4d8ab0..bae3a3b6 100644 --- a/src/fftFilter/FFTFilterParams.java +++ b/src/fftFilter/FFTFilterParams.java @@ -8,6 +8,7 @@ import org.w3c.dom.Element; import Filters.FilterBand; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.FrequencyFormat; public class FFTFilterParams implements Serializable, Cloneable, ManagedParameters { @@ -62,7 +63,7 @@ public class FFTFilterParams implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/fftManager/Complex.java b/src/fftManager/Complex.java index 25b53edd..e2e13ded 100644 --- a/src/fftManager/Complex.java +++ b/src/fftManager/Complex.java @@ -25,6 +25,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Class definition for a Complex number type. @@ -349,7 +350,7 @@ public class Complex implements Cloneable, Serializable, Comparable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/fftManager/FFTDataBlock.java b/src/fftManager/FFTDataBlock.java index db04f8d6..3bf0b7b1 100644 --- a/src/fftManager/FFTDataBlock.java +++ b/src/fftManager/FFTDataBlock.java @@ -4,6 +4,9 @@ import java.util.List; import java.util.ListIterator; import java.util.Vector; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + import PamView.GeneralProjector.ParameterType; import PamView.GeneralProjector.ParameterUnits; import PamguardMVC.DataBlock2D; @@ -186,6 +189,13 @@ public class FFTDataBlock extends DataBlock2D { public DataTypeInfo getScaleInfo() { return dataTypeInfo; } + @Override + public Element getDataBlockXML(Document doc) { + Element el = super.getDataBlockXML(doc); + el.setAttribute("FFTLength", String.format("%d", getFftLength())); + el.setAttribute("FFTHop", String.format("%d", getFftHop())); + return el; + } diff --git a/src/fftManager/FFTDataDisplayOptions.java b/src/fftManager/FFTDataDisplayOptions.java index a6d17619..969a7a81 100644 --- a/src/fftManager/FFTDataDisplayOptions.java +++ b/src/fftManager/FFTDataDisplayOptions.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class FFTDataDisplayOptions implements Serializable, Cloneable, ManagedParameters { @@ -45,7 +46,7 @@ public class FFTDataDisplayOptions implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("maxVal"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/fileOfflineData/OfflineFileControl.java b/src/fileOfflineData/OfflineFileControl.java index cb408652..45998aaf 100644 --- a/src/fileOfflineData/OfflineFileControl.java +++ b/src/fileOfflineData/OfflineFileControl.java @@ -54,6 +54,11 @@ public abstract class OfflineFileControl extends PamControlledUnit implements Of } + @Override + public String getDataLocation() { + return fileParams.offlineFolder; + } + /* (non-Javadoc) * @see PamController.PamControlledUnit#notifyModelChanged(int) */ diff --git a/src/fileOfflineData/OfflineFileParams.java b/src/fileOfflineData/OfflineFileParams.java index b31d547b..82e4d61a 100644 --- a/src/fileOfflineData/OfflineFileParams.java +++ b/src/fileOfflineData/OfflineFileParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OfflineFileParams implements Serializable, Cloneable, ManagedParameters { @@ -28,7 +29,7 @@ public class OfflineFileParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/generalDatabase/DBControl.java b/src/generalDatabase/DBControl.java index 7e229fee..788366c4 100644 --- a/src/generalDatabase/DBControl.java +++ b/src/generalDatabase/DBControl.java @@ -577,10 +577,16 @@ PamSettingsSource { */ @Override public boolean saveStartSettings(long timeNow) { - return dbProcess.saveStartSettings(); + return dbProcess.saveStartSettings(timeNow); } + @Override + public boolean saveEndSettings(long timeNow) { + // TODO Auto-generated method stub + return true; + } + @Override public int getNumSettings() { if (dbSettingsStore == null) { diff --git a/src/generalDatabase/DBControlUnit.java b/src/generalDatabase/DBControlUnit.java index f3bc4b37..e2c129c9 100644 --- a/src/generalDatabase/DBControlUnit.java +++ b/src/generalDatabase/DBControlUnit.java @@ -408,6 +408,11 @@ public class DBControlUnit extends DBControl implements DataOutputStore { return getUnitName(); } + @Override + public String getDataLocation() { + return getDatabaseName(); + } + @Override public boolean loadData(PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) { SQLLogging logging = dataBlock.getLogging(); diff --git a/src/generalDatabase/DBParameters.java b/src/generalDatabase/DBParameters.java index ce8103d7..ab06c212 100644 --- a/src/generalDatabase/DBParameters.java +++ b/src/generalDatabase/DBParameters.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class DBParameters implements Cloneable, Serializable, ManagedParameters { @@ -75,7 +76,7 @@ public class DBParameters implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); if (databaseName != null) { try { Field field = this.getClass().getDeclaredField("databaseName"); diff --git a/src/generalDatabase/DBProcess.java b/src/generalDatabase/DBProcess.java index 167d49f5..597b1a10 100644 --- a/src/generalDatabase/DBProcess.java +++ b/src/generalDatabase/DBProcess.java @@ -102,6 +102,8 @@ public class DBProcess extends PamProcess { dbSpecials.add(logSettings = new LogSettings(databaseControll, "Pamguard Settings", false)); dbSpecials.add(logLastSettings = new LogSettings(databaseControll, "Pamguard Settings Last", true)); dbSpecials.add(logViewerSettings = new LogSettings(databaseControll, "Pamguard Settings Viewer", true)); + + dbSpecials.add(new LogXMLSettings(databaseControll)); } @@ -113,9 +115,13 @@ public class DBProcess extends PamProcess { } } - protected boolean saveStartSettings() { + protected boolean saveStartSettings(long timeNow) { PamConnection con = databaseControll.getConnection(); if (con != null) { + /** + * This first one is the 'old' pre 2022 method which saves a serialised lump of all + * the settings in the database. It ain't broke, so not fixing it. + */ for (int i = 0; i < dbSpecials.size(); i++) { dbSpecials.get(i).pamStart(con); } @@ -124,6 +130,11 @@ public class DBProcess extends PamProcess { return false; } + protected boolean saveEndSettings(long timeNow) { + + return true; + } + @Override public void pamStop() { PamConnection con = databaseControll.getConnection(); @@ -212,7 +223,7 @@ public class DBProcess extends PamProcess { } dataBlocks = PamController.getInstance().getDataBlocks(); - PamTableDefinition tableDefinition; + EmptyTableDefinition tableDefinition; SQLLogging logging; // for each datablock, check that the process can log (ignoring GPS process) diff --git a/src/generalDatabase/DBSchemaWriter.java b/src/generalDatabase/DBSchemaWriter.java index f602ad5c..a29a90b5 100644 --- a/src/generalDatabase/DBSchemaWriter.java +++ b/src/generalDatabase/DBSchemaWriter.java @@ -48,7 +48,7 @@ public class DBSchemaWriter { } - PamTableDefinition tableDef = logging.getTableDefinition(); + EmptyTableDefinition tableDef = logging.getTableDefinition(); tableDef = logging.getBaseTableDefinition(); if (tableDef instanceof PamTableDefinition) { @@ -63,13 +63,14 @@ public class DBSchemaWriter { return true; } - private void exportDatabaseSchema(File outputFolder, PamDataBlock dataBlock, SQLLogging logging, PamTableDefinition tableDef) { - - /** - * write a parent item, e.g. if tableDef is a sub class of PamTableDefinition - */ - // String parentName = writeParentTableSchema(outputFolder, dataBlock, tableDef); - + /** + * Generate an xml schema for a datablock. + * @param dataBlock + * @param logging + * @param tableDef + * @return + */ + public Document generateDatabaseSchema(PamDataBlock dataBlock, SQLLogging logging, EmptyTableDefinition tableDef) { String tableName = tableDef.getTableName(); Document doc = PamUtils.XMLUtils.createBlankDoc(); Element schemaEl = doc.createElement("xs:schema"); @@ -95,7 +96,20 @@ public class DBSchemaWriter { } } } + return doc; + } + + private void exportDatabaseSchema(File outputFolder, PamDataBlock dataBlock, SQLLogging logging, EmptyTableDefinition tableDef) { + /** + * write a parent item, e.g. if tableDef is a sub class of PamTableDefinition + */ + // String parentName = writeParentTableSchema(outputFolder, dataBlock, tableDef); + + Document doc = generateDatabaseSchema(dataBlock, logging, tableDef); + + String tableName = tableDef.getTableName(); + try { File outputFile = new File(outputFolder, tableName+".xsd"); XMLUtils.writeToFile(doc, outputFile); diff --git a/src/generalDatabase/DbSpecial.java b/src/generalDatabase/DbSpecial.java index 05400f7a..401eac1a 100644 --- a/src/generalDatabase/DbSpecial.java +++ b/src/generalDatabase/DbSpecial.java @@ -9,7 +9,7 @@ import PamguardMVC.PamDataUnit; * @author Doug Gillespie * */ -abstract public class DbSpecial extends SQLLogging{ +abstract public class DbSpecial extends SQLLogging { private DBControl dbControl; diff --git a/src/generalDatabase/EmptyTableDefinition.java b/src/generalDatabase/EmptyTableDefinition.java index 9e10753e..53cfd1fb 100644 --- a/src/generalDatabase/EmptyTableDefinition.java +++ b/src/generalDatabase/EmptyTableDefinition.java @@ -300,7 +300,7 @@ public class EmptyTableDefinition implements Cloneable { * @param tableName * @return reference to the database deinition if it exists, or null */ - static PamTableDefinition findTableDefinition(String tableName) { + static EmptyTableDefinition findTableDefinition(String tableName) { String searchName = EmptyTableDefinition.deblankString(tableName); SQLLogging log = SQLLogging.findLogger(searchName); if (log == null) return null; @@ -389,6 +389,15 @@ public class EmptyTableDefinition implements Cloneable { this.updatePolicy = updatePolicy; } + public PamConnection getCheckedConnection() { + return checkedConnection; + } + + public void setCheckedConnection(PamConnection checkedConnection) { + this.checkedConnection = checkedConnection; + } + + @Override protected EmptyTableDefinition clone() { try { diff --git a/src/generalDatabase/LogSettings.java b/src/generalDatabase/LogSettings.java index af5305e9..23b713be 100644 --- a/src/generalDatabase/LogSettings.java +++ b/src/generalDatabase/LogSettings.java @@ -23,7 +23,7 @@ import PamUtils.PamCalendar; import PamguardMVC.PamDataUnit; /** - * Functions for writing Pamguard Settings into any database as character data + * Functions for writing serialised Pamguard Settings into any database as character data * Runs at DAQ start, goes through the settings manager list and for each * set of settings, it serialises the settings data into a binary array, this * is then converted from binary data to 6 bit ascii data (using the character set @@ -185,6 +185,7 @@ public class LogSettings extends DbSpecial { DeserialisationWarning dsWarning = new DeserialisationWarning(getDbControl().getDatabaseName()); SQLTypes sqlTypes = con.getSqlTypes(); + boolean haveData; if (result != null) try { haveData = result.next(); @@ -193,7 +194,7 @@ public class LogSettings extends DbSpecial { // transfer data back into the tableItems store. transferDataFromResult(sqlTypes, result); - tableItem = getTableDefinition().getTimeStampItem(); + tableItem = tableDef.getTimeStampItem(); // timestamp = (Timestamp) tableItem.getTimestampValue(); timeMillis = sqlTypes.millisFromTimeStamp(tableItem.getValue()); diff --git a/src/generalDatabase/LogXMLDataUnit.java b/src/generalDatabase/LogXMLDataUnit.java new file mode 100644 index 00000000..63189784 --- /dev/null +++ b/src/generalDatabase/LogXMLDataUnit.java @@ -0,0 +1,75 @@ +package generalDatabase; + +import PamController.PamSettings; +import PamguardMVC.PamDataUnit; + +/** + * simple data unit for use with the LogXMLSettings class + * @author dg50 + * + */ +public class LogXMLDataUnit extends PamDataUnit { + + private long processTime; + private PamSettings pamSettings; + private String xml; + private Long dataEnd, processEnd; + + public LogXMLDataUnit(long timeMilliseconds, long processTime, PamSettings pamSettings, String xml) { + super(timeMilliseconds); + this.processTime = processTime; + this.pamSettings = pamSettings; + this.xml = xml; + } + + /** + * @return the dataEnd + */ + public Long getDataEnd() { + return dataEnd; + } + + /** + * @param dataEnd the dataEnd to set + */ + public void setDataEnd(Long dataEnd) { + this.dataEnd = dataEnd; + } + + /** + * @return the processEnd + */ + public Long getProcessEnd() { + return processEnd; + } + + /** + * @param processEnd the processEnd to set + */ + public void setProcessEnd(Long processEnd) { + this.processEnd = processEnd; + } + + /** + * @return the processTime + */ + public long getProcessTime() { + return processTime; + } + + /** + * @return the pamSettings + */ + public PamSettings getPamSettings() { + return pamSettings; + } + + /** + * @return the xml + */ + public String getXml() { + return xml; + } + + +} diff --git a/src/generalDatabase/LogXMLSettings.java b/src/generalDatabase/LogXMLSettings.java new file mode 100644 index 00000000..3f33c188 --- /dev/null +++ b/src/generalDatabase/LogXMLSettings.java @@ -0,0 +1,123 @@ +package generalDatabase; + +import java.io.Serializable; +import java.util.HashMap; + +import org.w3c.dom.Document; + +import PamController.PamControlledUnit; +import PamController.PamController; +import PamController.PamSettings; +import PamController.PamguardVersionInfo; +import PamController.settings.output.xml.PamguardXMLWriter; +import PamUtils.PamCalendar; +import PamguardMVC.PamDataUnit; +/** + * 2022 Additional way of saving settings for each module into the database in more human readable + * XML format.

+ * In other ways, similar to LogSettings which saves serialised Java. This will write a line + * per module. A main difference is that on pamStop it will update the end time for each line, so + * that we have a record of analysis effort for each module. Will therefore need to store the last + * index of the entry for each module, so that we can update the appropriate row. + * @author dg50 + * + */ +public class LogXMLSettings extends DbSpecial { + + private XMLSettingsTableDefinition xmlTableDef; + + private HashMap moduleRows; + + private PamguardXMLWriter xmlWriter; + + public LogXMLSettings(DBControl dbControl) { + super(dbControl); + xmlTableDef = new XMLSettingsTableDefinition("Module Effort"); + setTableDefinition(xmlTableDef); + moduleRows = new HashMap<>(); + xmlWriter = PamguardXMLWriter.getXMLWriter(); + } + + @Override + public void pamStart(PamConnection con) { + long time = PamCalendar.getTimeInMillis(); + saveModuleSettings(con, time); + } + + @Override + public void pamStop(PamConnection con) { + long time = PamCalendar.getTimeInMillis(); + updateModuleSettings(con, time); + } + + private void saveModuleSettings(PamConnection con, long dataTime) { + int n = PamController.getInstance().getNumControlledUnits(); + long now = System.currentTimeMillis(); + for (int i = 0; i < n; i++) { + saveModuleSettings(con, dataTime, now, PamController.getInstance().getControlledUnit(i)); + } + + } + + private void saveModuleSettings(PamConnection con, long dataTime, long now, PamControlledUnit controlledUnit) { + if (controlledUnit instanceof PamSettings == false) { + return; + } + PamSettings pamSettings = (PamSettings) controlledUnit; + Serializable settings = pamSettings.getSettingsReference(); + Document doc = xmlWriter.writeOneModule(pamSettings, dataTime); + String xmlString = xmlWriter.getAsString(doc, true); + LogXMLDataUnit logXMLDataUnit = new LogXMLDataUnit(dataTime, now, pamSettings, xmlString); + + logData(logXMLDataUnit); + int dbIndex = logXMLDataUnit.getDatabaseIndex(); + moduleRows.put(getModuleHash(pamSettings), logXMLDataUnit); + } + + private void updateModuleSettings(PamConnection con, long dataTime) { + int n = PamController.getInstance().getNumControlledUnits(); + long now = System.currentTimeMillis(); + for (int i = 0; i < n; i++) { + updateModuleSettings(con, dataTime, now, PamController.getInstance().getControlledUnit(i)); + } + + } + + private void updateModuleSettings(PamConnection con, long dataTime, long now, PamControlledUnit controlledUnit) { + if (controlledUnit instanceof PamSettings == false) { + return; + } + PamSettings pamSettings = (PamSettings) controlledUnit; + LogXMLDataUnit logXMLDataUnit = moduleRows.get(getModuleHash(pamSettings)); + if (logXMLDataUnit == null) { + return; + } + logXMLDataUnit.setDataEnd(dataTime); + logXMLDataUnit.setProcessEnd(now); + reLogData(con, logXMLDataUnit); + } + + private String getModuleHash(PamSettings pamSettings) { + if (pamSettings == null) { + return null; + } + return pamSettings.getUnitName()+pamSettings.getUnitType(); + } + + @Override + public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) { + LogXMLDataUnit logXMLDataUnit = (LogXMLDataUnit) pamDataUnit; + PamSettings pamSettings = logXMLDataUnit.getPamSettings(); + + xmlTableDef.getDataStart().setValue(sqlTypes.getTimeStamp(pamDataUnit.getTimeMilliseconds())); + xmlTableDef.getDataEnd().setValue(sqlTypes.getTimeStamp(logXMLDataUnit.getDataEnd())); + xmlTableDef.getProcessStart().setValue(sqlTypes.getTimeStamp(logXMLDataUnit.getProcessTime())); + xmlTableDef.getProcessEnd().setValue(sqlTypes.getTimeStamp(logXMLDataUnit.getProcessEnd())); + xmlTableDef.getName().setValue(pamSettings.getUnitName()); + xmlTableDef.getType().setValue(pamSettings.getUnitType()); + xmlTableDef.getPamGuardVersion().setValue(PamguardVersionInfo.version); + xmlTableDef.getSettingsVersion().setValue(pamSettings.getSettingsVersion()); + xmlTableDef.getXmlSettings().setValue(logXMLDataUnit.getXml()); + } + +} diff --git a/src/generalDatabase/MySQLParameters.java b/src/generalDatabase/MySQLParameters.java index 9491a6da..cadd498f 100644 --- a/src/generalDatabase/MySQLParameters.java +++ b/src/generalDatabase/MySQLParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MySQLParameters implements Cloneable, Serializable, ManagedParameters { @@ -37,7 +38,7 @@ public class MySQLParameters implements Cloneable, Serializable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("databaseName"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/generalDatabase/PamTableDefinition.java b/src/generalDatabase/PamTableDefinition.java index e8a2b5dc..8424b683 100644 --- a/src/generalDatabase/PamTableDefinition.java +++ b/src/generalDatabase/PamTableDefinition.java @@ -192,14 +192,7 @@ public class PamTableDefinition extends EmptyTableDefinition implements Cloneabl public PamTableItem getUidItem() { return uid; } - public PamConnection getCheckedConnection() { - return checkedConnection; - } - - public void setCheckedConnection(PamConnection checkedConnection) { - this.checkedConnection = checkedConnection; - } - + public PamTableItem getUpdateReference() { return updateReference; } diff --git a/src/generalDatabase/PamTableItem.java b/src/generalDatabase/PamTableItem.java index 2a046623..e73772e8 100644 --- a/src/generalDatabase/PamTableItem.java +++ b/src/generalDatabase/PamTableItem.java @@ -377,7 +377,7 @@ public class PamTableItem implements Cloneable { * column for use in cross referencing. */ public static PamTableItem findTableItem(String tableName, String columnName) { - PamTableDefinition tableDef = EmptyTableDefinition. + EmptyTableDefinition tableDef = EmptyTableDefinition. findTableDefinition(EmptyTableDefinition.deblankString(tableName)); if (tableDef == null) return null; return tableDef.findTableItem(EmptyTableDefinition.deblankString(columnName)); diff --git a/src/generalDatabase/SQLLogging.java b/src/generalDatabase/SQLLogging.java index e9c094ed..8f8b9f84 100644 --- a/src/generalDatabase/SQLLogging.java +++ b/src/generalDatabase/SQLLogging.java @@ -190,7 +190,7 @@ public abstract class SQLLogging { ArrayList blockList = PamController.getInstance() .getDataBlocks(); SQLLogging logger; - PamTableDefinition tableDef; + EmptyTableDefinition tableDef; for (int i = 0; i < blockList.size(); i++) { if ((logger = blockList.get(i).getLogging()) != null) { tableDef = logger.getTableDefinition(); @@ -293,37 +293,42 @@ public abstract class SQLLogging { * @param superDetection */ protected void fillTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit, PamDataUnit superDetection) { + + EmptyTableDefinition emptyTableDef = getTableDefinition(); - PamTableDefinition tableDef = getTableDefinition(); PamTableItem tableItem; - tableDef.getIndexItem().setValue(pamDataUnit.getDatabaseIndex()); - /* - * All tables have a timestamp near the front of the table. And all data - * units have a time in milliseconds, so always fill this in ! - */ - tableDef.getTimeStampItem().setValue( - sqlTypes.getTimeStamp(pamDataUnit.getTimeMilliseconds())); + emptyTableDef.getIndexItem().setValue(pamDataUnit.getDatabaseIndex()); + + if (emptyTableDef instanceof PamTableDefinition) { + PamTableDefinition tableDef = (PamTableDefinition) emptyTableDef; + /* + * All tables have a timestamp near the front of the table. And all data + * units have a time in milliseconds, so always fill this in ! + */ + tableDef.getTimeStampItem().setValue( + sqlTypes.getTimeStamp(pamDataUnit.getTimeMilliseconds())); - tableDef.getTimeStampMillis().setValue((int) (pamDataUnit.getTimeMilliseconds()%1000)); + tableDef.getTimeStampMillis().setValue((int) (pamDataUnit.getTimeMilliseconds()%1000)); - tableDef.getLocalTimeItem().setValue(sqlTypes.getLocalTimeStamp(pamDataUnit.getTimeMilliseconds())); + tableDef.getLocalTimeItem().setValue(sqlTypes.getLocalTimeStamp(pamDataUnit.getTimeMilliseconds())); - tableDef.getPCTimeItem().setValue(sqlTypes.getTimeStamp(System.currentTimeMillis())); + tableDef.getPCTimeItem().setValue(sqlTypes.getTimeStamp(System.currentTimeMillis())); - tableDef.getUidItem().setValue(pamDataUnit.getUID()); + tableDef.getUidItem().setValue(pamDataUnit.getUID()); - tableDef.getChannelBitmap().setValue(pamDataUnit.getChannelBitmap()); + tableDef.getChannelBitmap().setValue(pamDataUnit.getChannelBitmap()); - tableDef.getSequenceBitmap().setValue(pamDataUnit.getSequenceBitmapObject()); + tableDef.getSequenceBitmap().setValue(pamDataUnit.getSequenceBitmapObject()); - if (tableDef.getUpdateReference() != null) { - tableDef.getUpdateReference().setValue(pamDataUnit.getDatabaseIndex()); + if (tableDef.getUpdateReference() != null) { + tableDef.getUpdateReference().setValue(pamDataUnit.getDatabaseIndex()); + } } - for (int i = 0; i < tableDef.getTableItemCount(); i++) { + for (int i = 0; i < emptyTableDef.getTableItemCount(); i++) { - tableItem = tableDef.getTableItem(i); + tableItem = emptyTableDef.getTableItem(i); // if (tableItem.isCounter()) { // tableItem.setValue(1); // } @@ -333,8 +338,8 @@ public abstract class SQLLogging { } } - if (tableDef instanceof PamSubtableDefinition) { - PamSubtableDefinition subTableDef = (PamSubtableDefinition) tableDef; + if (emptyTableDef instanceof PamSubtableDefinition) { + PamSubtableDefinition subTableDef = (PamSubtableDefinition) emptyTableDef; fillSubTableData(subTableDef, pamDataUnit, superDetection); } @@ -525,7 +530,7 @@ public abstract class SQLLogging { } // now put some sql into the statement // if (resultSet == null) { - PamTableDefinition tableDef = getTableDefinition(); + EmptyTableDefinition tableDef = getTableDefinition(); String sqlString = tableDef.getSQLSelectString(con.getSqlTypes()); // sqlString = "select \"comment\" from userinput"; try { @@ -546,6 +551,71 @@ public abstract class SQLLogging { // } return resultSet; } + + /** + * Find the data point which is closest in time to that given, or null + * returning whatever type of data unit this deals with. + * @param timeMillis + * @return + */ + public PamDataUnit findClosestDataPoint(PamConnection con, long timeMillis) { + + PamCursor pamCursor = loggingCursorFinder.getCursor(con, pamTableDefinition); + + // can't really do any math with the string based dates, so will have to query from + // a few s before the time we want. + PamDataUnit[] beforeNafter = new PamDataUnit[2]; + + SQLTypes sqlTypes = con.getSqlTypes(); + + for (int i = 0; i < 2; i++) { + String clause; + + if (i == 0) { + clause = String.format("WHERE UTC <= %s ORDER BY UTC DESC", sqlTypes.formatDBDateTimeQueryString(timeMillis)); + } + else { + clause = String.format("WHERE UTC >= %s ORDER BY UTC ASC", sqlTypes.formatDBDateTimeQueryString(timeMillis)); + } + + ResultSet result = pamCursor.openReadOnlyCursor(con, clause); + if (result==null) { + return null; + } + + PamTableItem tableItem; + try { + if (result.next()) { + // for (int i = 0; i < pamTableDefinition.getTableItemCount(); i++) { + // tableItem = pamTableDefinition.getTableItem(i); + // tableItem.setValue(result.getObject(i + 1)); + // } + // return true; + boolean ok = transferDataFromResult(con.getSqlTypes(), result); + result.close(); + beforeNafter[i] = createDataUnit(sqlTypes, lastTime, lastLoadIndex); + } + } catch (SQLException ex) { + ex.printStackTrace(); + continue; + } + } + // now pick the closest + if (beforeNafter[0] == null) { + return beforeNafter[1]; + } + if (beforeNafter[1] == null) { + return beforeNafter[0]; + } + long t1 = timeMillis-beforeNafter[0].getTimeMilliseconds(); + long t2 = beforeNafter[1].getTimeMilliseconds()-timeMillis; + if (t1 < t2) { + return beforeNafter[0]; + } + else { + return beforeNafter[1]; + } + } /** * Called when a new database is connected to read the last values back in @@ -1079,7 +1149,7 @@ public abstract class SQLLogging { public boolean transferDataFromResult(SQLTypes sqlTypes, ResultSet resultSet) { - PamTableDefinition tableDef = getTableDefinition(); + EmptyTableDefinition tableDef = getTableDefinition(); PamTableItem tableItem; try { for (int i = 0; i < tableDef.getTableItemCount(); i++) { @@ -1090,17 +1160,20 @@ public abstract class SQLLogging { // Timestamp ts = (Timestamp) getTableDefinition().getTimeStampItem().getValue(); // Timestamp ts = getTableDefinition().getTimeStampItem().getTimestampValue(); // lastTime = sqlTypes.millisFromTimeStamp(ts); - lastTime = sqlTypes.millisFromTimeStamp(getTableDefinition().getTimeStampItem().getValue()); - if (lastTime%1000 == 0) { - // some databases may have stored the milliseconds, in which - // case this next bit is redundant. - lastTime += getTableDefinition().getTimeStampMillis().getIntegerValue(); - } - lastLoadIndex = getTableDefinition().getIndexItem().getIntegerValue(); - lastLoadUID = getTableDefinition().getUidItem().getLongObject(); - lastChannelBitmap = getTableDefinition().getChannelBitmap().getIntegerValue(); - lastSequenceBitmap = getTableDefinition().getSequenceBitmap().getIntegerObject(); + if (tableDef instanceof PamTableDefinition) { + PamTableDefinition pamTableDef = (PamTableDefinition) tableDef; + lastTime = sqlTypes.millisFromTimeStamp(pamTableDef.getTimeStampItem().getValue()); + if (lastTime%1000 == 0) { + // some databases may have stored the milliseconds, in which + // case this next bit is redundant. + lastTime += pamTableDef.getTimeStampMillis().getIntegerValue(); + } + + lastLoadUID = pamTableDef.getUidItem().getLongObject(); + lastChannelBitmap = pamTableDef.getChannelBitmap().getIntegerValue(); + lastSequenceBitmap = pamTableDef.getSequenceBitmap().getIntegerObject(); + } return true; } catch (SQLException ex) { diff --git a/src/generalDatabase/SQLLoggingAddon.java b/src/generalDatabase/SQLLoggingAddon.java index 6d347fb4..ff8bd561 100644 --- a/src/generalDatabase/SQLLoggingAddon.java +++ b/src/generalDatabase/SQLLoggingAddon.java @@ -15,7 +15,7 @@ public interface SQLLoggingAddon { * Add a load of columns to an existing table definition * @param pamTableDefinition */ - public void addTableItems(PamTableDefinition pamTableDefinition); + public void addTableItems(EmptyTableDefinition pamTableDefinition); /** * Save data - that is transfer data from the pamDataUnit to the data objects @@ -24,7 +24,7 @@ public interface SQLLoggingAddon { * @param pamDataUnit data unit * @return true if successful */ - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); /** * Load data - that is read data from the table definition and turn it into something sensible @@ -33,7 +33,7 @@ public interface SQLLoggingAddon { * @param pamDataUnit data unit * @return true if successful */ - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit); /** * Get a name for the SQLLogging Addon. this is used diff --git a/src/generalDatabase/SQLTypes.java b/src/generalDatabase/SQLTypes.java index a81edd89..fd8ccb56 100644 --- a/src/generalDatabase/SQLTypes.java +++ b/src/generalDatabase/SQLTypes.java @@ -387,6 +387,7 @@ public class SQLTypes { return timestamp.getTime() + tz.getOffset(timestamp.getTime()); } else if (timeValue instanceof String) { + timeValue = ((String) timeValue).replace("'", ""); return PamCalendar.millisFromDateString((String) timeValue, false); } if (timeValue instanceof Long) { diff --git a/src/generalDatabase/XMLSettingsTableDefinition.java b/src/generalDatabase/XMLSettingsTableDefinition.java new file mode 100644 index 00000000..8d40bc55 --- /dev/null +++ b/src/generalDatabase/XMLSettingsTableDefinition.java @@ -0,0 +1,94 @@ +package generalDatabase; + +import java.sql.Types; + +import PamguardMVC.PamConstants; + +public class XMLSettingsTableDefinition extends PamTableDefinition { + + private PamTableItem dataStart, dataEnd, processStart, processEnd, type, name, pamGuardVersion, settingsVersion, xmlSettings; + + public XMLSettingsTableDefinition(String tableName) { + super(tableName, SQLLogging.UPDATE_POLICY_WRITENEW); + pamTableItems.add(dataStart = new PamTableItem("Data Start", Types.TIMESTAMP, "Data start time")); + pamTableItems.add(dataEnd = new PamTableItem("Data End", Types.TIMESTAMP, "Data end time")); + pamTableItems.add(processStart = new PamTableItem("Process Start", Types.TIMESTAMP, "Process start time")); + pamTableItems.add(processEnd = new PamTableItem("Process End", Types.TIMESTAMP, "Process end time")); + addTableItem(type = new PamTableItem("unitType", Types.CHAR, PamConstants.MAX_ITEM_NAME_LENGTH)); + addTableItem(name = new PamTableItem("unitName", Types.CHAR, PamConstants.MAX_ITEM_NAME_LENGTH)); + addTableItem(pamGuardVersion = new PamTableItem("PAMGuardVersion", Types.INTEGER)); + addTableItem(settingsVersion = new PamTableItem("SettingsVersion", Types.INTEGER)); + addTableItem(xmlSettings = new PamTableItem("XMLSettings", Types.VARCHAR)); + setUseCheatIndexing(false); + } + + + /** + * @return the dataStart + */ + public PamTableItem getDataStart() { + return dataStart; + } + + + /** + * @return the dataEnd + */ + public PamTableItem getDataEnd() { + return dataEnd; + } + + + /** + * @return the processStart + */ + public PamTableItem getProcessStart() { + return processStart; + } + + + /** + * @return the processEnd + */ + public PamTableItem getProcessEnd() { + return processEnd; + } + + + /** + * @return the type + */ + public PamTableItem getType() { + return type; + } + + /** + * @return the name + */ + public PamTableItem getName() { + return name; + } + + /** + * @return the pamGuardVersion + */ + public PamTableItem getPamGuardVersion() { + return pamGuardVersion; + } + + /** + * @return the settingsVersion + */ + public PamTableItem getSettingsVersion() { + return settingsVersion; + } + + /** + * @return the xmlSettings + */ + public PamTableItem getXmlSettings() { + return xmlSettings; + } + + +} diff --git a/src/generalDatabase/dataExport/ValueFilterParams.java b/src/generalDatabase/dataExport/ValueFilterParams.java index 15ffdfbd..52c57cfd 100644 --- a/src/generalDatabase/dataExport/ValueFilterParams.java +++ b/src/generalDatabase/dataExport/ValueFilterParams.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Abstract class for ValueFilters for filtering database data tables. @@ -110,7 +111,7 @@ public abstract class ValueFilterParams implements Cloneable, Serializable, Mana @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/generalDatabase/lookupTables/LookupItem.java b/src/generalDatabase/lookupTables/LookupItem.java index 7115406e..9ee05094 100644 --- a/src/generalDatabase/lookupTables/LookupItem.java +++ b/src/generalDatabase/lookupTables/LookupItem.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.PamSymbol; import PamView.PamSymbolType; @@ -232,7 +233,7 @@ public class LookupItem implements Cloneable, Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/generalDatabase/lookupTables/LookupList.java b/src/generalDatabase/lookupTables/LookupList.java index 8e0a0e0c..7714cdd3 100644 --- a/src/generalDatabase/lookupTables/LookupList.java +++ b/src/generalDatabase/lookupTables/LookupList.java @@ -7,6 +7,7 @@ import java.util.Vector; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Handles information for a single list from the look up table @@ -253,7 +254,7 @@ public class LookupList implements Cloneable, Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/generalDatabase/parameterstore/ParameterDatabaseStore.java b/src/generalDatabase/parameterstore/ParameterDatabaseStore.java new file mode 100644 index 00000000..29c740eb --- /dev/null +++ b/src/generalDatabase/parameterstore/ParameterDatabaseStore.java @@ -0,0 +1,187 @@ +package generalDatabase.parameterstore; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import java.util.Arrays; +import java.util.Collection; + +import PamModel.parametermanager.ManagedParameters; +import PamModel.parametermanager.PamParameterData; +import PamModel.parametermanager.PamParameterSet; +import generalDatabase.DBControlUnit; +import generalDatabase.EmptyTableDefinition; +import generalDatabase.PamConnection; +import generalDatabase.PamTableItem; +import generalDatabase.SQLTypes; + +/** + * Store parameters from a managed parameter set in the PAMGuard database. These go into a dead simple table, which has + * two columns. The first is a name, the second a string value. Each parameter can only appear once. + * This works with ManagedParameters using the same names and field names that go into the xml output. + * @author dg50 + * + */ +public class ParameterDatabaseStore { + + + private EmptyTableDefinition tableDef; + private PamTableItem nameItem, dataItem; + + public ParameterDatabaseStore(String tableName) { + tableDef = new EmptyTableDefinition(tableName); + tableDef.addTableItem(nameItem = new PamTableItem("ParameterName", Types.VARCHAR)); + tableDef.addTableItem(dataItem = new PamTableItem("Value", Types.VARCHAR)); + } + + public boolean saveParameterSet(ManagedParameters managedParameters) { + if (managedParameters == null) { + return false; + } + return saveParameterSet(managedParameters.getClass().getSimpleName(), managedParameters); + } + + private boolean saveParameterSet(String name, ManagedParameters managedParameters) { + DBControlUnit dbControl = DBControlUnit.findDatabaseControl(); + if (dbControl == null) { + return false; + } + PamConnection con = dbControl.getConnection(); + if (checkTable(con) == false) { + return false; + } + + String prefix; + if (name == null) { + prefix = ""; + } + else { + prefix = name + "."; + } + PamParameterSet paramSet = managedParameters.getParameterSet(); + Collection params = paramSet.getParameterCollection(); + for (PamParameterData paramData : params) { + String paramName = paramData.getFieldName(); + paramName = prefix + paramName; + Object data = null; + try { + data = paramData.getData();// .getField().get(managedParameters); + } catch (IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } +// System.out.printf("Store param \"%s\" as \"%s\"\n", paramName, data); + saveToDatabase(con, paramName, data); + } + dbControl.commitChanges(); + + return true; + } + + private boolean saveToDatabase(PamConnection con, String name, Object data) { + int[] existing = findExistingRows(con, name); + boolean ok = true; + if (existing == null || existing.length == 0) { + ok |= newRecord(con, name, data); + } + else { + ok |= updateRecord(con, existing[0], name, data); + if (existing.length > 1) { + for (int i = 1; i < existing.length; i++) { + ok |= deleteDuplicateRow(con, existing[i]); + } + } + } + return true; + } + + private int[] findExistingRows(PamConnection con, String name) { + /** + * Find existing rows with that name. + */ + int[] rows = new int[0]; + if (con == null) { + return rows; + } + String qStr = String.format("SELECT Id FROM %s WHERE %s='%s'", tableDef.getTableName(), nameItem.getName(), name); + try { + Statement stmt = con.getConnection().createStatement(); + ResultSet res = stmt.executeQuery(qStr); + while (res.next()) { + int rowId = res.getInt(1); + rows = Arrays.copyOf(rows, rows.length+1); + rows[rows.length-1] = rowId; + } + res.close(); + stmt.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return rows; + } + + private boolean newRecord(PamConnection con, String name, Object data) { + + String insertStr = tableDef.getSQLInsertString(con.getSqlTypes()); + try { + PreparedStatement stmt = con.getConnection().prepareStatement(insertStr); + stmt.setString(1, name); + if (data == null) { + stmt.setNull(2, Types.VARCHAR); + } + else { + stmt.setString(2, data.toString()); + } + stmt.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + private boolean updateRecord(PamConnection con, int iRow, String name, Object data) { + SQLTypes st = con.getSqlTypes(); + String updateString = String.format("UPDATE %s SET %s = '%s' WHERE Id = %d", tableDef.getTableName(), + st.formatColumnName(dataItem.getName()), data, iRow); + + try { + PreparedStatement stmt = con.getConnection().prepareStatement(updateString); + stmt.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + private boolean deleteDuplicateRow(PamConnection con, int rowId) { + + String delStr = String.format("DELETE FROM %s WHERE Id=%d", tableDef.getTableName(), rowId); + + try { + PreparedStatement stmt = con.getConnection().prepareStatement(delStr); + stmt.executeUpdate(); + + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + return true; + } + + private boolean checkTable(PamConnection con) { + DBControlUnit dbControl = DBControlUnit.findDatabaseControl(); + if (dbControl == null) { + return false; + } + dbControl.commitChanges(); + return dbControl.getDbProcess().checkTable(tableDef); + } + +} diff --git a/src/generalDatabase/sqlite/SqliteSQLTypes.java b/src/generalDatabase/sqlite/SqliteSQLTypes.java index 580c8c5e..4f2baf73 100644 --- a/src/generalDatabase/sqlite/SqliteSQLTypes.java +++ b/src/generalDatabase/sqlite/SqliteSQLTypes.java @@ -10,7 +10,7 @@ import PamUtils.PamCalendar; public class SqliteSQLTypes extends SQLTypes { - protected static final SQLiteConfig.DateClass dateClass = SQLiteConfig.DateClass.TEXT; + public static final SQLiteConfig.DateClass dateClass = SQLiteConfig.DateClass.TEXT; @Override public String typeToString(int sqlType, int length, boolean counter) { diff --git a/src/gpl/GPLParameters.java b/src/gpl/GPLParameters.java index 666c559e..fcda34d9 100644 --- a/src/gpl/GPLParameters.java +++ b/src/gpl/GPLParameters.java @@ -6,6 +6,7 @@ import java.io.Serializable; import PamModel.parametermanager.FieldNotFoundException; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.blockprocess.PamBlockParams; import gpl.contour.ContourMerge; @@ -198,7 +199,7 @@ public class GPLParameters implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { ps.findParameterData("minPeakGap").setInfo("Minimum gap", "bins", "Minimum gap between peaks (FFT time bins)"); ps.findParameterData("minCallLengthSeconds").setInfo("Minimum length", "bins", "Minimum length of a detection in seconds"); diff --git a/src/gpl/io/GPLLogging.java b/src/gpl/io/GPLLogging.java index d8817bdc..c407193f 100644 --- a/src/gpl/io/GPLLogging.java +++ b/src/gpl/io/GPLLogging.java @@ -5,6 +5,7 @@ import java.sql.Types; import PamDetection.AcousticSQLLogging; import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLTypes; @@ -22,7 +23,7 @@ public class GPLLogging extends AcousticSQLLogging { super(gplDetectionBlock, gplControlledUnit.getUnitName() + " Detections"); this.gplControlledUnit = gplControlledUnit; - PamTableDefinition pamTable = getTableDefinition(); + EmptyTableDefinition pamTable = getTableDefinition(); pamTable.addTableItem(peakValue = new PamTableItem("PeakValue", Types.REAL)); pamTable.addTableItem(contourArea = new PamTableItem("ContourArea", Types.REAL)); } diff --git a/src/group3dlocaliser/Group3DParams.java b/src/group3dlocaliser/Group3DParams.java index fbf75743..6467a9ad 100644 --- a/src/group3dlocaliser/Group3DParams.java +++ b/src/group3dlocaliser/Group3DParams.java @@ -6,6 +6,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import PamView.GroupedSourceParameters; import group3dlocaliser.algorithm.LocaliserAlgorithm3D; @@ -126,7 +127,7 @@ public class Group3DParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("algorithmSpecificParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java b/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java index 7f7e1371..735d70f1 100644 --- a/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java +++ b/src/group3dlocaliser/algorithm/gridsearch/MFPGridSearchParams.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class MFPGridSearchParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class MFPGridSearchParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fftLength"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java b/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java index 6f2a0fb2..8c845ffe 100644 --- a/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java +++ b/src/group3dlocaliser/algorithm/gridsearch/TOADGridParams.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import group3dlocaliser.grids.SphericalGrid; import pamMaths.PamVector; @@ -49,7 +50,7 @@ public class TOADGridParams implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("gridType"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java b/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java index 1aa70f8a..b0e11190 100644 --- a/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java +++ b/src/group3dlocaliser/algorithm/toadbase/TOADBaseParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters that apply to all TOAD based localisers. @@ -117,7 +118,7 @@ public class TOADBaseParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java b/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java index 879eae8b..86e2397d 100644 --- a/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java +++ b/src/group3dlocaliser/dataselector/Group3DDataSelectParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; public class Group3DDataSelectParams extends DataSelectParams implements Serializable, Cloneable, ManagedParameters { @@ -28,7 +29,7 @@ public class Group3DDataSelectParams extends DataSelectParams implements Seriali @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/group3dlocaliser/grids/SphericalGridParams.java b/src/group3dlocaliser/grids/SphericalGridParams.java index f323ee53..5ece7b39 100644 --- a/src/group3dlocaliser/grids/SphericalGridParams.java +++ b/src/group3dlocaliser/grids/SphericalGridParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SphericalGridParams implements Serializable, Cloneable, ManagedParameters { @@ -88,7 +89,7 @@ public class SphericalGridParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/group3dlocaliser/grouper/DetectionGrouperParams.java b/src/group3dlocaliser/grouper/DetectionGrouperParams.java index 5d92afd1..d789b054 100644 --- a/src/group3dlocaliser/grouper/DetectionGrouperParams.java +++ b/src/group3dlocaliser/grouper/DetectionGrouperParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class DetectionGrouperParams implements Serializable, Cloneable, ManagedParameters { @@ -38,7 +39,7 @@ public class DetectionGrouperParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/help/JavaHelpSearch/DOCS b/src/help/JavaHelpSearch/DOCS index aece1f43..aa2227fe 100644 Binary files a/src/help/JavaHelpSearch/DOCS and b/src/help/JavaHelpSearch/DOCS differ diff --git a/src/help/JavaHelpSearch/DOCS.TAB b/src/help/JavaHelpSearch/DOCS.TAB index fcb0be96..ad72b66e 100644 Binary files a/src/help/JavaHelpSearch/DOCS.TAB and b/src/help/JavaHelpSearch/DOCS.TAB differ diff --git a/src/help/JavaHelpSearch/OFFSETS b/src/help/JavaHelpSearch/OFFSETS index 7aeaea18..8a7b9b88 100644 Binary files a/src/help/JavaHelpSearch/OFFSETS and b/src/help/JavaHelpSearch/OFFSETS differ diff --git a/src/help/JavaHelpSearch/POSITIONS b/src/help/JavaHelpSearch/POSITIONS index 168a00c2..91375b46 100644 Binary files a/src/help/JavaHelpSearch/POSITIONS and b/src/help/JavaHelpSearch/POSITIONS differ diff --git a/src/help/JavaHelpSearch/SCHEMA b/src/help/JavaHelpSearch/SCHEMA index f1bcbb62..0de6873b 100644 --- a/src/help/JavaHelpSearch/SCHEMA +++ b/src/help/JavaHelpSearch/SCHEMA @@ -1,2 +1,2 @@ JavaSearch 1.0 -TMAP bs=2048 rt=1 fl=-1 id1=6700 id2=1 +TMAP bs=2048 rt=1 fl=-1 id1=6709 id2=1 diff --git a/src/help/JavaHelpSearch/TMAP b/src/help/JavaHelpSearch/TMAP index 0f4d546b..a083f8e0 100644 Binary files a/src/help/JavaHelpSearch/TMAP and b/src/help/JavaHelpSearch/TMAP differ diff --git a/src/help/Map.jhm b/src/help/Map.jhm index 176022cb..a3886c8c 100644 --- a/src/help/Map.jhm +++ b/src/help/Map.jhm @@ -528,6 +528,8 @@ + + @@ -644,6 +646,8 @@ + + diff --git a/src/help/PAMGUARDHelpProject.xml b/src/help/PAMGUARDHelpProject.xml index 69b52d84..fe06f32b 100644 --- a/src/help/PAMGUARDHelpProject.xml +++ b/src/help/PAMGUARDHelpProject.xml @@ -6,7 +6,7 @@ PAMGUARD - C:\Users\dg50\source\repos\PAMGuardDG\src\help + C:\Users\dg50\source\repos\PAMGuardDG_2\src\help index.html diff --git a/src/help/PAMGUARDIndex.xml b/src/help/PAMGUARDIndex.xml index 18d93123..c9cf5489 100644 --- a/src/help/PAMGUARDIndex.xml +++ b/src/help/PAMGUARDIndex.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/help/PAMGUARDTOC.xml b/src/help/PAMGUARDTOC.xml index 73590bca..e1eeb6dc 100644 --- a/src/help/PAMGUARDTOC.xml +++ b/src/help/PAMGUARDTOC.xml @@ -195,6 +195,12 @@ + + + + + + diff --git a/src/help/pamHelpStylesheet.css b/src/help/pamHelpStylesheet.css index e2174daf..d2d474b9 100644 --- a/src/help/pamHelpStylesheet.css +++ b/src/help/pamHelpStylesheet.css @@ -52,7 +52,9 @@ ol { FONT-SIZE: 14; } + img.wrap {float: left} +img.wrapright {float: right} table, th, td { border: 1px solid black; diff --git a/src/help/utilities/tethys/docs/images/Tethys-200.png b/src/help/utilities/tethys/docs/images/Tethys-200.png new file mode 100644 index 00000000..19e3c48f Binary files /dev/null and b/src/help/utilities/tethys/docs/images/Tethys-200.png differ diff --git a/src/help/utilities/tethys/docs/tethys_overview.html b/src/help/utilities/tethys/docs/tethys_overview.html new file mode 100644 index 00000000..da30d095 --- /dev/null +++ b/src/help/utilities/tethys/docs/tethys_overview.html @@ -0,0 +1,70 @@ + + + + + +Tethys Module Overview + + + +

Tethys Interface

+

Overview

+ +

+ Tethys mosaic +

+

+ + Tethys is a freely + available open source temporal-spatial database for metadata related + to acoustic recordings. The database is intended to house the metadata + from marine mammal detection and localization studies, allowing the + user to perform meta analyses or to aggregate data from many + experimental efforts based on a common attribute. This resulting + database can then be queried based on time, space, or any desired + attribute and the results can be integrated with external datasets + such as NASA's Ocean Color, lunar illumination, etc. in a consistent + manner. While Tethys is designed primarily for acoustic metadata from + marine mammals, the design is general enough to permit use in other + areas as well. + +

+

PAMGuard is compatible with Tethys 3.0, released early in 2024.

+

The Tethys database is not a replacement for the existing + + PAMGuard Database. + Where the PAMGuard database only contains data from a single instrument or cruise, the Tethys + database contains data from many cruises and projects and can be used to hold a summary of all data + from a lab or organisation. +

+ +

Before using the module in PAMGuard, you should install the Tethys Server, which runs under + Windows. + Instructions for installing the Tethys Server can be found here.

+ + +

+ + + Next: Configuring the Tethys + Module +

+
+
+
+ + diff --git a/src/help/utilities/tethys/docs/tethys_server.html b/src/help/utilities/tethys/docs/tethys_server.html new file mode 100644 index 00000000..50a61a06 --- /dev/null +++ b/src/help/utilities/tethys/docs/tethys_server.html @@ -0,0 +1,34 @@ + + + + + + + + Tethys Module Overview + + +

Tethys Interface

+

Tethys Server

+

+ Tethys is ... +

+ +
+
+ +
+
+
+ + diff --git a/src/landMarks/LandmarkData.java b/src/landMarks/LandmarkData.java index 2be20e55..ef0cb561 100644 --- a/src/landMarks/LandmarkData.java +++ b/src/landMarks/LandmarkData.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamController.masterReference.MasterReferencePoint; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.LatLong; import PamView.PamSymbol; @@ -49,7 +50,7 @@ public class LandmarkData extends Object implements Serializable, Cloneable, Man @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/landMarks/LandmarkDatas.java b/src/landMarks/LandmarkDatas.java index d4cd386d..73fb4785 100644 --- a/src/landMarks/LandmarkDatas.java +++ b/src/landMarks/LandmarkDatas.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class LandmarkDatas implements Serializable, Cloneable, ManagedParameters { @@ -76,7 +77,7 @@ public class LandmarkDatas implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/levelMeter/LevelMeterParams.java b/src/levelMeter/LevelMeterParams.java index dd1b6752..c25860dc 100644 --- a/src/levelMeter/LevelMeterParams.java +++ b/src/levelMeter/LevelMeterParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class LevelMeterParams implements Cloneable, Serializable, ManagedParameters { @@ -35,7 +36,7 @@ public class LevelMeterParams implements Cloneable, Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/AcquisitionSettings.java b/src/likelihoodDetectionModule/AcquisitionSettings.java index abf61481..10033395 100644 --- a/src/likelihoodDetectionModule/AcquisitionSettings.java +++ b/src/likelihoodDetectionModule/AcquisitionSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * The AcquisitionSettings class provides a module-local storage object for holding @@ -48,7 +49,7 @@ public class AcquisitionSettings implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/ConfigurationDialogSettings.java b/src/likelihoodDetectionModule/ConfigurationDialogSettings.java index 6856e501..9011ffbd 100644 --- a/src/likelihoodDetectionModule/ConfigurationDialogSettings.java +++ b/src/likelihoodDetectionModule/ConfigurationDialogSettings.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * The Class ConfigurationDialogSettings holds parameters about the @@ -28,7 +29,7 @@ public class ConfigurationDialogSettings implements Serializable, ManagedParamet @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("expandedState"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/likelihoodDetectionModule/GuardBand.java b/src/likelihoodDetectionModule/GuardBand.java index ccd9a6c0..cb07df7b 100644 --- a/src/likelihoodDetectionModule/GuardBand.java +++ b/src/likelihoodDetectionModule/GuardBand.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Represents the parameters that make up a guard band, used as @@ -106,7 +107,7 @@ public class GuardBand implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java b/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java index 9c405cdd..9481c26c 100644 --- a/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java +++ b/src/likelihoodDetectionModule/LikelihoodDetectionParameters.java @@ -11,6 +11,7 @@ import java.util.Iterator; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * The Class LikelihoodDetectionParameters provides the standard PamGuard @@ -271,7 +272,7 @@ public class LikelihoodDetectionParameters implements Serializable, Cloneable, M @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/likelihoodDetectionModule/LikelihoodFFTParameters.java b/src/likelihoodDetectionModule/LikelihoodFFTParameters.java index e90e51c8..13b85fda 100644 --- a/src/likelihoodDetectionModule/LikelihoodFFTParameters.java +++ b/src/likelihoodDetectionModule/LikelihoodFFTParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import fftManager.FFTParameters; import Spectrogram.WindowFunction; @@ -270,7 +271,7 @@ public class LikelihoodFFTParameters implements Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("sourceNumber"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/likelihoodDetectionModule/SignalBand.java b/src/likelihoodDetectionModule/SignalBand.java index 00e7af96..3b3150d6 100644 --- a/src/likelihoodDetectionModule/SignalBand.java +++ b/src/likelihoodDetectionModule/SignalBand.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Represents the parameters that make up a signal band, used as @@ -151,7 +152,7 @@ public class SignalBand implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/likelihoodDetectionModule/TargetConfiguration.java b/src/likelihoodDetectionModule/TargetConfiguration.java index 29c82890..0cc0e398 100644 --- a/src/likelihoodDetectionModule/TargetConfiguration.java +++ b/src/likelihoodDetectionModule/TargetConfiguration.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import likelihoodDetectionModule.normalizer.NormalizerProcess.NormalizerAlgorithm; /** @@ -453,7 +454,7 @@ public class TargetConfiguration implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/loc3d_Thode/TowedArray3DSQLLogging.java b/src/loc3d_Thode/TowedArray3DSQLLogging.java index c5a8b1f7..95bc98e6 100644 --- a/src/loc3d_Thode/TowedArray3DSQLLogging.java +++ b/src/loc3d_Thode/TowedArray3DSQLLogging.java @@ -1,5 +1,6 @@ package loc3d_Thode; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamDetectionLogging; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; @@ -17,7 +18,6 @@ public class TowedArray3DSQLLogging extends PamDetectionLogging { TowedArray3DController towedArray3DController; - PamTableDefinition tableDefinition; PamTableItem dateItem, range_boat_Item, range_f_Item, range_r_Item, depthItem, azi_boat_Item,azi_f_Item, azi_r_Item, tdd_Item, bearing_f_Item,bearing_r_Item, tds_f_Item, tds_r_Item, za_f_Item, za_r_Item; @@ -34,7 +34,7 @@ public class TowedArray3DSQLLogging extends PamDetectionLogging { this.towedArray3DController = towedArray3DController; // create the table definition. - tableDefinition = createTableDefinition(); + PamTableDefinition tableDefinition = createTableDefinition(); } public PamTableDefinition createTableDefinition() { diff --git a/src/loggerForms/FormPlotOptions.java b/src/loggerForms/FormPlotOptions.java index 8f55f828..9763d8ba 100644 --- a/src/loggerForms/FormPlotOptions.java +++ b/src/loggerForms/FormPlotOptions.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; /** @@ -95,7 +96,7 @@ public class FormPlotOptions implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("controlChoices"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/loggerForms/FormSettings.java b/src/loggerForms/FormSettings.java index 199edfe4..f7553e13 100644 --- a/src/loggerForms/FormSettings.java +++ b/src/loggerForms/FormSettings.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Manage a bit of persistent data for a single Logger form description.

@@ -32,7 +33,7 @@ public class FormSettings implements Cloneable, Serializable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/loggerForms/FormsDataDisplayTable.java b/src/loggerForms/FormsDataDisplayTable.java index 26e2f5b3..1300fc79 100644 --- a/src/loggerForms/FormsDataDisplayTable.java +++ b/src/loggerForms/FormsDataDisplayTable.java @@ -261,6 +261,7 @@ public class FormsDataDisplayTable { + /** * Called when data have changed in the datablock. */ diff --git a/src/loggerForms/monitor/FormsSelectorParams.java b/src/loggerForms/monitor/FormsSelectorParams.java index d691af0c..d1797798 100644 --- a/src/loggerForms/monitor/FormsSelectorParams.java +++ b/src/loggerForms/monitor/FormsSelectorParams.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.dataSelector.DataSelectParams; public class FormsSelectorParams extends DataSelectParams implements Cloneable, Serializable, ManagedParameters { @@ -30,7 +31,7 @@ public class FormsSelectorParams extends DataSelectParams implements Cloneable, @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("formSelection"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/ltsa/LtsaModuleHeader.java b/src/ltsa/LtsaModuleHeader.java index 0b5d888e..50c1034d 100644 --- a/src/ltsa/LtsaModuleHeader.java +++ b/src/ltsa/LtsaModuleHeader.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import binaryFileStorage.BinaryHeader; import binaryFileStorage.BinaryObjectData; import binaryFileStorage.ModuleHeader; @@ -37,7 +38,7 @@ public class LtsaModuleHeader extends ModuleHeader implements ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fftLength"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/ltsa/LtsaParameters.java b/src/ltsa/LtsaParameters.java index 2dfd9a62..dbf62ec0 100644 --- a/src/ltsa/LtsaParameters.java +++ b/src/ltsa/LtsaParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class LtsaParameters implements Cloneable, Serializable, ManagedParameters { @@ -35,7 +36,7 @@ public class LtsaParameters implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } } diff --git a/src/mapgrouplocaliser/MapGrouperSettings.java b/src/mapgrouplocaliser/MapGrouperSettings.java index 955542dc..440700b7 100644 --- a/src/mapgrouplocaliser/MapGrouperSettings.java +++ b/src/mapgrouplocaliser/MapGrouperSettings.java @@ -7,6 +7,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.paneloverlay.OverlayDataInfo; import PamView.paneloverlay.overlaymark.MarkDataSelectorParams; import PamView.paneloverlay.overlaymark.OverlayMarkDataInfo; @@ -64,7 +65,7 @@ public class MapGrouperSettings implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("markDataSelectorParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/matchedTemplateClassifer/MTClassifier.java b/src/matchedTemplateClassifer/MTClassifier.java index ddde2bc7..9065daac 100644 --- a/src/matchedTemplateClassifer/MTClassifier.java +++ b/src/matchedTemplateClassifer/MTClassifier.java @@ -15,6 +15,7 @@ import Localiser.DelayMeasurementParams; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamArrayUtils; import PamUtils.PamInterp; import PamUtils.complex.ComplexArray; @@ -629,7 +630,7 @@ public class MTClassifier implements Serializable, Cloneable, ManagedParameters */ @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("inteprWaveformReject"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/matchedTemplateClassifer/MatchTemplate.java b/src/matchedTemplateClassifer/MatchTemplate.java index 7f758ddf..0990a22d 100644 --- a/src/matchedTemplateClassifer/MatchTemplate.java +++ b/src/matchedTemplateClassifer/MatchTemplate.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.RawDataHolder; import PamguardMVC.RawDataTransforms; @@ -51,7 +52,7 @@ public class MatchTemplate implements RawDataHolder, Serializable, Cloneable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/matchedTemplateClassifer/MatchedTemplateParams.java b/src/matchedTemplateClassifer/MatchedTemplateParams.java index 05f8b107..edd2b912 100644 --- a/src/matchedTemplateClassifer/MatchedTemplateParams.java +++ b/src/matchedTemplateClassifer/MatchedTemplateParams.java @@ -8,6 +8,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamView.PamSymbolType; import PamView.symbol.SymbolData; import fftFilter.FFTFilterParams; @@ -150,7 +151,7 @@ public class MatchedTemplateParams implements Serializable, Cloneable, ManagedPa @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("fftFilterParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java b/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java index acf38f67..3b248ea9 100644 --- a/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java +++ b/src/matchedTemplateClassifer/annotation/MatchedClickAnnotationSQL.java @@ -7,6 +7,7 @@ import java.util.List; import PamUtils.PamArrayUtils; import PamguardMVC.PamDataUnit; import PamguardMVC.debug.Debug; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -49,7 +50,7 @@ public class MatchedClickAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(typeTable); pamTableDefinition.addTableItem(mtThresholdsTable); pamTableDefinition.addTableItem(mtMatchCorrsTable); @@ -58,7 +59,7 @@ public class MatchedClickAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { MatchedClickAnnotation clickAnnotation = (MatchedClickAnnotation) pamDataUnit.findDataAnnotation(MatchedClickAnnotation.class); @@ -95,7 +96,7 @@ public class MatchedClickAnnotationSQL implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { String threshold = mtThresholdsTable.getDeblankedStringValue(); String mtMatchCorrs = mtMatchCorrsTable.getDeblankedStringValue(); diff --git a/src/mcc/mccacquisition/MCCDaqParams.java b/src/mcc/mccacquisition/MCCDaqParams.java index f1fc3450..ba44c99e 100644 --- a/src/mcc/mccacquisition/MCCDaqParams.java +++ b/src/mcc/mccacquisition/MCCDaqParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import Acquisition.DaqSystemXMLManager; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import analoginput.AnalogRangeData; import simulatedAcquisition.SimProcess; @@ -51,7 +52,7 @@ public class MCCDaqParams implements Serializable, Cloneable, ManagedParameters return null; } - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/metadata/MetaDataContol.java b/src/metadata/MetaDataContol.java new file mode 100644 index 00000000..98093b08 --- /dev/null +++ b/src/metadata/MetaDataContol.java @@ -0,0 +1,114 @@ +package metadata; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.Serializable; + +import javax.swing.JFrame; +import javax.swing.JMenuItem; + +import PamController.PamControlledUnit; +import PamController.PamControlledUnitSettings; +import PamController.PamController; +import PamController.PamSettingManager; +import PamController.PamSettings; +import metadata.swing.MetaDataDialog; + +/** + * Class to handle Project MetaData. Am making this a PAMControlledUnit, but may never + * register it with the model ? Will see what advantages and disadvantages there are. + * @author dg50 + * + */ +public class MetaDataContol extends PamControlledUnit implements PamSettings { + + public static final String unitType = "Meta Data"; + + private static MetaDataContol singleInstance; + + private PamguardMetaData pamguardMetaData = new PamguardMetaData(); + +// private ParameterSetManager deploymentSetManager; + + + private MetaDataContol(String unitName) { + super(unitType, unitName); +// deploymentSetManager = new ParameterSetManager(deploymentData, "Deployment Data"); + PamSettingManager.getInstance().registerSettings(this); + } + + /** + * Easy getter for singleton MetaData controller. + * @return meta data controller + */ + public static MetaDataContol getMetaDataControl() { + if (singleInstance == null) { + singleInstance = new MetaDataContol(unitType); + // add this line to add it to the main modules list. Then it will get menu's, etc. + PamController.getInstance().addControlledUnit(singleInstance); + } + return singleInstance; + } + + /** + * Get PAMGuard Metadata. This contains a nilus Deployment object wrapped up + * so that it can be serialised into other PAMGuard settings. + * @return PAMGuard meta data + */ + public PamguardMetaData getMetaData() { + return pamguardMetaData; + } + + /** + * Set the meta data object. + * @param metaData + */ + public void setMetaData(PamguardMetaData metaData) { + this.pamguardMetaData = metaData; + } + + @Override + public Serializable getSettingsReference() { + pamguardMetaData.checkSerialisation(); + return pamguardMetaData; + } + + @Override + public long getSettingsVersion() { + return PamguardMetaData.serialVersionUID; + } + + @Override + public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { + Object obj = pamControlledUnitSettings.getSettings(); + if (obj instanceof PamguardMetaData) { + pamguardMetaData = (PamguardMetaData) obj; + return true; + } + return false; + } + +// @Override + public JMenuItem createMenu(JFrame parentFrame) { + JMenuItem menuItem = new JMenuItem("Project information ..."); + menuItem.setToolTipText("General project objectives, region, etc."); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showDialog(parentFrame); + } + }); + return menuItem; + } + + protected void showDialog(JFrame parentFrame) { + PamguardMetaData newData = MetaDataDialog.showDialog(parentFrame, pamguardMetaData); + if (newData != null) { + this.pamguardMetaData = newData; + // send around a notification ? + } + } + + + +} diff --git a/src/metadata/PamguardMetaData.java b/src/metadata/PamguardMetaData.java new file mode 100644 index 00000000..ae4064ab --- /dev/null +++ b/src/metadata/PamguardMetaData.java @@ -0,0 +1,111 @@ +package metadata; + +import java.io.Serializable; + +import PamUtils.LatLong; +import nilus.ContactInfo; +import nilus.Deployment; +import nilus.DeploymentRecoveryDetails; +import nilus.DescriptionType; +import nilus.Helper; +import nilus.MetadataInfo; +import nilus.ResponsibleParty; +import tethys.niluswraps.NilusSettingsWrapper; + +/** + * Meta data for a PAMGuard data set. This is based around serialisable versions of + * nilus classes to be compliant with both Tethys and PAMGuard settings files. May only + * need a Deployment object, but scope for adding others / other fields if it's useful. + * @author dg50 + * + */ +public class PamguardMetaData implements Serializable { + + public static final long serialVersionUID = 1L; + + private NilusSettingsWrapper deploymentWrapper; + + public boolean useAudioForDeploymentTimes = true; + +// /** +// * Deployment time (used if different +// */ +// private Long deploymentMillis; +// +// private Long recoverMillis; +// +// private LatLong recoverLatLong; + + /** + * Get the deployment data + * @return nilus deployment + */ + public Deployment getDeployment() { + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + Deployment deployment = deploymentWrapper.getNilusObject(Deployment.class); + if (deployment == null) { + deployment = new Deployment(); + try { + Helper.createRequiredElements(deployment); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + deploymentWrapper.setNilusObject(deployment); + } + // check some fields we know we'll need that the Helper may not have managed. + if (deployment.getDescription() == null) { + deployment.setDescription(new DescriptionType()); + } + if (deployment.getMetadataInfo() == null) { + deployment.setMetadataInfo(new MetadataInfo()); + } + if (deployment.getMetadataInfo().getContact() == null) { + deployment.getMetadataInfo().setContact(new ResponsibleParty()); + } + if (deployment.getMetadataInfo().getContact().getContactInfo() == null) { + deployment.getMetadataInfo().getContact().setContactInfo(new ContactInfo()); + } + + if (deployment.getDeploymentDetails() == null) { + deployment.setDeploymentDetails(new DeploymentRecoveryDetails()); + } + if (deployment.getRecoveryDetails() == null) { + deployment.setRecoveryDetails(new DeploymentRecoveryDetails()); + } + return deployment; + } + + /** + * Set the deployment data. + * @param deployment nilus deployment + */ + public void setDeployment(Deployment deployment) { + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + deploymentWrapper.setNilusObject(deployment); + } + + /** + * @return the deploymentWrapper + */ + public NilusSettingsWrapper getDeploymentWrapper() { + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + return deploymentWrapper; + } + + public void checkSerialisation() { + // check that all wrappers have their xml up to date. + if (deploymentWrapper == null) { + deploymentWrapper = new NilusSettingsWrapper<>(); + } + deploymentWrapper.reSerialise(); + } + + + +} diff --git a/src/metadata/swing/MetaDataDialog.java b/src/metadata/swing/MetaDataDialog.java new file mode 100644 index 00000000..9f744391 --- /dev/null +++ b/src/metadata/swing/MetaDataDialog.java @@ -0,0 +1,121 @@ +package metadata.swing; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Window; + +import javax.swing.BoxLayout; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.border.TitledBorder; + +import PamController.PamController; +import PamView.dialog.PamDialog; +import PamView.panel.PamNorthPanel; +import PamView.panel.WestAlignedPanel; +import metadata.PamguardMetaData; +import nilus.Deployment; +import tethys.TethysControl; +import tethys.TethysState; +import tethys.TethysState.StateType; +import tethys.deployment.swing.ProjectInformationPanel; +import tethys.swing.export.DeploymentPeriodPanel; +import tethys.swing.export.DescriptionTypePanel; +import tethys.swing.export.ResponsiblePartyPanel; + +public class MetaDataDialog extends PamDialog { + + private static MetaDataDialog singleInstance; + + private PamguardMetaData pamguardMetaData; + + private DescriptionTypePanel descriptionPanel; + + private ProjectInformationPanel projectInformationPanel; + + private DeploymentPeriodPanel deploymentPeriodPanel; + + private ResponsiblePartyPanel responsiblePanel; + + private TethysControl tethysControl; + + private MetaDataDialog(Window parentFrame) { + super(parentFrame, "Project information", false); + + JPanel mainPanel = new JPanel(); + mainPanel.setLayout(new BorderLayout()); + JTabbedPane tabbedPane = new JTabbedPane(); + + tethysControl = (TethysControl) PamController.getInstance().findControlledUnit(TethysControl.unitType); + + projectInformationPanel = new ProjectInformationPanel(parentFrame, null); + descriptionPanel = new DescriptionTypePanel(null, false, false, false); + deploymentPeriodPanel = new DeploymentPeriodPanel(parentFrame); + descriptionPanel.getMainPanel().setPreferredSize(new Dimension(400,300)); + + responsiblePanel = new ResponsiblePartyPanel(); + JPanel northPanel = new JPanel(); + WestAlignedPanel wp; + northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS)); + + northPanel.add(wp = new WestAlignedPanel(projectInformationPanel.getMainPanel())); + wp.setBorder(new TitledBorder("General project information")); + northPanel.add(wp = new WestAlignedPanel(responsiblePanel.getMainPanel())); + wp.setBorder(new TitledBorder("Contact information")); + + JPanel dpPanel = new WestAlignedPanel(deploymentPeriodPanel.getMainPanel()); + dpPanel.setBorder(new TitledBorder("Deployment period")); + + mainPanel.add(tabbedPane, BorderLayout.CENTER); + tabbedPane.add(northPanel, "General"); + tabbedPane.add(descriptionPanel.getMainPanel(), "Description"); + tabbedPane.add(dpPanel, "Deployment"); + + setResizable(true); + + setDialogComponent(mainPanel); + } + + + + + public static PamguardMetaData showDialog(Window frame, PamguardMetaData pamguardMetaData) { + singleInstance = new MetaDataDialog(frame); + singleInstance.setParams(pamguardMetaData); + singleInstance.setVisible(true); + return singleInstance.pamguardMetaData; + } + + private void setParams(PamguardMetaData pamguardMetaData) { + this.pamguardMetaData = pamguardMetaData; + Deployment deployment = pamguardMetaData.getDeployment(); + projectInformationPanel.setParams(deployment); + descriptionPanel.setParams(deployment.getDescription()); + responsiblePanel.setParams(deployment.getMetadataInfo().getContact()); + deploymentPeriodPanel.setParams(pamguardMetaData); + } + + @Override + public boolean getParams() { + Deployment deployment = pamguardMetaData.getDeployment(); + boolean ok = descriptionPanel.getParams(deployment.getDescription()); + ok &= responsiblePanel.getParams(deployment.getMetadataInfo().getContact()); + ok &= deploymentPeriodPanel.getParams(pamguardMetaData); + + if (tethysControl != null) { + tethysControl.sendStateUpdate(new TethysState(StateType.NEWPROJECTSELECTION)); + } + return ok; + } + + @Override + public void cancelButtonPressed() { + pamguardMetaData = null; + } + + @Override + public void restoreDefaultSettings() { + + } + +} diff --git a/src/networkTransfer/emulator/EmulatorParams.java b/src/networkTransfer/emulator/EmulatorParams.java index e4fe0f74..3f38266a 100644 --- a/src/networkTransfer/emulator/EmulatorParams.java +++ b/src/networkTransfer/emulator/EmulatorParams.java @@ -8,6 +8,7 @@ import PamController.PamControlledUnitSettings; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.LatLong; public class EmulatorParams implements Cloneable, Serializable, ManagedParameters { @@ -50,7 +51,7 @@ public class EmulatorParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("circleRadius"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/networkTransfer/receive/BuoyStatusData.java b/src/networkTransfer/receive/BuoyStatusData.java index 6b17a6ad..8138f4bf 100644 --- a/src/networkTransfer/receive/BuoyStatusData.java +++ b/src/networkTransfer/receive/BuoyStatusData.java @@ -5,6 +5,7 @@ import java.util.Hashtable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; /** @@ -140,7 +141,7 @@ public class BuoyStatusData implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/networkTransfer/receive/BuoyStatusValue.java b/src/networkTransfer/receive/BuoyStatusValue.java index d73a5acd..a42ea7ff 100644 --- a/src/networkTransfer/receive/BuoyStatusValue.java +++ b/src/networkTransfer/receive/BuoyStatusValue.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamUtils.PamCalendar; public class BuoyStatusValue implements Serializable, ManagedParameters { @@ -53,7 +54,7 @@ public class BuoyStatusValue implements Serializable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/networkTransfer/receive/NetworkReceiveParams.java b/src/networkTransfer/receive/NetworkReceiveParams.java index f067c789..488899c5 100644 --- a/src/networkTransfer/receive/NetworkReceiveParams.java +++ b/src/networkTransfer/receive/NetworkReceiveParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NetworkReceiveParams implements Cloneable, Serializable, ManagedParameters { @@ -40,7 +41,7 @@ public class NetworkReceiveParams implements Cloneable, Serializable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/networkTransfer/send/NetworkSendParams.java b/src/networkTransfer/send/NetworkSendParams.java index 9e0024d8..87e25b0c 100644 --- a/src/networkTransfer/send/NetworkSendParams.java +++ b/src/networkTransfer/send/NetworkSendParams.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamguardMVC.PamDataBlock; public class NetworkSendParams implements Serializable, Cloneable, ManagedParameters { @@ -108,7 +109,7 @@ public class NetworkSendParams implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("selectedDataBlocks"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/nidaqdev/networkdaq/NIDaqLogging.java b/src/nidaqdev/networkdaq/NIDaqLogging.java index dc12309b..75022e5c 100644 --- a/src/nidaqdev/networkdaq/NIDaqLogging.java +++ b/src/nidaqdev/networkdaq/NIDaqLogging.java @@ -3,6 +3,7 @@ package nidaqdev.networkdaq; import java.sql.Types; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -20,12 +21,12 @@ public class NIDaqLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(crioTemperature); } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { Double lastTemp = niNetworkDaq.getLastTemperature(); if (lastTemp == null) { crioTemperature.setValue(null); @@ -38,7 +39,7 @@ public class NIDaqLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { // TODO Auto-generated method stub return false; } diff --git a/src/nidaqdev/networkdaq/NINetworkDaqParams.java b/src/nidaqdev/networkdaq/NINetworkDaqParams.java index 7458739e..a7f67845 100644 --- a/src/nidaqdev/networkdaq/NINetworkDaqParams.java +++ b/src/nidaqdev/networkdaq/NINetworkDaqParams.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import Acquisition.DaqSystemXMLManager; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NINetworkDaqParams implements Serializable, Cloneable, ManagedParameters { @@ -169,7 +170,7 @@ public class NINetworkDaqParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { if (DaqSystemXMLManager.isSelected(NINetworkDaq.systemName)) { - return PamParameterSet.autoGenerate(this); + return PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); } return null; } diff --git a/src/nmeaEmulator/NMEAEmulatorParams.java b/src/nmeaEmulator/NMEAEmulatorParams.java index 1889ca17..d7b89529 100644 --- a/src/nmeaEmulator/NMEAEmulatorParams.java +++ b/src/nmeaEmulator/NMEAEmulatorParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NMEAEmulatorParams implements Serializable, Cloneable, ManagedParameters { @@ -23,7 +24,7 @@ public class NMEAEmulatorParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/noiseBandMonitor/NoiseBandSettings.java b/src/noiseBandMonitor/NoiseBandSettings.java index d905c536..8f00571c 100644 --- a/src/noiseBandMonitor/NoiseBandSettings.java +++ b/src/noiseBandMonitor/NoiseBandSettings.java @@ -7,6 +7,7 @@ import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class NoiseBandSettings implements Serializable, Cloneable, ManagedParameters { @@ -59,7 +60,7 @@ public class NoiseBandSettings implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("showStandard"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseMonitor/NoiseDataBlock.java b/src/noiseMonitor/NoiseDataBlock.java index b5e7f628..effbd591 100644 --- a/src/noiseMonitor/NoiseDataBlock.java +++ b/src/noiseMonitor/NoiseDataBlock.java @@ -2,11 +2,18 @@ package noiseMonitor; import noiseMonitor.alarm.NoiseAlarmCounter; import noiseMonitor.alarm.NoiseAlarmProvider; +import noiseMonitor.species.TethysNoiseDataProvider; +import tethys.TethysControl; +import tethys.pamdata.TethysDataProvider; +import tethys.species.DataBlockSpeciesManager; +import tethys.species.FixedSpeciesManager; import alarm.AlarmCounter; import alarm.AlarmCounterProvider; import alarm.AlarmDataSource; import PamUtils.FrequencyFormat; import PamUtils.PamUtils; +import PamguardMVC.DataAutomation; +import PamguardMVC.DataAutomationInfo; import PamguardMVC.PamDataBlock; import PamguardMVC.PamProcess; @@ -32,13 +39,15 @@ public class NoiseDataBlock extends PamDataBlock implements Alarm private NoiseAlarmProvider noiseAlarmCounter; /** - * These are the names used in the database columns, so dont' change them on pain of + * These are the names used in the database columns, so don't change them on pain of * nothing ever working ever again ! */ public static final String[] measureNames = {"mean", "median", "low95", "high95", "Min", "Max", "Peak"}; public static final String[] displayNames = {"Mean", "Median", "Lower 95%", "Upper 95%", "Minimum", "Maximim", "Peak"}; private int statisticTypes; + private TethysNoiseDataProvider tethysNoiseDataProvider; + private FixedSpeciesManager fixedSpeciesManager; public NoiseDataBlock(String dataName, PamProcess parentProcess, int channelMap) { @@ -244,6 +253,27 @@ public class NoiseDataBlock extends PamDataBlock implements Alarm } return noiseAlarmCounter; } + + @Override + public DataAutomationInfo getDataAutomationInfo() { + return new DataAutomationInfo(DataAutomation.AUTOMATIC); + } + + @Override + public TethysDataProvider getTethysDataProvider(TethysControl tethysControl) { + if (tethysNoiseDataProvider == null) { + tethysNoiseDataProvider = new TethysNoiseDataProvider(tethysControl, this); + } + return tethysNoiseDataProvider; + } + + @Override + public DataBlockSpeciesManager getDatablockSpeciesManager() { + if (fixedSpeciesManager == null) { + fixedSpeciesManager = new FixedSpeciesManager(this, -10, "anthropogenic", "noise"); + } + return fixedSpeciesManager; + } } diff --git a/src/noiseMonitor/NoiseDisplaySettings.java b/src/noiseMonitor/NoiseDisplaySettings.java index 7ef4f5de..b70db3ac 100644 --- a/src/noiseMonitor/NoiseDisplaySettings.java +++ b/src/noiseMonitor/NoiseDisplaySettings.java @@ -6,6 +6,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class NoiseDisplaySettings implements Serializable, Cloneable, ManagedParameters { @@ -70,7 +71,7 @@ public class NoiseDisplaySettings implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("displayLengthSeconds"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseMonitor/NoiseLogging.java b/src/noiseMonitor/NoiseLogging.java index 4bbc0cfd..a3a62d61 100644 --- a/src/noiseMonitor/NoiseLogging.java +++ b/src/noiseMonitor/NoiseLogging.java @@ -116,5 +116,27 @@ public class NoiseLogging extends SQLLogging { } } } + + private long lastTime; + + @Override + protected PamDataUnit createDataUnit(SQLTypes sqlTypes, long timeMilliseconds, int databaseIndex) { + int chan = channelNumber.getIntegerValue(); + int nBands = noiseDataBlock.getBandLoEdges().length; + int nMeasures = noiseDataBlock.getUsedMeasureNames().length; + if (nMeasures * nBands != bandItems.length) { + return null; + } + double[][] bandData = new double[nBands][nMeasures]; + for (int iBand = 0, iCol = 0; iBand < nBands; iBand++) { + for (int iMeasure = 0; iMeasure < nMeasures; iMeasure++, iCol++) { + bandData[iBand][iMeasure] = bandItems[iCol].getDoubleValue(); + } + } + + NoiseDataUnit noiseDataUnit = new NoiseDataUnit(timeMilliseconds, 1< measurements = params.getFrequencyMeasurementsDB(); + double[][] noiseData = noiseDataUnit.getNoiseBandData(); + int meanIndex = -1; + for (int i = 0; i < nTypes; i++) { + int type = PamUtils.getNthChannel(i, statTypes); + String name = noiseDataBlock.getMeasureName(type); + if (1< effortKinds, + StreamExportParams exportParams) { + super.getEffortKinds(pDeployment, effortKinds, exportParams); + DetectionEffortKind kind = effortKinds.get(0); + nilus.DetectionEffortKind.Parameters params = kind.getParameters(); + if (params == null) { + params = new nilus.DetectionEffortKind.Parameters(); + try { + Helper.createRequiredElements(params); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + kind.setParameters(params); + } + List fMeasures = params.getFrequencyMeasurementsHz(); + double[] loEdges = noiseDataBlock.getBandLoEdges(); + double[] hiEdges = noiseDataBlock.getBandHiEdges(); + // put lot mean into the array + for (int i = 0; i < loEdges.length; i++) { + fMeasures.add(roundSignificantFigures(Math.sqrt(loEdges[i]*hiEdges[i]), 4)); + } + } + + @Override + public boolean wantExportDialogCard(ExportWizardCard wizPanel) { + if (wizPanel.getClass() == GranularityCard.class) { + return false; + } + return super.wantExportDialogCard(wizPanel); + } + +} diff --git a/src/noiseOneBand/OneBandAlarmParameters.java b/src/noiseOneBand/OneBandAlarmParameters.java index 90a1659c..3e4e5a69 100644 --- a/src/noiseOneBand/OneBandAlarmParameters.java +++ b/src/noiseOneBand/OneBandAlarmParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OneBandAlarmParameters implements Serializable, Cloneable, ManagedParameters { @@ -37,7 +38,7 @@ public class OneBandAlarmParameters implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/noiseOneBand/OneBandDisplayParams.java b/src/noiseOneBand/OneBandDisplayParams.java index 04cf01d7..fe9b7a82 100644 --- a/src/noiseOneBand/OneBandDisplayParams.java +++ b/src/noiseOneBand/OneBandDisplayParams.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; public class OneBandDisplayParams implements Serializable, Cloneable, ManagedParameters { @@ -61,7 +62,7 @@ public class OneBandDisplayParams implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("displayChannels"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseOneBand/OneBandParameters.java b/src/noiseOneBand/OneBandParameters.java index b35e4f68..ea2f3320 100644 --- a/src/noiseOneBand/OneBandParameters.java +++ b/src/noiseOneBand/OneBandParameters.java @@ -10,6 +10,7 @@ import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OneBandParameters implements Serializable, Cloneable, ManagedParameters { @@ -235,7 +236,7 @@ public class OneBandParameters implements Serializable, Cloneable, ManagedParame @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("filterParams"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/noiseOneBand/offline/OneBandSummaryParams.java b/src/noiseOneBand/offline/OneBandSummaryParams.java index 7565c6e7..14e71708 100644 --- a/src/noiseOneBand/offline/OneBandSummaryParams.java +++ b/src/noiseOneBand/offline/OneBandSummaryParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class OneBandSummaryParams implements Serializable, Cloneable, ManagedParameters { @@ -23,7 +24,7 @@ public class OneBandSummaryParams implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/offlineProcessing/TaskGroupParams.java b/src/offlineProcessing/TaskGroupParams.java index 25497c24..c04a88cc 100644 --- a/src/offlineProcessing/TaskGroupParams.java +++ b/src/offlineProcessing/TaskGroupParams.java @@ -8,6 +8,7 @@ import java.util.Arrays; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameter control for offline task groups. @@ -137,7 +138,7 @@ public class TaskGroupParams implements Cloneable, Serializable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("taskSelection"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/pamMaths/PamVector.java b/src/pamMaths/PamVector.java index 910e0bc9..d491f01e 100644 --- a/src/pamMaths/PamVector.java +++ b/src/pamMaths/PamVector.java @@ -382,7 +382,7 @@ public class PamVector implements Serializable, Cloneable, PamCoordinate, Manage * @return magnitude of those dimensions only. */ public double norm(int nDim) { - return Math.sqrt(normSquared(2)); + return Math.sqrt(normSquared(nDim)); } /** * diff --git a/src/pamguard/Pamguard.java b/src/pamguard/Pamguard.java index a80c16cc..ee3936fc 100644 --- a/src/pamguard/Pamguard.java +++ b/src/pamguard/Pamguard.java @@ -717,6 +717,47 @@ public class Pamguard { } } } + /* + * Some bits that need added to Maven POM. + * + + + org.eclipse.persistence + org.eclipse.persistence.moxy + 2.5.0 + + + javax.xml.bind + jaxb-api + 2.4.0-b180830.0359 + + + org.glassfish.jaxb + jaxb-runtime + 2.4.0-b180830.0438 + + + org.glassfish.jaxb + jaxb-xjc + 2.4.0-b180830.0438 + + + + */ } diff --git a/src/quickAnnotation/QuickAnnotationParameters.java b/src/quickAnnotation/QuickAnnotationParameters.java index fd8ed2a7..65e3b05b 100644 --- a/src/quickAnnotation/QuickAnnotationParameters.java +++ b/src/quickAnnotation/QuickAnnotationParameters.java @@ -9,6 +9,7 @@ import PamController.PamSettingManager; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import difar.DifarControl; import difar.DifarParameters; import generalDatabase.lookupTables.LookupItem; @@ -96,7 +97,7 @@ public class QuickAnnotationParameters implements Serializable, Cloneable, Manag @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("exportClips"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java b/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java index 7ad1ffb9..41ef495e 100644 --- a/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java +++ b/src/rawDeepLearningClassifier/dataPlotFX/DLPredDisplayParams.java @@ -3,6 +3,7 @@ package rawDeepLearningClassifier.dataPlotFX; import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import javafx.scene.paint.Color; /** @@ -25,7 +26,7 @@ public class DLPredDisplayParams implements Serializable, Cloneable, ManagedPara @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java b/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java index 72761199..b046b27b 100644 --- a/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java +++ b/src/rawDeepLearningClassifier/logging/DLAnnotationSQL.java @@ -1,6 +1,7 @@ package rawDeepLearningClassifier.logging; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.SQLLoggingAddon; import generalDatabase.SQLTypes; @@ -12,19 +13,19 @@ public class DLAnnotationSQL implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { // TODO Auto-generated method stub } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { // TODO Auto-generated method stub return false; } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { // TODO Auto-generated method stub return false; } diff --git a/src/rocca/RoccaParameters.java b/src/rocca/RoccaParameters.java index bec1fecb..c7db4aae 100644 --- a/src/rocca/RoccaParameters.java +++ b/src/rocca/RoccaParameters.java @@ -30,6 +30,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters for Rocca
@@ -856,7 +857,7 @@ public class RoccaParameters implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("runAncCalcs4Clicks"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/seismicVeto/VetoParameters.java b/src/seismicVeto/VetoParameters.java index 0ca08357..e41907f7 100644 --- a/src/seismicVeto/VetoParameters.java +++ b/src/seismicVeto/VetoParameters.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class VetoParameters implements Serializable, Cloneable, ManagedParameters { @@ -40,7 +41,7 @@ public class VetoParameters implements Serializable, Cloneable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("backgroundConstant"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/serialComms/SerialPortParameters.java b/src/serialComms/SerialPortParameters.java index bb9d699c..373852fd 100644 --- a/src/serialComms/SerialPortParameters.java +++ b/src/serialComms/SerialPortParameters.java @@ -29,6 +29,7 @@ import com.fazecast.jSerialComm.SerialPort; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * @author David McLaren, Paul Redmond @@ -166,7 +167,7 @@ public class SerialPortParameters implements Serializable, Cloneable, ManagedPar @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/simulatedAcquisition/SimObject.java b/src/simulatedAcquisition/SimObject.java index 053c8a9b..335139fb 100644 --- a/src/simulatedAcquisition/SimObject.java +++ b/src/simulatedAcquisition/SimObject.java @@ -5,6 +5,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; import PamModel.parametermanager.PrivatePamParameterData; import simulatedAcquisition.movement.MovementModel; import simulatedAcquisition.movement.MovementModels; @@ -150,7 +151,7 @@ public class SimObject implements Serializable, Cloneable, ManagedParameters { @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); try { Field field = this.getClass().getDeclaredField("depth"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/simulatedAcquisition/movement/CircularMovementParams.java b/src/simulatedAcquisition/movement/CircularMovementParams.java index 4fe63e95..c956209e 100644 --- a/src/simulatedAcquisition/movement/CircularMovementParams.java +++ b/src/simulatedAcquisition/movement/CircularMovementParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class CircularMovementParams implements Serializable, Cloneable, ManagedParameters { @@ -84,7 +85,7 @@ public class CircularMovementParams implements Serializable, Cloneable, ManagedP @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/simulatedAcquisition/movement/GridMovementParams.java b/src/simulatedAcquisition/movement/GridMovementParams.java index 210ac943..72ae6cb2 100644 --- a/src/simulatedAcquisition/movement/GridMovementParams.java +++ b/src/simulatedAcquisition/movement/GridMovementParams.java @@ -6,6 +6,7 @@ import java.lang.reflect.Field; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class GridMovementParams implements Serializable, Cloneable, ManagedParameters { @@ -42,7 +43,7 @@ public class GridMovementParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("distRangeMetres"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/soundPlayback/PlaybackParameters.java b/src/soundPlayback/PlaybackParameters.java index 08c1e56a..2d7d22d1 100644 --- a/src/soundPlayback/PlaybackParameters.java +++ b/src/soundPlayback/PlaybackParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; /** * Parameters controlling sound playback @@ -165,7 +166,7 @@ public class PlaybackParameters implements Cloneable, Serializable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/soundPlayback/preprocess/EnvelopeParams.java b/src/soundPlayback/preprocess/EnvelopeParams.java index b3e0587c..7dd143e9 100644 --- a/src/soundPlayback/preprocess/EnvelopeParams.java +++ b/src/soundPlayback/preprocess/EnvelopeParams.java @@ -7,6 +7,7 @@ import Filters.FilterParams; import Filters.FilterType; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class EnvelopeParams implements Cloneable, Serializable, ManagedParameters { @@ -87,7 +88,7 @@ public class EnvelopeParams implements Cloneable, Serializable, ManagedParameter @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DISPLAY); return ps; } diff --git a/src/soundtrap/STClickControl.java b/src/soundtrap/STClickControl.java index 203357fe..8e7ca7b0 100644 --- a/src/soundtrap/STClickControl.java +++ b/src/soundtrap/STClickControl.java @@ -37,6 +37,7 @@ import javax.swing.JSeparator; import org.pamguard.x3.sud.SUDClickDetectorInfo; import Acquisition.AcquisitionControl; +import PamController.PamSensor; import PamController.PamControlledUnitSettings; import PamController.PamController; import PamController.PamSettingManager; @@ -54,7 +55,7 @@ import soundtrap.sud.SudFileDWVHandler; * @author mo55 * */ -public class STClickControl extends ClickControl { +public class STClickControl extends ClickControl implements PamSensor { private SUDClickDetectorInfo sudClickDetectorInfo; @@ -229,6 +230,17 @@ public class STClickControl extends ClickControl { public void setSudClickDetectorInfo(SUDClickDetectorInfo sudClickDetectorInfo) { this.sudClickDetectorInfo = sudClickDetectorInfo; } + + @Override + public String getSensorDescription() { + String desc = String.format("SoundTrap Click Detector at %dHz", (int) getClickDataBlock().getSampleRate()); + return desc; + } + + @Override + public String getSensorId() { + return null; + } /** * Class to handle SoundTrap click detector settings without messing up diff --git a/src/soundtrap/STToolsParams.java b/src/soundtrap/STToolsParams.java index 722c6fb6..514b96d6 100644 --- a/src/soundtrap/STToolsParams.java +++ b/src/soundtrap/STToolsParams.java @@ -5,6 +5,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class STToolsParams implements Serializable, Cloneable, ManagedParameters { @@ -62,7 +63,7 @@ public class STToolsParams implements Serializable, Cloneable, ManagedParameters @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java b/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java index 0931c963..9cfa3765 100644 --- a/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java +++ b/src/spectrogramNoiseReduction/SpectrogramNoiseSettings.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; import PamModel.parametermanager.PrivatePamParameterData; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class SpectrogramNoiseSettings implements Serializable, Cloneable, ManagedParameters { @@ -79,7 +80,7 @@ public class SpectrogramNoiseSettings implements Serializable, Cloneable, Manage @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); try { Field field = this.getClass().getDeclaredField("runMethod"); ps.put(new PrivatePamParameterData(this, field) { diff --git a/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java b/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java index 23e9f1f7..18f1811e 100644 --- a/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java +++ b/src/spectrogramNoiseReduction/averageSubtraction/AverageSubtractionParameters.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class AverageSubtractionParameters implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class AverageSubtractionParameters implements Serializable, Cloneable, Ma @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java b/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java index fe91beba..c24aed99 100644 --- a/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java +++ b/src/spectrogramNoiseReduction/medianFilter/MedianFilterParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class MedianFilterParams implements Serializable, Cloneable, ManagedParameters { @@ -25,7 +26,7 @@ public class MedianFilterParams implements Serializable, Cloneable, ManagedParam @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/spectrogramNoiseReduction/threshold/ThresholdParams.java b/src/spectrogramNoiseReduction/threshold/ThresholdParams.java index 8842e6e0..5674d577 100644 --- a/src/spectrogramNoiseReduction/threshold/ThresholdParams.java +++ b/src/spectrogramNoiseReduction/threshold/ThresholdParams.java @@ -4,6 +4,7 @@ import java.io.Serializable; import PamModel.parametermanager.ManagedParameters; import PamModel.parametermanager.PamParameterSet; +import PamModel.parametermanager.PamParameterSet.ParameterSetType; public class ThresholdParams implements Serializable, Cloneable, ManagedParameters { @@ -27,7 +28,7 @@ public class ThresholdParams implements Serializable, Cloneable, ManagedParamete @Override public PamParameterSet getParameterSet() { - PamParameterSet ps = PamParameterSet.autoGenerate(this); + PamParameterSet ps = PamParameterSet.autoGenerate(this, ParameterSetType.DETECTOR); return ps; } diff --git a/src/targetMotionOld/TargetMotionSQLLogging.java b/src/targetMotionOld/TargetMotionSQLLogging.java index 6017a12b..4f4f133e 100644 --- a/src/targetMotionOld/TargetMotionSQLLogging.java +++ b/src/targetMotionOld/TargetMotionSQLLogging.java @@ -15,6 +15,7 @@ import PamDetection.AbstractLocalisation; import PamDetection.LocContents; import PamUtils.LatLong; import PamguardMVC.PamDataUnit; +import generalDatabase.EmptyTableDefinition; import generalDatabase.PamTableDefinition; import generalDatabase.PamTableItem; import generalDatabase.SQLLoggingAddon; @@ -119,7 +120,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { } @Override - public void addTableItems(PamTableDefinition pamTableDefinition) { + public void addTableItems(EmptyTableDefinition pamTableDefinition) { pamTableDefinition.addTableItem(modelName); @@ -146,7 +147,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { } @Override - public boolean saveData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + public boolean saveData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { AbstractLocalisation tmResult = pamDataUnit.getLocalisation(); clearEverything(); @@ -218,7 +219,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { return true; } - private boolean saveGroupLocalisation(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + private boolean saveGroupLocalisation(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit, GroupLocalisation groupLocalisation) { int nAmbiguities = groupLocalisation.getAmbiguityCount(); @@ -239,7 +240,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { return true; } - private boolean saveGroupLocalisation(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + private boolean saveGroupLocalisation(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit, int resultIndex, GroupLocResult tmResult) { @@ -323,7 +324,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { } @Override - public boolean loadData(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + public boolean loadData(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit) { GroupLocalisation tml = new GroupLocalisation(pamDataUnit, null); @@ -341,7 +342,7 @@ public class TargetMotionSQLLogging implements SQLLoggingAddon { return true; } - private GroupLocResult loadLocResult(SQLTypes sqlTypes, PamTableDefinition pamTableDefinition, + private GroupLocResult loadLocResult(SQLTypes sqlTypes, EmptyTableDefinition pamTableDefinition, PamDataUnit pamDataUnit, GroupLocalisation tml, int resultIndex) { double latVal, longVal; diff --git a/src/tethys/Collection.java b/src/tethys/Collection.java new file mode 100644 index 00000000..93a6acb2 --- /dev/null +++ b/src/tethys/Collection.java @@ -0,0 +1,136 @@ +package tethys; + +/** + * Names of Tethys Collections. These are the plural names, though contain functionality + * to get the document names, which are generally the singular of the enum + * @author dg50 + * + */ +public enum Collection { + + Deployments, Detections, Calibrations, Localizations, SpeciesAbbreviations, Ensembles, SourceMaps, ITIS, ITIS_ranks, OTHER; + + /** + * A list of the main collections in the database, i.e. ones the user will + * possibly want to interract with through the GUI. + * @return list of main collections. + */ + public static Collection[] mainList() { + Collection[] cs = {Deployments, Detections, Calibrations, Localizations, SpeciesAbbreviations, Ensembles}; + return cs; + } + /** + * Get the name of a document in this collection, this is generally the singular + * of the collection name. + * @return Document name, e.g. Detection for Detections + */ + public String documentName() { + switch (this) { + case Calibrations: + return "Calibration"; + case Deployments: + return "Deployment"; + case Detections: + return "Detections"; // this one is plural ! + case Localizations: + return "Localize"; + case SpeciesAbbreviations: + return "SpeciesAbbreviation"; + case Ensembles: + return "Ensemble"; + default: + break; + } + return null; + } + + public String collectionName() { + return this.toString(); + } + + /** + * Find a collection for the given name. This does + * a bit more than the simple 'valueof' since it also + * allows the user to input a documentname in place, which + * is just the collection name without the plural 's' on the end + * @param name Collection name. + * @return Collection or null. + */ + public static Collection fromName(String name) { + Collection c = Collection.valueOf(name); + if (c != null) { + return c; + } + /** + * Otherwise, may need to do a longer search to see if the user has passed + * the singular document name. + */ + if (name.endsWith("s") == false) { + c = Collection.valueOf(name+"s"); + if (c != null) { + return c; + } + } + return null; + } + /** + * get Tethys collection name from nilus collection objects + * @param className nilus object Class Name + * @return name of Tethys collection + */ + public static Collection fromClass(Class nilusClass) { + String className = nilusClass.getName(); + switch(className) { + case "nilus.Deployment": + return Deployments; + case "nilus.Detections": + return Detections; + case "nilus.Calibration": + return Calibrations; + case "nilus.Ensemble": + return Ensembles; + case "nilus.Localization": + return Localizations; + case "nilus.SpeciesAbbreviation": + return SpeciesAbbreviations; + case "nilus.SourceMap": + return SourceMaps; + case "nilus.ITIS": + return ITIS; + case "nilus.ranks": + return ITIS_ranks; + default: + return null; + } + } +// /** +// * get Tethys collection name from nilus collection objects +// * @param className nilus object Class Name +// * @return name of Tethys collection +// */ +// public static String getCollection(Class nilusClass) { +// String className = nilusClass.getName(); +// switch(className) { +// case "nilus.Deployment": +// return "Deployments"; +// case "nilus.Detections": +// return "Detections"; +// case "nilus.Calibration": +// return "Calibrations"; +// case "nilus.Ensemble": +// return "Ensembles"; +// case "nilus.Localization": +// return "Localizations"; +// case "nilus.SpeciesAbbreviation": +// return "SpeciesAbbreviations"; +// case "nilus.SourceMap": +// return "SourceMaps"; +// case "nilus.ITIS": +// return "ITIS"; +// case "nilus.ranks": +// return "ITIS_ranks"; +// default: +// return ""; +// } +// } +} diff --git a/src/tethys/DocumentInfo.java b/src/tethys/DocumentInfo.java new file mode 100644 index 00000000..7ad2d750 --- /dev/null +++ b/src/tethys/DocumentInfo.java @@ -0,0 +1,49 @@ +package tethys; + +/** + * Basic information about a document that can be used to + * make document lists. + * @author dg50 + * + */ +public class DocumentInfo implements Comparable { + + private Collection collection; + private String documentName; + private String documentId; + + /** + * @param collection + * @param documentName + * @param documentId + */ + public DocumentInfo(Collection collection, String documentName, String documentId) { + this.collection = collection; + this.documentName = documentName; + this.documentId = documentId; + } + @Override + public int compareTo(DocumentInfo o) { + return this.documentName.compareTo(o.documentName); + } + /** + * @return the collection + */ + public Collection getCollection() { + return collection; + } + /** + * @return the documentName + */ + public String getDocumentName() { + return documentName; + } + /** + * @return the documentId + */ + public String getDocumentId() { + return documentId; + } + + +} diff --git a/src/tethys/DocumentNilusObject.java b/src/tethys/DocumentNilusObject.java new file mode 100644 index 00000000..c6b5a402 --- /dev/null +++ b/src/tethys/DocumentNilusObject.java @@ -0,0 +1,32 @@ +package tethys; + +/** + * information about a document AND the nilus object to go with it. + * @author dg50 + * + * @param + */ +public class DocumentNilusObject extends DocumentInfo { + + private T nilusObject; + + public DocumentNilusObject(Collection collection, String documentName, String documentId, T nilusObject) { + super(collection, documentName, documentId); + this.nilusObject = nilusObject; + } + + /** + * @return the nilusObject + */ + public T getNilusObject() { + return nilusObject; + } + + /** + * @param nilusObject the nilusObject to set + */ + public void setNilusObject(T nilusObject) { + this.nilusObject = nilusObject; + } + +} diff --git a/src/tethys/TethysControl.java b/src/tethys/TethysControl.java new file mode 100644 index 00000000..446face1 --- /dev/null +++ b/src/tethys/TethysControl.java @@ -0,0 +1,703 @@ +package tethys; + +import java.awt.Desktop; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import javax.swing.Timer; + +import PamController.PamControlledUnit; +import PamController.PamControlledUnitSettings; +import PamController.PamController; +import PamController.PamControllerInterface; +import PamController.PamFolders; +import PamController.PamSettingManager; +import PamController.PamSettings; +import PamUtils.PamFileChooser; +import PamUtils.PamFileFilter; +import PamView.PamTabPanel; +import PamView.dialog.warn.WarnOnce; +import PamguardMVC.PamDataBlock; +import metadata.MetaDataContol; +import metadata.PamguardMetaData; +import nilus.Deployment; +import tethys.TethysState.StateType; +import tethys.calibration.CalibrationHandler; +import tethys.dbxml.DBXMLConnect; +import tethys.dbxml.DBXMLQueries; +import tethys.dbxml.ServerStatus; +import tethys.dbxml.TethysException; +import tethys.dbxml.TethysQueryException; +import tethys.deployment.DeploymentHandler; +import tethys.detection.DetectionsHandler; +import tethys.niluswraps.PDeployment; +import tethys.output.DatablockSynchInfo; +import tethys.output.TethysExportParams; +import tethys.species.ITISFunctions; +import tethys.species.SpeciesMapManager; +import tethys.swing.ProjectDeploymentsDialog; +import tethys.swing.TethysTabPanel; +import tethys.swing.XMLStringView; +import tethys.swing.documents.TethysDocumentsFrame; + +/** + * Quick play with a simple system for outputting data to Tethys. At it's start + * this is simply going to offer a dialog and have a few functions which show how + * to access data within PAMGuard. + * @author dg50 + * + */ +public class TethysControl extends PamControlledUnit implements PamSettings, TethysStateObserver { + + public static final String unitType = "Tethys Interface"; + public static String defaultName = "Tethys"; + public static String xmlNameSpace = "http://tethys.sdsu.edu/schema/1.0"; + + private TethysExportParams tethysExportParams = new TethysExportParams(); + + private DBXMLConnect dbxmlConnect; + + private TethysTabPanel tethysTabPanel; + + private DBXMLQueries dbxmlQueries; + + private ArrayList stateObservers; + + private Timer serverCheckTimer; + + private ServerStatus lastServerStatus; + + private ArrayList dataBlockSynchInfos; + + private DeploymentHandler deploymentHandler; + private DetectionsHandler detectionsHandler; + private CalibrationHandler calibrationHandler; + + private ITISFunctions itisFunctions; + + public TethysControl(String unitName) { + super(unitType, unitName); + stateObservers = new ArrayList(); + dbxmlConnect = new DBXMLConnect(this); + dbxmlQueries = new DBXMLQueries(this, dbxmlConnect); + deploymentHandler = new DeploymentHandler(this); + detectionsHandler = new DetectionsHandler(this); + calibrationHandler = new CalibrationHandler(this); + + serverCheckTimer = new Timer(10000, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + checkServer(); + } + }); + serverCheckTimer.setInitialDelay(0); + PamSettingManager.getInstance().registerSettings(this); + addStateObserver(this); + + if (PamController.getInstance().isInitializationComplete()) { + // must be adding module later on ... + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + initializationStuff(); + } + }); + } + } + + /** + * Get DBXML Connector. This class contains all the functions that are needed + * to talk to the database. + * @return DBXML functions. + */ + public DBXMLConnect getDbxmlConnect() { + return dbxmlConnect; + } + @Override + public JMenuItem createDetectionMenu(Frame parentFrame) { + return createTethysMenu(parentFrame); + } + + @Override + public JMenuItem createFileMenu(JFrame parentFrame) { + // TODO Auto-generated method stub + return super.createFileMenu(parentFrame); + } + + /** + * Make a menu. Can go either in File or Settings. TBD. + * @param parentFrame + * @return + */ + public JMenuItem createTethysMenu(Frame parentFrame) { + JMenu tethysMenu = new JMenu("Tethys"); +// JMenuItem tethysExport = new JMenuItem("Export ..."); +// tethysMenu.add(tethysExport); +// tethysExport.addActionListener(new ActionListener() { +// @Override +// public void actionPerformed(ActionEvent e) { +// tethysExport(parentFrame); +// } +// }); + JMenuItem menuItem; + menuItem = new JMenuItem("Open client in browser"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + openTethysClient(); + } + }); + + tethysMenu.add(menuItem); + menuItem = new JMenuItem("Open temp document folder"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + openTempDocuments(); + } + }); + tethysMenu.add(menuItem); + + + JMenuItem collections = new JMenu("Collections"); + Collection[] mainCollections = Collection.mainList(); + for (int i = 0; i < mainCollections.length; i++) { + Collection col = mainCollections[i]; + menuItem = new JMenuItem("Open " + col.collectionName() + " collection in browser"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + openTethysCollection(col); + } + }); + collections.add(menuItem); + } + + tethysMenu.add(collections); + tethysMenu.addSeparator(); + JMenuItem showDeps = new JMenuItem("Show project deployments"); + showDeps.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showProjectDeploymentsDialog(); + } + }); + tethysMenu.add(showDeps); + + JMenuItem cals = new JMenuItem("Export calibrations"); + cals.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + calibrationHandler.exportAllCalibrations(); + } + }); + tethysMenu.add(cals); + + tethysMenu.addSeparator(); + JMenuItem mapItem = new JMenuItem("Export species maps ..."); + mapItem.setToolTipText("Export all species maps (PAMGuard codes to ITIS codes to file for import into other configurations"); + mapItem.addActionListener(SpeciesMapManager.getInstance().getExportAction(parentFrame)); + tethysMenu.add(mapItem); + + mapItem = new JMenuItem("Import species maps ..."); + mapItem.setToolTipText("Import species maps (PAMGuard codes to ITIS codes to file for import into other configurations"); + mapItem.addActionListener(SpeciesMapManager.getInstance().getImportAction(parentFrame)); + tethysMenu.add(mapItem); + + return tethysMenu; + } + + protected void openTempDocuments() { + File tempFolder = dbxmlConnect.checkTempFolder(); + if (tempFolder == null) { + WarnOnce.showWarning("Tethys Error", "Unable to obtain a temporary folder name", WarnOnce.WARNING_MESSAGE); + return; + } + try { +// String cmd = "explorer.exe /select," + tempFolder.getAbsolutePath() + File.separator; +// Runtime.getRuntime().exec(cmd); + Desktop.getDesktop().open(tempFolder); + } + catch(Exception e) { + e.printStackTrace(); + } + } + + public void showProjectDeploymentsDialog() { + ProjectDeploymentsDialog.showDialog(getGuiFrame(), this); + } + + public ArrayList getExportableDataBlocks() { + ArrayList sets = new ArrayList<>(); + ArrayList allDataBlocks = PamController.getInstance().getDataBlocks(); + for (PamDataBlock aDataBlock : allDataBlocks) { + if (aDataBlock.getTethysDataProvider(this) != null) { + sets.add(aDataBlock); + } + } + return sets; + } + + /** + * Get the synchronisation info for all datablocks. + * This list should be static, but check it in case something has been + * added or removed. + * @return + */ + public ArrayList getSynchronisationInfos() { + if (dataBlockSynchInfos == null) { + dataBlockSynchInfos = new ArrayList<>(); + } + ArrayList dataBlocks = getExportableDataBlocks(); + // check all datablocks are in there ... + for (PamDataBlock aBlock : dataBlocks) { + if (findDatablockSynchInfo(aBlock) == null) { + dataBlockSynchInfos.add(new DatablockSynchInfo(this, aBlock)); + } + } + // and remove any which are no longer there. + for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) { + if (!dataBlocks.contains(synchInfo.getDataBlock())) { + dataBlockSynchInfos.remove(synchInfo); + } + } + + return dataBlockSynchInfos; + } + + public DatablockSynchInfo findDatablockSynchInfo(PamDataBlock dataBlock) { + if (dataBlockSynchInfos == null) { + return null; + } + for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) { + if (synchInfo.getDataBlock() == dataBlock) { + return synchInfo; + } + } + return null; + } + + /** + * open client in the default web browser + */ + public void openTethysClient() { +// String urlString = tethysExportParams.getFullServerName() + "/Client"; +// System.out.println("Opening url " + urlString); +// URL url = null; +// try { +// url = new URL(urlString); +// } catch (MalformedURLException e) { +// e.printStackTrace(); +// } +// if (url == null) { +// return; +// } +// try { +// Desktop.getDesktop().browse(url.toURI()); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (URISyntaxException e) { +// e.printStackTrace(); +// } + openCollectionInBrowser("Client"); + } + /** + * open client in the default web browser + */ + public void openTethysCollection(Collection collection) { + if (collection == null) { + return; + } + if (getTethysExportParams().listDocsInPamguard) { + openCollectionInPAMGuard(collection); + } + else { + openCollectionInBrowser(collection.collectionName()); + } + } + public void openCollectionInPAMGuard(Collection collection) { + TethysDocumentsFrame.showTable(getGuiFrame(), this, collection); + } + + public void openCollectionInBrowser(String collectionName) { + String urlString = tethysExportParams.getFullServerName() + "/" + collectionName; +// System.out.println("Opening url " + urlString); + URL url = null; + try { + url = new URL(urlString); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + if (url == null) { + return; + } + try { + Desktop.getDesktop().browse(url.toURI()); + } catch (IOException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + } + + @Override + public PamTabPanel getTabPanel() { + if (tethysTabPanel == null) { + tethysTabPanel = new TethysTabPanel(this); + } + return tethysTabPanel; + } + + /** + * @return the tethysExportParams + */ + public TethysExportParams getTethysExportParams() { + return tethysExportParams; + } + +// /** +// * We'll probably want to +// * @param parentFrame +// */ +// protected void tethysExport(JFrame parentFrame) { +// TethysExportParams newExportParams = TethysExportDialog.showDialog(parentFrame, this); +// if (newExportParams != null) { +// // dialog returns null if cancel was pressed. +// tethysExportParams = newExportParams; +// exportTethysData(tethysExportParams); +// } +// } +// +// /** +// * We'll arrive here if the dialog has been opened and we want to export Tethys data. +// * @param tethysExportParams2 +// */ +// private void exportTethysData(TethysExportParams tethysExportParams) { +// TethysExporter tethysExporter = new TethysExporter(this, tethysExportParams); +// tethysExporter.doExport(); +// +// sendStateUpdate(new TethysState(StateType.TRANSFERDATA)); +// countProjectDetections(); +// sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION)); +// } + + /** + * Get global deployment data. This is a bit of a mess, trying to use a separate module + * so that the rest of PAMGuard can use it, but creating the + * @return + */ + public Deployment getGlobalDeplopymentData() { + + MetaDataContol metaControl = MetaDataContol.getMetaDataControl(); + PamguardMetaData metaData = metaControl.getMetaData(); + return metaData.getDeployment(); +// Deployment deploymentData = metaControl != null ? metaData.getDeployment() : getTethysProjectData(); +// +//// deploymentData.setProject("thisIsAProject"); +////// deploymentData.setPlatform("Yay a platform"); +//// deploymentData.setCruise("cruisey"); +//// deploymentData.setDeploymentId(142536); +////// deploymentData.setInstrumentId("super instrument"); +//// deploymentData.setSite("in the ocean somewhere"); +//// deploymentData.setRegion("ocean water"); +////// deploymentData.setInstrumentType("sensor of sorts"); +// +// return deploymentData; + } + + /** + * Add a new state observer. + * @param stateObserver + */ + public void addStateObserver(TethysStateObserver stateObserver) { + stateObservers.add(stateObserver); + } + + /** + * Remove a state observer. + * @param stateObserver + * @return true if it existed. + */ + public boolean removeStateObserver(TethysStateObserver stateObserver) { + return stateObservers.remove(stateObserver); + } + + /** + * Send state updates around to all state observers. + * @param tethysState + */ + public void sendStateUpdate(TethysState tethysState) { + for (TethysStateObserver stateObserver : this.stateObservers) { + stateObserver.updateState(tethysState); + } + } + /** + * A name for any deta selectors. + * @return + */ + public String getDataSelectName() { + return getUnitName(); + } + + public DBXMLQueries getDbxmlQueries() { + return dbxmlQueries; + } + + @Override + public void notifyModelChanged(int changeType) { + super.notifyModelChanged(changeType); + switch (changeType) { + case PamControllerInterface.INITIALIZE_LOADDATA: +// case PamControllerInterface.INITIALIZATION_COMPLETE: + initializationStuff(); + break; + } + } + + /** + * Stuff to do on initial load (initialization complete or addition of + * a Tethys module after initialisation). + */ + private void initializationStuff() { + deploymentHandler.createPamguardOverview(); + serverCheckTimer.start(); + sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION)); + } + + /** + * Check the server. This will send around a notification if the state + * has changed since the last call to this function, so it's unlikely you'll + * need to use the return value + * @return server status. + */ + public ServerStatus checkServer() { + ServerStatus serverState = dbxmlConnect.pingServer(); + if (lastServerStatus == null || lastServerStatus.ok != serverState.ok) { + sendStateUpdate(new TethysState(StateType.UPDATESERVER)); + } + lastServerStatus = serverState; + return serverState; + } + + @Override + public Serializable getSettingsReference() { + return tethysExportParams; + } + + @Override + public long getSettingsVersion() { + return TethysExportParams.serialVersionUID; + } + + @Override + public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { + tethysExportParams = (TethysExportParams) pamControlledUnitSettings.getSettings(); + return true; + } + + @Override + public void updateState(TethysState tethysState) { + switch (tethysState.stateType) { + case NEWPROJECTSELECTION: + case EXPORTRDATA: + case DELETEDATA: + countProjectDetections(); + break; + } + } + + private void countProjectDetections() { + if (dataBlockSynchInfos == null) { + return; + } + Deployment deplData = getGlobalDeplopymentData(); + String[] dataPrefixes = new String[dataBlockSynchInfos.size()]; + int i = 0; + ArrayList matchedDeployments = deploymentHandler.getMatchedDeployments(); + for (DatablockSynchInfo synchInfo : dataBlockSynchInfos) { +// dataPrefixes[i] = DetectionsHandler.getDetectionsDocIdPrefix(deplData.getProject(), synchInfo.getDataBlock()); + int detectionCount = 0; + int documentCount = 0; + for (PDeployment pDepl : matchedDeployments) { + detectionCount += dbxmlQueries.countData(synchInfo.getDataBlock(), pDepl.deployment.getId()); + ArrayList detectionsNames = getDbxmlQueries().getDetectionsDocuments(synchInfo.getDataBlock(), pDepl.deployment.getId()); + if (detectionsNames != null) { + documentCount += detectionsNames.size(); + } + } + synchInfo.setDataCount(detectionCount); + synchInfo.setDetectionDocumentCount(documentCount); + + i++; + } +// int[] counts = dbxmlQueries.countDataForProject(deplData.getProject(), dataPrefixes); +// if (counts != null) { +// for ( i = 0; i < counts.length; i++ ) { +// dataBlockSynchInfos.get(i).setDataCount(counts[i]); +// } +// } + } + + /** + * One stop place to get Deployment information. Will provide + * both information on record periods in PAMGuard and also Deployment docs in Tethys. + * @return set of functions for handling deployments. + */ + public DeploymentHandler getDeploymentHandler() { + return deploymentHandler; + } + + public DetectionsHandler getDetectionsHandler() { + return detectionsHandler; + } + + public void showException(TethysException tethysException) { + String title = tethysException.getMessage(); + StackTraceElement[] stack = tethysException.getStackTrace(); + String msg = ""; + if (stack != null) { + msg = "Caused in"; + for (int i = 0; i < Math.min(stack.length, 3); i++) { + msg += "
" + stack[i].getClassName() + "." + stack[i].getMethodName(); + } + } + if (tethysException instanceof TethysQueryException) { + TethysQueryException tqe = (TethysQueryException) tethysException; +// msg += tqe. + } + + String xml = tethysException.getXmlError(); + if (xml != null) { + /** + * html can't handle the < and > in xml without getting very confused + * but it seems to work fine if they are replaced with their html codes. + */ + xml = xml.replace("<", "<"); + xml = xml.replace(">", ">"); + xml = xml.replace("\n", "
"); + msg += "

"+xml+"
"; + } + WarnOnce.showWarning(title, msg, WarnOnce.WARNING_MESSAGE); + } + + public void displayDocument(DocumentInfo docInfo) { + String collectionName = docInfo.getCollection().collectionName(); + String docId = docInfo.getDocumentName(); + displayDocument(collectionName, docId); + } + /** + * Load a document from the database and display it in a popup window + * @param collection + * @param documentId + */ + public void displayDocument(String collection, String documentId) { + String doc = getDbxmlQueries().getDocument(collection, documentId); + if (doc == null | doc.length() == 0) { + doc = String.format("Unable to retrieve document %s/%s from database\n", collection, documentId); + + } + XMLStringView.showDialog(getGuiFrame(), collection, documentId, doc); + } + + /** + * Load a document from the database and write to a file selected by the user + * @param collection + * @param documentId + */ + public void exportDocument(String collection, String documentId) { + String doc = getDbxmlQueries().getDocument(collection, documentId); + if (doc == null | doc.length() == 0) { + String msg = String.format("Unable to retrieve document %s/%s from database\n", collection, documentId); + WarnOnce.showWarning("Error", msg, WarnOnce.WARNING_MESSAGE); + } + + PamFileFilter fileFilter = new PamFileFilter("XML documents", ".xml"); +// fileFilter + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileFilter(fileFilter); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + // make a default name based on the document id and the dataset directory. + String defFolder = PamFolders.getDefaultProjectFolder(); + File defFile = null; + if (defFolder != null) { + defFolder = String.format("%s%s%s_%s.xml", defFolder,File.separator,collection,documentId); + defFile = new File(defFolder); + fileChooser.setAcceptAllFileFilterUsed(true); + fileChooser.setSelectedFile(defFile); + +// fileChooser.setSelectedFile(new File(String.format("%s.xml", documentId))); +// fileChooser.set + } + int state = fileChooser.showSaveDialog(getGuiFrame()); + if (state != JFileChooser.APPROVE_OPTION) return; + File newFile = fileChooser.getSelectedFile(); + if (newFile == null) return; + newFile = PamFileFilter.checkFileEnd(newFile, "xml", true); + if (newFile == null) { + return; + } + if (newFile.exists()) { + int ans2 = WarnOnce.showWarning(newFile.getAbsolutePath(), + "The file already exists. Do you want to overwrite it ?", WarnOnce.OK_CANCEL_OPTION); + if (ans2 == WarnOnce.CANCEL_OPTION) { + return; + } + } + try { + BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile)); + bos.write(doc.getBytes()); + bos.close(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * @return the itisFunctions + */ + public ITISFunctions getItisFunctions() { + if (itisFunctions == null) { + itisFunctions = new ITISFunctions(this); + } + return itisFunctions; + } + + /** + * Called when a detections document has been exported. + * @param dataBlock + */ + public void exportedDetections(PamDataBlock dataBlock) { + sendStateUpdate(new TethysState(StateType.EXPORTRDATA, Collection.Detections)); + countProjectDetections(); + sendStateUpdate(new TethysState(StateType.NEWPAMGUARDSELECTION, Collection.Detections)); + } + + /** + * @return the calibrationHandler + */ + public CalibrationHandler getCalibrationHandler() { + return calibrationHandler; + } + + +} diff --git a/src/tethys/TethysLocationFuncs.java b/src/tethys/TethysLocationFuncs.java new file mode 100644 index 00000000..dbfa68d8 --- /dev/null +++ b/src/tethys/TethysLocationFuncs.java @@ -0,0 +1,83 @@ +package tethys; + +import Array.ArrayManager; +import Array.HydrophoneLocator; +import Array.PamArray; +import Array.Streamer; +import GPS.GPSControl; +import GPS.GpsDataUnit; +import PamUtils.LatLong; +import PamUtils.PamUtils; +import generalDatabase.DBControlUnit; +import generalDatabase.PamConnection; +import nilus.Deployment; +import nilus.DeploymentRecoveryDetails; + +/** + * Function(s) to get location information for Tethys in the required format. + * @author dg50 + * + */ +public class TethysLocationFuncs { + + + /** + * Get everything we need for a deployment document including the track # + * and the deployment / recovery information. Basically this means we + * have to load the GPS data, then potentially filter it. Slight risk this + * may all be too much for memory, but give it a go by loading GPS data for + * the deployment times. + * @param deployment + */ + public static void getTrackAndPositionData(Deployment deployment) { + long start = TethysTimeFuncs.millisFromGregorianXML(deployment.getDeploymentDetails().getAudioTimeStamp()); + long end = TethysTimeFuncs.millisFromGregorianXML(deployment.getRecoveryDetails().getAudioTimeStamp()); + /* + * Need to load data for GPS, Hydrophones and Streamers datablocks for this time period. Can then use + * the snapshot geomentry classes to do the rest from the array manager ? + */ + boolean ok = true; + ok &= addPositionData(deployment.getDeploymentDetails()); + ok &= addPositionData(deployment.getRecoveryDetails()); + + } + + /** + * Add position data to DeploymentRecoveryDetails. + * @param drd + * @return + */ + public static boolean addPositionData(DeploymentRecoveryDetails drd) { + long timeMillis = TethysTimeFuncs.millisFromGregorianXML(drd.getAudioTimeStamp()); + LatLong pos = getLatLongData(timeMillis); + if (pos == null) { + return false; + } + drd.setLongitude(PamUtils.constrainedAngle(pos.getLongitude(), 360)); + drd.setLatitude(pos.getLatitude()); + drd.setElevationInstrumentM(pos.getHeight()); + drd.setDepthInstrumentM(-pos.getHeight()); + return true; + } + + public static LatLong getLatLongData(long timeMillis) { + // check the array time. + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + Streamer aStreamer = array.getStreamer(0); + GPSControl gpsControl = GPSControl.getGpsControl(); + PamConnection con = DBControlUnit.findConnection(); + if (gpsControl != null) { +// check GPS data are loaded for times around this. + GpsDataUnit gpsData = (GpsDataUnit) gpsControl.getGpsDataBlock().getLogging().findClosestDataPoint(con, timeMillis); + if (gpsData != null) { + return gpsData.getGpsData(); + } + } + HydrophoneLocator hydrophoneLocator = aStreamer.getHydrophoneLocator(); + if (hydrophoneLocator == null) { + return null; + } + return hydrophoneLocator.getStreamerLatLong(timeMillis); + } + +} diff --git a/src/tethys/TethysMenuActions.java b/src/tethys/TethysMenuActions.java new file mode 100644 index 00000000..625096a9 --- /dev/null +++ b/src/tethys/TethysMenuActions.java @@ -0,0 +1,70 @@ +package tethys; + + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.util.ArrayList; + +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; + +import tethys.dbxml.TethysException; +import tethys.niluswraps.PDeployment; + +/* + * Some standard meny dirven functions which we may want to call from + * a few different places. + */ +public class TethysMenuActions { + + private TethysControl tethysControl; + + public TethysMenuActions(TethysControl tethysControl) { + super(); + this.tethysControl = tethysControl; + } + + public void deploymentMouseActions(MouseEvent e, PDeployment pDeployment) { + ArrayList detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocuments(pDeployment.deployment.getId()); +// System.out.println("Detections for deployment " + pDeployment.deployment.getId()); +// for (String detName : detDocNames) { +// System.out.println(detName); +// } + JPopupMenu menu = new JPopupMenu(); + if (detDocNames.size() == 0) { + JMenuItem menuItem = new JMenuItem("Delete deployment " + pDeployment.deployment.getId()); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + deleteDeployment(pDeployment); + } catch (TethysException e1) { + tethysControl.showException(e1); + } + } + }); + menu.add(menuItem); + } + else { + String str = String.format("Delete deployment %s and %d Detections documents", pDeployment.deployment.getId(), detDocNames.size()); + JMenuItem menuItem = new JMenuItem(str); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + deleteDeployment(pDeployment); + } catch (TethysException e1) { + tethysControl.showException(e1); + } + } + }); + menu.add(menuItem); + } + menu.show(e.getComponent(), e.getX(), e.getY()); + } + + protected void deleteDeployment(PDeployment pDeployment) throws TethysException { + tethysControl.getDbxmlConnect().deleteDeployment(pDeployment.deployment.getId()); + } +} diff --git a/src/tethys/TethysState.java b/src/tethys/TethysState.java new file mode 100644 index 00000000..ea2f2746 --- /dev/null +++ b/src/tethys/TethysState.java @@ -0,0 +1,54 @@ +package tethys; + +/** + * Basis for a message system which will get passed around whenever something happens in + * Tethys, whether it be a new connection, progress during data output, etc. + * @author dg50 + * + */ +public class TethysState { + + public enum StateType {UPDATESERVER, // Server connection or status has changed + EXPORTRDATA, // data have been transferred from PAMGuard to Tethys + NEWPROJECTSELECTION, // a new Tethys project has been selected in the GUI + NEWPAMGUARDSELECTION, // new PAMGuard data are available (called once on first load) + UPDATEMETADATA, // META Data being prepared for output have changed (so may be able to enable output!) + EXPORTING, // currently exporting data. may be a while ... + DELETEDATA // data were deleted + } + + public StateType stateType; + + public Collection collection; + + public TethysState(StateType stateType) { + super(); + this.stateType = stateType; + collection = Collection.OTHER; + } + + public TethysState(StateType stateType, Collection collection) { + this.stateType = stateType; + this.collection = collection; + if (this.collection == null) { + this.collection = Collection.OTHER; + } + } + + /** + * @return the collection associated with this notification. Note that there is + * an OTHER category in Collections which is used for server / project updates, making + * it easier to switch on the collection type when notifications are received. + */ + public Collection getCollection() { + return collection; + } + + /** + * @return the stateType + */ + public StateType getStateType() { + return stateType; + } + +} diff --git a/src/tethys/TethysStateObserver.java b/src/tethys/TethysStateObserver.java new file mode 100644 index 00000000..33a9de5c --- /dev/null +++ b/src/tethys/TethysStateObserver.java @@ -0,0 +1,13 @@ +package tethys; + +public interface TethysStateObserver { + + /** + * Receive state updates when Tethys has done something (made a connection, moved some data, etc.)
+ * Note that this is for RECEIVING state updates, not for sending them. To avoid infinite notifications + * loops, use tethysControl.sendStateUpdate(TethysState) to send out state notifications. + * @param tethysState + */ + public void updateState(TethysState tethysState); + +} diff --git a/src/tethys/TethysTimeFuncs.java b/src/tethys/TethysTimeFuncs.java new file mode 100644 index 00000000..70d11704 --- /dev/null +++ b/src/tethys/TethysTimeFuncs.java @@ -0,0 +1,90 @@ +package tethys; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import PamUtils.PamCalendar; + +public class TethysTimeFuncs { + + private static TimeZone timeZone = TimeZone.getTimeZone("UTC"); + + /* + * Copied from http://www.java2s.com/Code/Java/Development-Class/ConvertsagiventimeinmillisecondsintoaXMLGregorianCalendarobject.htm + */ + public static XMLGregorianCalendar xmlGregCalFromMillis(long millis) { + try { + final GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTimeZone(timeZone); + calendar.setTimeInMillis(millis); + return DatatypeFactory.newInstance().newXMLGregorianCalendar( + calendar); + } + catch (final DatatypeConfigurationException ex) { + System.out.println("Unable to convert date '%s' to an XMLGregorianCalendar object"); + return null; + } + } + + /** + * Convert a Gregorian calendar value back to milliseconds. + * @param xmlGregorian + * @return + */ + public static Long millisFromGregorianXML(XMLGregorianCalendar xmlGregorian) { + if (xmlGregorian == null) { + return null; + } + GregorianCalendar gc2 = xmlGregorian.toGregorianCalendar(); + gc2.setTimeZone(timeZone); + return gc2.getTimeInMillis(); + } + + /** + * Make a Gregorian calendar object from a returned XML string. + * @param gregorianString + * @return + */ + public static XMLGregorianCalendar fromGregorianXML(String gregorianString) { + // typical string is 2018-10-20T00:00:00Z + if (gregorianString == null) { + return null; + } +// GregorianCalendar gCal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + gregorianString = gregorianString.replace("T", " "); + gregorianString = gregorianString.replace("Z", ""); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + df.setTimeZone(TimeZone.getTimeZone("UTC")); + Date date = null; + try { + date = df.parse(gregorianString); + } catch (ParseException e) { + System.out.printf("Unparsable date string:\"%s\"", gregorianString); + e.printStackTrace(); + return null; + } + return xmlGregCalFromMillis(date.getTime()); +// gCal.setTimeInMillis(date.getTime()); +//// gCal.se +// return gCal; + } + + public static String formatGregorianTime(XMLGregorianCalendar gregCal) { + if (gregCal == null) { + return null; + } + Long millis = millisFromGregorianXML(gregCal); + if (millis == null) { + return gregCal.toString(); + } + return PamCalendar.formatDBDateTime(millis); + } +} diff --git a/src/tethys/calibration/CalibrationHandler.java b/src/tethys/calibration/CalibrationHandler.java new file mode 100644 index 00000000..15f3ece4 --- /dev/null +++ b/src/tethys/calibration/CalibrationHandler.java @@ -0,0 +1,545 @@ +package tethys.calibration; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.xml.bind.JAXBException; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; + +import Acquisition.AcquisitionControl; +import Acquisition.AcquisitionParameters; +import Acquisition.AcquisitionProcess; +import Array.ArrayManager; +import Array.Hydrophone; +import Array.PamArray; +import Array.Preamplifier; +import PamController.PamController; +import PamController.soundMedium.GlobalMedium; +import PamController.soundMedium.GlobalMedium.SoundMedium; +import PamUtils.PamCalendar; +import PamView.dialog.warn.WarnOnce; +import dbxml.Queries; +import PamController.soundMedium.GlobalMediumManager; +import nilus.AlgorithmType.Parameters; +import nilus.Calibration; +import nilus.Calibration.FrequencyResponse; +import nilus.Calibration.QualityAssurance; +import nilus.Helper; +import nilus.MetadataInfo; +import nilus.QualityValueBasic; +import nilus.ResponsibleParty; +import tethys.Collection; +import tethys.DocumentInfo; +import tethys.DocumentNilusObject; +import tethys.TethysControl; +import tethys.TethysState; +import tethys.TethysStateObserver; +import tethys.TethysTimeFuncs; +import tethys.calibration.swing.CalibrationsExportWizard; +import tethys.dbxml.DBXMLConnect; +import tethys.dbxml.TethysException; +import tethys.niluswraps.NilusSettingsWrapper; +import tethys.niluswraps.NilusUnpacker; +import tethys.pamdata.AutoTethysProvider; + +public class CalibrationHandler implements TethysStateObserver { + + private TethysControl tethysControl; + + private ArrayList> calibrationsList; + + public static final String[] updateOptions = {"as-needed", "unplanned", "yearly"}; + + public static final String[] calibrationMethods = {"Reference hydrophone", "Manufacturers specification", "Piston phone", "Other calibrated source", "Unknown"}; + + public static final String[] qaTypes = {"unverified", "valid", "invalid"}; + + private Helper nilusHelper; + /** + * @param tethysControl + */ + public CalibrationHandler(TethysControl tethysControl) { + this.tethysControl = tethysControl; + calibrationsList = new ArrayList(); + tethysControl.addStateObserver(this); try { + nilusHelper = new Helper(); + } catch (JAXBException e) { + e.printStackTrace(); + } + } + + @Override + public void updateState(TethysState tethysState) { + switch (tethysState.stateType) { + case EXPORTING: + break; + case NEWPAMGUARDSELECTION: + case NEWPROJECTSELECTION: + case EXPORTRDATA: + case DELETEDATA: + case UPDATEMETADATA: + case UPDATESERVER: + if (isWantedState(tethysState)) { + updateDocumentsList(); + } + default: + break; + + } + } + + /** + * Is it a state notification we want to respond to + * @param state + * @return true if worth it. + */ + protected boolean isWantedState(TethysState state) { + if (state.collection == null) { + return true; + } + switch (state.collection) { + case OTHER: + case Calibrations: + return true; + } + return false; + } + + /** + * Update the list of documents associated with the selected instrument. + */ + private void updateDocumentsList() { + + calibrationsList.clear(); + + ArrayList docsList = getArrayCalibrations(); + // now immediately read the calibrations in again. + if (docsList == null) { + return; + } + NilusUnpacker unpacker = new NilusUnpacker(); + for (DocumentInfo aDoc : docsList) { + Queries queries = tethysControl.getDbxmlConnect().getTethysQueries(); + String result = null; + Calibration calObj = null; + try { + result = queries.getDocument(Collection.Calibrations.toString(), aDoc.getDocumentName()); + if (result != null) { + // create a document and convert it into a Nilus calibrations document. + Document doc = tethysControl.getDbxmlQueries().convertStringToXMLDocument(result); + if (doc == null) { + System.out.println("Unable to convert Calibration result to Document\n " + result); + continue; + } + calObj = (Calibration) unpacker.unpackDocument(doc, Calibration.class); + if (calObj == null) { + System.out.println("Unable to convert Calibration document to nilus object\n " + result); + continue; + } + } + long t = System.currentTimeMillis(); + try { + XMLGregorianCalendar gt = calObj.getMetadataInfo().getDate(); + if (gt != null) { + t = TethysTimeFuncs.millisFromGregorianXML(gt); + } + } + catch (Exception e) { + + } + DocumentNilusObject calDataUnit = new DocumentNilusObject(Collection.Calibrations, aDoc.getDocumentName(), calObj.getId(), calObj); + calibrationsList.add(calDataUnit); +// System.out.println(result); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + public int exportAllCalibrations() { + + Calibration sampleCal = new Calibration(); + try { + Helper.createRequiredElements(sampleCal); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e1) { + e1.printStackTrace(); + } + sampleCal = CalibrationsExportWizard.showWizard(tethysControl.getGuiFrame(), sampleCal); + if (sampleCal == null) { + return 0; + } + + NilusSettingsWrapper wrappedSample = new NilusSettingsWrapper(); + wrappedSample.setNilusObject(sampleCal); + + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nPhone = array.getHydrophoneCount(); + DBXMLConnect dbxml = tethysControl.getDbxmlConnect(); + int nExport = 0; + boolean overwrite = false; + boolean exists; + for (int i = 0; i < nPhone; i++) { +// String docName = getHydrophoneId(i); + NilusSettingsWrapper clonedWrap = wrappedSample.clone(); + sampleCal = clonedWrap.getNilusObject(Calibration.class); + Calibration calDoc = createCalibrationDocument(i); + if (sampleCal != null) { + calDoc.setMetadataInfo(sampleCal.getMetadataInfo()); + calDoc.setProcess(sampleCal.getProcess()); + calDoc.setQualityAssurance(sampleCal.getQualityAssurance()); + calDoc.setResponsibleParty(sampleCal.getResponsibleParty()); + calDoc.setTimeStamp(sampleCal.getTimeStamp()); + } + + addParameterDetails(calDoc, i); + + String calDocName = createDocumentName(calDoc, i); + exists = calDocumentExists(calDocName); + if (exists && overwrite == false) { + String msg = String.format("Calibration document %s already exists. Do you want to overwrite it and other documents from this date?", calDocName); + int ans = WarnOnce.showWarning("Calibration Export", msg, WarnOnce.OK_CANCEL_OPTION); + if (ans == WarnOnce.OK_OPTION) { + overwrite = true; + } + else { + return nExport; + } + } + boolean ok = false; + if (exists == true && overwrite == false) { + continue; + } + try { + if (exists) { + ok = dbxml.removeDocument(Collection.Calibrations, calDocName); + } + ok = dbxml.postAndLog(calDoc, calDocName); + } catch (TethysException e) { + e.printStackTrace(); + tethysControl.showException(e); + ok = false; + break; + } + if (ok) { + nExport++; + } + } + tethysControl.sendStateUpdate(new TethysState(TethysState.StateType.EXPORTRDATA, Collection.Calibrations)); + return nExport; + } + + /** + * Add the separate pamguard parameters to the document which are used + * to make up the overall calibration. + * @param calDoc + * @param i hydrophone number + */ + private void addParameterDetails(Calibration calDoc, int i) { + Parameters params = calDoc.getProcess().getParameters(); + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.unitType); + AcquisitionParameters daqParams = daqControl.getAcquisitionParameters(); + Hydrophone phone = array.getHydrophoneArray().get(i); + try { + nilusHelper.AddAnyElement(params.getAny(), "HydrophoneType", phone.getType()); + nilusHelper.AddAnyElement(params.getAny(), "Sensitivity", String.format("%3.1f", phone.getSensitivity())); + nilusHelper.AddAnyElement(params.getAny(), "PreampGain", String.format("%3.1f", phone.getPreampGain())); + nilusHelper.AddAnyElement(params.getAny(), "ADCp-p", String.format("%3.2fV", daqParams.getVoltsPeak2Peak())); + Preamplifier preamp = daqParams.preamplifier; + if (preamp != null) { + nilusHelper.AddAnyElement(params.getAny(), "ADCAmplifier", String.format("%3.2fdB", preamp.getGain())); + } + } catch (JAXBException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + + } + + /** + * Format the data in the dd MMMM yyyy format + * @param timeInMillis time in milliseconds + * @return formatted string. + */ + public static String formatDate(long timeInMillis) { + Calendar c = Calendar.getInstance(); + c.setTimeInMillis(timeInMillis); + c.setTimeZone(PamCalendar.defaultTimeZone); + DateFormat df = new SimpleDateFormat("yyMMdd"); + df.setTimeZone(PamCalendar.defaultTimeZone); + Date d = c.getTime(); + return df.format(d); + } + + + /** + * Get a name for the document, which is a bit like the id within + * the document, but also contain a yymmdd data string. + * @param calDoc + * @param i channel + * @return document name + */ + private String createDocumentName(Calibration calDoc, int iChan) { + long docDate = System.currentTimeMillis(); + XMLGregorianCalendar date = calDoc.getMetadataInfo().getDate(); + if (date != null) { + docDate = TethysTimeFuncs.millisFromGregorianXML(date); + } + String dateStr = formatDate(docDate); + String name = String.format("%s_%s_ch%d", createCalibrationDocumentRoot(), dateStr, iChan); + return name; + } + + /** + * Get a start of name for a calibration document. This will be used in the document name + * with a date and a channel, and the document Id just of the root and the channel. + * @return root string for document names and document id's. + */ + public String createCalibrationDocumentRoot() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + if (array == null) { + return null; + } + String root = String.format("%s %s", array.getInstrumentType(), array.getInstrumentId()); + root = root.replace(" ", "_"); + return root; + } + + /** + * Create a calibration document for a single hydrophone channel. + * @param pDeployment deployment, for cross referencing. + * @param channelIndex channel id. One document per channel for a multi hydrophone array. + * @return Calibration document. + */ + public Calibration createCalibrationDocument(int channelIndex) { + AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.unitType); + return createCalibrationDocument(daqControl, channelIndex); + } + + /** + * Create a calibration document for a single hydrophone channel. + * @param pDeployment deployment, for cross referencing. + * @param soundAcquisition Daq information - needed to get the ADC calibration information. + * @param channelIndex channel id. One document per channel for a multi hydrophone array. + * @return Calibration document. + */ + public Calibration createCalibrationDocument(AcquisitionControl soundAcquisition, int channelIndex) { + /** + * Calibrations document id and cross referencing to Deploymnet documents: + * Identifier of instrument, preamplifier, or hydrophone. + * Corresponds to elements in Deployment: + * Deployment/Instrument/Id, + * Deployment/Sensors/Audio/HydrophoneId, + * Deployment/Sensors/Audio[i]/PreampId. + * As instruments may be calibrated multiple times, it is not an error for duplicate Id values to appear. + * It is recommended that the three different types of identifiers (instrument, hydrophone, preamp) be distinct, + * but the Type element may be used to distinguish them if they are not. + */ + + /* + * very remote possibility that DAQ doesn't exist. What to do in this case ? It's also possible that some configurations may + * have to have >1 DAQ's ? + */ + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + if (array == null) { + return null; + } + if (channelIndex < 0 || channelIndex >= array.getHydrophoneCount()) { + return null; + } +// ArrayManager.getArrayManager().get +// hydrophones = array. + Hydrophone hydrophone = array.getHydrophoneArray().get(channelIndex); + double hSens = hydrophone.getSensitivity(); + double preampGain = hydrophone.getPreampGain(); + + GlobalMediumManager mediumManager = PamController.getInstance().getGlobalMediumManager(); + SoundMedium currentMedium = mediumManager.getCurrentMedium(); + double dbRef = GlobalMedium.getdBreference(currentMedium); // probably in Pa, so multiply by 1e6. 20 (air) or 0 (water) + + /** + * The calibration id can be a bit tricky, it will need to be cross referenced from the + * Deployment document, and it is likely that a deployment document will have to reference several + * calibration documents for different channels. + * Make the name from the Array name (new), the array Instrument Id (unique to the array) + * and the channel number. These will then all have to go into the Deployment document in + * the list of audio devices, cross referenced as the SensorId field. + * + */ + + Calibration calibration = new Calibration(); + + try { + Helper.createRequiredElements(calibration); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + String id = getHydrophoneId(channelIndex); +// id = String.format("%d", channelIndex); + calibration.setId(id); + calibration.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); +// calibration.setType(GlobalMedium.getRecieverString(currentMedium, false, false)); + calibration.setType("end-to-end"); + calibration.setIntensityReferenceUPa(AutoTethysProvider.roundSignificantFigures(dbRef*1e6,3)); +// String sensRef = GlobalMedium.getdBRefString(currentMedium); + // it doesn't like this since it has a unicode character. Leave it or change the micro to 'u' +// calibration.setSensitivityReference(sensRef); + calibration.setSensitivityDBV(hSens+preampGain); + if (soundAcquisition != null) { + AcquisitionProcess daqProcess = soundAcquisition.getAcquisitionProcess(); + double fullScale = daqProcess.rawAmplitude2dB(1, channelIndex, false); + calibration.setSensitivityDBFS(fullScale); + } + FrequencyResponse frs = calibration.getFrequencyResponse(); + List hz = frs.getHz(); + List db = frs.getDB(); + hz.add(Double.valueOf(0)); + db.add(Double.valueOf(hSens+preampGain)); + + MetadataInfo metaInf = calibration.getMetadataInfo(); + if (metaInf == null) { + metaInf = new MetadataInfo(); + calibration.setMetadataInfo(metaInf); + } + metaInf.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); + metaInf.setUpdateFrequency("as-needed"); + ResponsibleParty contact = metaInf.getContact(); + if (contact == null) { + contact = new ResponsibleParty(); + metaInf.setContact(contact); + } + contact.setIndividualName("Unknown"); + contact.setOrganizationName("unknown"); + + QualityAssurance qa = calibration.getQualityAssurance(); + if (qa == null) { + qa = new QualityAssurance(); + calibration.setQualityAssurance(qa); + } + qa.setQuality(QualityValueBasic.VALID); + qa.setComment("Unknown calibration"); + + + return calibration; + } + + /** + * See if a document already exists. This should only occur if you + * try to export the same document twice with the same calibration date. + * @param documentName + * @return true if a document already exists. + */ + public boolean calDocumentExists(String documentName) { + if (calibrationsList == null) { + return false; + } + for (int i = 0; i < calibrationsList.size(); i++) { + if (calibrationsList.get(i).getDocumentName().equalsIgnoreCase(documentName)) { + return true; + } + } + return false; + } + + /** + * Return if we have at least one document for every channel. + * @return true if all cal documents exist. + */ + public boolean haveAllChannelCalibrations() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nPhone = array.getHydrophoneCount(); + for (int i = 0; i < nPhone; i++) { + if (haveChannelCalibration(i) == false) { + return false; + } + } + return true; + } + + /** + * Find whether we have a document for this instrument and channel. + * @param iChan + * @return true if we have an appropriate doc. + */ + public boolean haveChannelCalibration(int iChan) { + if (calibrationsList == null) { + return false; + } + String seachPattern = makeChannelNamePart(iChan); + for (int i = 0; i < calibrationsList.size(); i++) { + String docName = calibrationsList.get(i).getDocumentName(); + if (docName.endsWith(seachPattern)) { + return true; + } + } + + return false; + } + + /** + * Get an id based on the instrument identifiers and channel number. + * This is the internal id of the document, not the document name which + * includes an additional date part in the name. + * @param channelIndex + * @return id string - instrument type + instrument id + channel + */ + public String getHydrophoneId(int channelIndex) { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + if (array == null) { + return null; + } + String id = String.format("%s_%s", createCalibrationDocumentRoot(), makeChannelNamePart(channelIndex)); + id = id.replace(" ", "_"); + return id; + } + + /** + * Make the final part of the document name / id which is the channel number. + * @param channelIndex channel index + * @return string in the form ch%02d (e.g. ch03) + */ + public String makeChannelNamePart(int channelIndex) { + return String.format("ch%02d", channelIndex); + } + + /** + * @return the calibrationDataBlock + */ + public ArrayList> getCalibrationDataList() { + return calibrationsList; + } + + /** + * Make a list of document names associated with this instrument. + * @return list of calibration documents using this instrument, based on the start of the document name. + */ + private ArrayList getArrayCalibrations() { + ArrayList allCals = null; + try { + allCals = tethysControl.getDbxmlQueries().getCollectionDocumentList(Collection.Calibrations); + } + catch (Exception e) { + + } + if (allCals == null) { + return null; + } + String prefix = createCalibrationDocumentRoot(); // find doc names that have that root. + ArrayList theseCals = new ArrayList<>(); + for (DocumentInfo aDoc : allCals) { + if (aDoc.getDocumentName().startsWith(prefix)) { + theseCals.add(aDoc); + } + } + return theseCals; + } +} diff --git a/src/tethys/calibration/swing/CalibrationProcessCard.java b/src/tethys/calibration/swing/CalibrationProcessCard.java new file mode 100644 index 00000000..30e37ba7 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationProcessCard.java @@ -0,0 +1,170 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.util.List; + +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; + +import PamView.dialog.PamGridBagContraints; +import PamView.panel.WestAlignedPanel; +import PamView.wizard.PamWizard; +import nilus.AlgorithmType; +import nilus.AlgorithmType.Parameters; +import nilus.AlgorithmType.SupportSoftware; +import nilus.Calibration; +import nilus.Calibration.QualityAssurance; +import nilus.QualityValueBasic; +import tethys.calibration.CalibrationHandler; + +public class CalibrationProcessCard extends CalibrationsCard { + + private JPanel processPanel; + + private JComboBox calMethod; + + private JTextArea software; + + private JTextField version; + + private JComboBox qaQuality; + + private JTextField qaComment; + + public CalibrationProcessCard(PamWizard pamWizard) { + super(pamWizard, "Calibration Process"); + this.setLayout(new BorderLayout()); + processPanel = new JPanel(new GridBagLayout()); + WestAlignedPanel wp; + this.add(BorderLayout.NORTH, wp = new WestAlignedPanel(processPanel)); + wp.setBorder(new TitledBorder("Calibration Process")); + + GridBagConstraints c = new PamGridBagContraints(); + + calMethod = new JComboBox(); + String[] meths = CalibrationHandler.calibrationMethods; + for (int i = 0; i < meths.length; i++) { + calMethod.addItem(meths[i]); + } + + qaQuality = new JComboBox<>(); + String[] vals = CalibrationHandler.qaTypes; + for (int i = 0; i < vals.length; i++) { + qaQuality.addItem(vals[i]); + } + + software = new JTextArea(5, 25); + software.setLineWrap(true); + software.setWrapStyleWord(true); + software.setToolTipText("Details of calibration method and software used"); + + version = new JTextField(20); + version.setToolTipText("Serial number of calibration device"); + + qaComment = new JTextField(20); + qaComment.setToolTipText("Comment on calibration quality"); + + processPanel.add(new JLabel("Method ", JLabel.RIGHT), c); + c.gridx++; + processPanel.add(calMethod, c); + c.gridx = 0; + c.gridy++; + c.gridwidth = 1; + processPanel.add(new JLabel("Serial number ", JLabel.RIGHT), c); + c.gridx++; + c.gridwidth = 2; + processPanel.add(version, c); + c.gridx = 0; + c.gridy++; + c.gridwidth = 1; + processPanel.add(new JLabel("Quality ", JLabel.RIGHT), c); + c.gridx++; + processPanel.add(qaQuality, c); + c.gridx = 0; + c.gridy++; + processPanel.add(new JLabel("QA Comment ", JLabel.RIGHT), c); + c.gridx++; + c.gridwidth = 2; + processPanel.add(qaComment, c); + + this.add(BorderLayout.CENTER, makeScrollablePanel(software, "Calibration method")); + + } + + private JScrollPane makeScrollablePanel(JTextArea textArea, String title) { + // TODO Auto-generated method stub +// mainPanel.add(new Label(title, JLabel.LEFT)); +// textArea.setMinimumSize(new Dimension(200, 200)); + JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(new TitledBorder(title)); + scrollPane.setPreferredSize(new Dimension(scrollPane.getPreferredSize().height/2, 0)); + return scrollPane; + } + + + @Override + public boolean getParams(Calibration calibration) { + if (calibration == null) { + return false; + } + AlgorithmType process = calibration.getProcess(); + if (process == null) { + process = new AlgorithmType(); + calibration.setProcess(process); + } + process.setMethod((String) calMethod.getSelectedItem()); + process.setVersion(version.getText()); + process.setSoftware(software.getText()); + if (software.getText() == null) { + getPamWizard().showWarning("You must specify the calibratin method used"); + } + + QualityAssurance qa = calibration.getQualityAssurance(); + if (qa == null) { + qa = new QualityAssurance(); + calibration.setQualityAssurance(qa); + } + qa.setComment(qaComment.getText()); + qa.setQuality(QualityValueBasic.fromValue((String) qaQuality.getSelectedItem())); + + // need to add a few fixed things for this to work... +// List supportSoftware = process.getSupportSoftware(); + Parameters params = process.getParameters(); + if (params == null) { + params = new Parameters(); + process.setParameters(params); + } + + return true; + } + + @Override + public void setParams(Calibration calibration) { + if (calibration == null) { + return; + } + AlgorithmType process = calibration.getProcess(); + if (process != null) { + calMethod.setSelectedItem(process.getMethod()); + version.setText(process.getVersion()); + software.setText(process.getSoftware()); + } + QualityAssurance qa = calibration.getQualityAssurance(); + if (qa != null) { + QualityValueBasic qb = qa.getQuality(); + if (qb != null) { + qaQuality.setSelectedItem(qb.value()); + } + qaComment.setText(qa.getComment()); + } + } +} diff --git a/src/tethys/calibration/swing/CalibrationsCard.java b/src/tethys/calibration/swing/CalibrationsCard.java new file mode 100644 index 00000000..b97221d3 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsCard.java @@ -0,0 +1,13 @@ +package tethys.calibration.swing; + +import PamView.wizard.PamWizard; +import PamView.wizard.PamWizardCard; +import nilus.Calibration; + +abstract public class CalibrationsCard extends PamWizardCard { + + public CalibrationsCard(PamWizard pamWizard, String title) { + super(pamWizard, title); + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsContactCard.java b/src/tethys/calibration/swing/CalibrationsContactCard.java new file mode 100644 index 00000000..3adc9f33 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsContactCard.java @@ -0,0 +1,198 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Date; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.TitledBorder; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.jdesktop.swingx.JXDatePicker; + +import PamView.dialog.PamDialog; +import PamView.dialog.PamGridBagContraints; +import PamView.panel.WestAlignedPanel; +import PamView.wizard.PamWizard; +import nilus.Calibration; +import nilus.ContactInfo; +import nilus.MetadataInfo; +import nilus.ResponsibleParty; +import tethys.TethysTimeFuncs; +import tethys.calibration.CalibrationHandler; +import tethys.swing.export.ResponsiblePartyPanel; + +public class CalibrationsContactCard extends CalibrationsCard { + + private JXDatePicker datePicker; + + private ResponsiblePartyPanel calibrator, dataManager; + + private JComboBox updateInterval; + + private MetadataInfo metaData; + + private JButton copyDown, copyUp; + + public CalibrationsContactCard(PamWizard pamWizard) { + super(pamWizard, "Contact Details"); + // TODO Auto-generated constructor stub +// setBorder(new TitledBorder("Contact")); + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + updateInterval = new JComboBox<>(); + String[] vals = CalibrationHandler.updateOptions; + for (int i = 0; i < vals.length; i++) { + updateInterval.addItem(vals[i]); + } + + JPanel datePanel = new JPanel(new GridBagLayout()); + JPanel lp = new WestAlignedPanel(datePanel); + lp.setBorder(new TitledBorder("Calibration date")); + GridBagConstraints c = new PamGridBagContraints(); + datePanel.add(new JLabel("Calibration date: ", JLabel.RIGHT), c); + datePicker = new JXDatePicker(); + c.gridx++; + datePanel.add(datePicker, c); + c.gridx = 0; + c.gridy++; + datePanel.add(new JLabel("Update Frequency", JLabel.RIGHT), c); + c.gridx++; + datePanel.add(updateInterval, c); + + calibrator = new ResponsiblePartyPanel("Technical Person"); + dataManager = new ResponsiblePartyPanel("Data Manager"); + + JPanel copyPanel = new JPanel(new GridBagLayout()); + c = new PamGridBagContraints(); + copyPanel.add(copyDown = new JButton("Copy down"),c); + c.gridx++; + copyPanel.add(copyUp = new JButton("Copy up"), c); + + add(lp); + add(calibrator.getMainPanel()); + add(copyPanel); + add(dataManager.getMainPanel()); + + copyDown.setToolTipText("Copy technical person to data manager"); + copyUp.setToolTipText("Copy data manager to technical person"); + copyDown.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + copyRPDown(); + } + }); + copyUp.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + copyRPUp(); + } + + }); + } + + protected void copyRPDown() { + copyRPData(calibrator, dataManager); + } + private void copyRPUp() { + copyRPData(dataManager, calibrator); + } + + private void copyRPData(ResponsiblePartyPanel rFrom, ResponsiblePartyPanel rTo) { + ResponsibleParty rp = checkRPChildren(null); + rFrom.getParams(rp); + rTo.setParams(rp); + } + + @Override + public boolean getParams(Calibration cardParams) { + ResponsibleParty rp = checkRPChildren(cardParams.getResponsibleParty()); + cardParams.setResponsibleParty(rp); + calibrator.getParams(rp); + + metaData = cardParams.getMetadataInfo(); + if (metaData == null) { + metaData = new MetadataInfo(); + cardParams.setMetadataInfo(metaData); + } + metaData.setContact(checkRPChildren(metaData.getContact())); + dataManager.getParams(metaData.getContact()); + + metaData.setUpdateFrequency((String) updateInterval.getSelectedItem()); + metaData.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); + + Date date = datePicker.getDate(); + if (date == null) { + return getPamWizard().showWarning("You must specify the data of the calibration"); + } + long millis = date.getTime(); + cardParams.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(millis)); + + return true; + } + + private ResponsibleParty checkRPChildren(ResponsibleParty rp) { + if (rp == null) { + rp = new ResponsibleParty(); + } + if (rp.getContactInfo() == null) { + rp.setContactInfo(new ContactInfo()); + } + if (rp.getContactInfo().getAddress() == null) { +// rp.getContactInfo().setAddress(new Address()); + } + return rp; + } + + private ResponsibleParty findResponsibleParty(Calibration cal) { + if (cal == null) { + return null; + } + MetadataInfo metaInfo = cal.getMetadataInfo(); + if (metaInfo != null) { + ResponsibleParty resp = metaInfo.getContact(); + if (resp != null && resp.getIndividualName() != null) { + return resp; + } + } + return cal.getResponsibleParty(); + + } + + @Override + public void setParams(Calibration cardParams) { + // fill in as much as possible from the existing Calibration + ResponsibleParty resp = cardParams.getResponsibleParty(); + if (resp != null) { + calibrator.setParams(resp); + } + + MetadataInfo metaInf = cardParams.getMetadataInfo(); + if (metaInf != null) { + resp = metaInf.getContact(); + if (resp != null) { + dataManager.getParams(resp); + } + String uf = metaInf.getUpdateFrequency(); + if (uf != null) { + updateInterval.setSelectedItem(uf); + } + } + + XMLGregorianCalendar ts = cardParams.getTimeStamp(); + if (ts != null) { + datePicker.setDate(new Date(TethysTimeFuncs.millisFromGregorianXML(ts))); + } + + + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsExportWizard.java b/src/tethys/calibration/swing/CalibrationsExportWizard.java new file mode 100644 index 00000000..74bb356a --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsExportWizard.java @@ -0,0 +1,42 @@ +package tethys.calibration.swing; + +import java.awt.Window; + +import PamView.wizard.PamWizard; +import PamView.wizard.PamWizardCard; +import nilus.Calibration; + +public class CalibrationsExportWizard extends PamWizard { + + private Calibration sampleDocument; + + private CalibrationsExportWizard(Window parentFrame, Calibration sampleDocument) { + super(parentFrame, "Calibrations Export"); + this.sampleDocument = sampleDocument; + addCard(new CalibrationProcessCard(this)); + addCard(new CalibrationsContactCard(this)); + } + + public static Calibration showWizard(Window parentFrame, Calibration sampleDocument) { + CalibrationsExportWizard wiz = new CalibrationsExportWizard(parentFrame, sampleDocument); + wiz.setParams(); + wiz.setVisible(true); + return wiz.sampleDocument; + } + + @Override + public void setCardParams(PamWizardCard wizardCard) { + wizardCard.setParams(sampleDocument); + } + + @Override + public boolean getCardParams(PamWizardCard wizardCard) { + return wizardCard.getParams(sampleDocument); + } + + @Override + public void cancelButtonPressed() { + sampleDocument = null; + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsMainPanel.java b/src/tethys/calibration/swing/CalibrationsMainPanel.java new file mode 100644 index 00000000..385ca9ef --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsMainPanel.java @@ -0,0 +1,66 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.TitledBorder; + + +import PamView.panel.PamPanel; +import tethys.TethysControl; +import tethys.calibration.CalibrationHandler; +import tethys.swing.TethysGUIPanel; + +public class CalibrationsMainPanel extends TethysGUIPanel { + + private CalibrationHandler calibrationHandler; + + private CalibrationsTable calibrationsTable; + + private JPanel mainPanel; + + private JPanel ctrlPanel; + + private JButton exportButton; + + private JLabel warning; + + public CalibrationsMainPanel(TethysControl tethysControl, CalibrationHandler calibrationHandler) { + super(tethysControl); + this.calibrationHandler = calibrationHandler; + mainPanel = new PamPanel(new BorderLayout()); + mainPanel.setBorder(new TitledBorder("Instrument calibration information")); + + calibrationsTable = new CalibrationsTable(tethysControl, calibrationHandler); + mainPanel.add(BorderLayout.CENTER, calibrationsTable.getComponent()); + + ctrlPanel = new PamPanel(new BorderLayout()); + exportButton = new JButton("Export ..."); + ctrlPanel.add(BorderLayout.WEST, exportButton); + warning = new JLabel(); + ctrlPanel.add(BorderLayout.CENTER, warning); + mainPanel.add(BorderLayout.NORTH, ctrlPanel); + exportButton.setToolTipText("Export calibration data to database"); + exportButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + exportCalibrations(); + } + }); + } + + protected void exportCalibrations() { + calibrationHandler.exportAllCalibrations(); + } + + @Override + public JComponent getComponent() { + return mainPanel; + } + +} diff --git a/src/tethys/calibration/swing/CalibrationsTable.java b/src/tethys/calibration/swing/CalibrationsTable.java new file mode 100644 index 00000000..45b91f18 --- /dev/null +++ b/src/tethys/calibration/swing/CalibrationsTable.java @@ -0,0 +1,285 @@ +package tethys.calibration.swing; + +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.JComponent; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.border.TitledBorder; +import javax.swing.table.AbstractTableModel; +import javax.xml.datatype.XMLGregorianCalendar; + +import PamController.PamController; +import PamController.soundMedium.GlobalMedium; +import PamController.soundMedium.GlobalMediumManager; +import PamUtils.PamCalendar; +import PamView.dialog.warn.WarnOnce; +import PamView.panel.PamPanel; +import PamView.tables.SwingTableColumnWidths; +import nilus.Calibration; +import tethys.Collection; +import tethys.DocumentNilusObject; +import tethys.TethysControl; +import tethys.TethysState; +import tethys.TethysState.StateType; +import tethys.TethysTimeFuncs; +import tethys.calibration.CalibrationHandler; +import tethys.dbxml.TethysException; +import tethys.swing.TethysGUIPanel; + +public class CalibrationsTable extends TethysGUIPanel { + + private CalibrationHandler calibrationHandler; + + private CalibrationsTableModel calTableModel; + + private JPanel mainPanel; + + private JTable calTable; + + private TethysControl tethysControl; + + /** + * @param calibrationHandler + */ + public CalibrationsTable(TethysControl tethysControl, CalibrationHandler calibrationHandler) { + super(tethysControl); + this.tethysControl = tethysControl; + this.calibrationHandler = calibrationHandler; + calTableModel = new CalibrationsTableModel(); + calTable = new JTable(calTableModel); + calTable.setRowSelectionAllowed(true); + calTable.addMouseListener(new TableMouse()); + + JScrollPane scrollPane = new JScrollPane(calTable); + + mainPanel = new PamPanel(new BorderLayout()); + mainPanel.add(BorderLayout.CENTER, scrollPane); + + calTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + new SwingTableColumnWidths(tethysControl.getUnitName()+"CalibrationsTable", calTable); + + } + + + @Override + public JComponent getComponent() { + return mainPanel; + } + + + @Override + public void updateState(TethysState tethysState) { + super.updateState(tethysState); + calTableModel.fireTableDataChanged(); + } + + private class TableMouse extends MouseAdapter { + + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) { + showPopupMenu(e); + } + } + + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) { + showPopupMenu(e); + } + } + + } + + public void showPopupMenu(MouseEvent e) { + int[] rows = calTable.getSelectedRows(); + if (rows == null || rows.length == 0) { + return; + } + int n = rows.length; + DocumentNilusObject doc = calibrationHandler.getCalibrationDataList().get(rows[0]); + + JPopupMenu popMenu = new JPopupMenu(); + JMenuItem menuItem; + if (n == 1) { + menuItem = new JMenuItem("Show document " + doc.getDocumentName()); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showCalibration(doc); + } + }); + popMenu.add(menuItem); + } + if (n > 1) { + menuItem = new JMenuItem("Delete selected documents"); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + deleteCalibrations(rows); + } + }); + popMenu.add(menuItem); + } + else { + menuItem = new JMenuItem("Delete document " + doc.getDocumentName()); + menuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + deleteCalibration(doc); + } + }); + popMenu.add(menuItem); + } + popMenu.show(e.getComponent(), e.getX(), e.getY()); + } + + protected void deleteCalibration(DocumentNilusObject doc) { + String docName = doc.getDocumentName(); + int ans = WarnOnce.showNamedWarning("delete doc " + Collection.Calibrations.collectionName(), + PamController.getMainFrame(), "Delete document", + "Are you sure you want to delete the document " + docName, WarnOnce.OK_CANCEL_OPTION); + if (ans == WarnOnce.OK_OPTION) { + try { + tethysControl.getDbxmlConnect().removeDocument(Collection.Calibrations.collectionName(), docName); + } catch (TethysException e) { + System.out.println("Failed to delete " + docName); + System.out.println(e.getMessage()); + } + } + updateEverything(); + calTableModel.fireTableDataChanged(); + } + + + protected void showCalibration(DocumentNilusObject docInfo) { + tethysControl.displayDocument(docInfo); + + } + + + protected void deleteCalibrations(int[] rows) { + String msg = String.format("Are you sure you want to delete %d calibrations documents ?", rows.length); + int ans = WarnOnce.showNamedWarning("Deletemanycalibrations", PamController.getMainFrame(), "Delete multiple documents", msg, WarnOnce.OK_CANCEL_OPTION); + if (ans != WarnOnce.OK_OPTION) { + return; + } + for (int i = 0; i < rows.length; i++) { + String docName = null; + try { + DocumentNilusObject doc = calibrationHandler.getCalibrationDataList().get(rows[i]); + docName = doc.getDocumentName(); + tethysControl.getDbxmlConnect().removeDocument(Collection.Calibrations, docName); + } catch (TethysException e) { + System.out.println("Failed to delete " + docName); + System.out.println(e.getMessage()); + } + } + + updateEverything(); + + } + + private void updateEverything() { + getTethysControl().sendStateUpdate(new TethysState(StateType.DELETEDATA, Collection.Calibrations)); + } + + class CalibrationsTableModel extends AbstractTableModel { + + private static final long serialVersionUID = 1L; + + private String[] columnNames = {"Document", "Id", "Date", "End to End", "Hydrophone"}; + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + DocumentNilusObject dataUnit = null; + try { + dataUnit = calibrationHandler.getCalibrationDataList().get(rowIndex); + } + catch (Exception e) { + return null; + } + if (dataUnit == null) { + return null; + } + Calibration cal = dataUnit.getNilusObject(); + switch (columnIndex) { + case 0: + return dataUnit.getDocumentName(); + case 1: + return cal.getId(); + case 2: + XMLGregorianCalendar ts = cal.getTimeStamp(); + if (ts == null) { + return null; + } + long ms = TethysTimeFuncs.millisFromGregorianXML(ts); + return PamCalendar.formatDBDate(ms); + case 3: + return getFSString(cal); + case 4: + return getPhoneString(cal); +// return String.format("%3.1fdB %s", cal.getSensitivityV(), cal.getType()); + } + return null; + } + + @Override + public int getRowCount() { + return calibrationHandler.getCalibrationDataList().size(); + } + + @Override + public int getColumnCount() { + return columnNames.length; + } + + @Override + public String getColumnName(int column) { + if (column == 4) { + return PamController.getInstance().getGlobalMediumManager().getRecieverString(); + } + else { + return columnNames[column]; + } + } + } + + public String getFSString(Calibration cal) { + Double fs = cal.getSensitivityDBFS(); + if (fs == null) { + return null; + } + double ir = cal.getIntensityReferenceUPa(); + String str = String.format("%3.1fdB", fs); + if (ir != 0) { + str += String.format(" re%.0f\u00B5Pa", ir); + } + return str; + } + + public Object getPhoneString(Calibration cal) { + Double dbV = cal.getSensitivityV(); + if (dbV == null) { + dbV = cal.getSensitivityDBV(); + } + if (dbV == null) { + return null; + } + double ir = cal.getIntensityReferenceUPa(); + String str = String.format("%3.1fdB", dbV); + if (ir != 0) { + str += String.format(" re%.0fV/\u00B5Pa", ir); + } + return str; + } +} diff --git a/src/tethys/database/TethysActions.java b/src/tethys/database/TethysActions.java new file mode 100644 index 00000000..0c9ece36 --- /dev/null +++ b/src/tethys/database/TethysActions.java @@ -0,0 +1,27 @@ +package tethys.database; + +/** + * Possible document actions + * @author dg50 + * + */ +public enum TethysActions { + + ADDDOCUMENT, DELETEDOCUMENT, UPDATEDOCUMENT; + +// @Override +// public String toString() { +// switch (this) { +// case ADDDOCUMENT: +// return "Add document"; +// case DELETEDOCUMENT: +// return "Delete document"; +// case UPDATEDOCUMENT: +// return "Update document"; +// default: +// return null; +// } +// } + + +} diff --git a/src/tethys/database/TethysLogDataBlock.java b/src/tethys/database/TethysLogDataBlock.java new file mode 100644 index 00000000..7a3639d6 --- /dev/null +++ b/src/tethys/database/TethysLogDataBlock.java @@ -0,0 +1,16 @@ +package tethys.database; + +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamProcess; +import tethys.TethysControl; + +public class TethysLogDataBlock extends PamDataBlock { + + private TethysControl tethysControl; + + public TethysLogDataBlock(TethysControl tethysControl) { + super(TethysLogDataUnit.class, "Tethys Log", null, 0); + this.tethysControl = tethysControl; + } + +} diff --git a/src/tethys/database/TethysLogDataUnit.java b/src/tethys/database/TethysLogDataUnit.java new file mode 100644 index 00000000..e1998c2b --- /dev/null +++ b/src/tethys/database/TethysLogDataUnit.java @@ -0,0 +1,59 @@ +package tethys.database; + +import PamguardMVC.PamDataUnit; + +public class TethysLogDataUnit extends PamDataUnit { + + private String collection; + private String documentId; + private TethysActions action; + private String comment; + private boolean success; + + public TethysLogDataUnit(long timeMilliseconds, String collection, String documentId, TethysActions action, boolean success, String comment) { + super(timeMilliseconds); + this.collection = collection; + this.documentId = documentId; + this.action = action; + this.success = success; + this.comment = comment; + + } + + /** + * @return the collection + */ + public String getCollection() { + return collection; + } + + /** + * @return the documentId + */ + public String getDocumentId() { + return documentId; + } + + /** + * @return the action + */ + public TethysActions getAction() { + return action; + } + + /** + * @return the comment + */ + public String getComment() { + return comment; + } + + /** + * @return the success + */ + public boolean isSuccess() { + return success; + } + + +} diff --git a/src/tethys/database/TethysLogger.java b/src/tethys/database/TethysLogger.java new file mode 100644 index 00000000..9e7ae2ad --- /dev/null +++ b/src/tethys/database/TethysLogger.java @@ -0,0 +1,128 @@ +package tethys.database; + +import java.sql.Types; + +import PamguardMVC.PamDataUnit; +import generalDatabase.DBControlUnit; +import generalDatabase.DBProcess; +import generalDatabase.PamConnection; +import generalDatabase.PamTableDefinition; +import generalDatabase.PamTableItem; +import generalDatabase.SQLLogging; +import generalDatabase.SQLTypes; +import tethys.TethysControl; + +/** + * Logging everything we put into Tethys in our own database. + * @author dg50 + * + */ +public class TethysLogger extends SQLLogging { + + private static TethysLogger tethysLogger; + + private TethysControl tethysControl; + + private TethysLogDataBlock logDataBlock; + + private PamTableDefinition tableDefinition; + + private PamTableItem collection, documentId, action, status, comment; + + private boolean tableChecked = false; + + private TethysLogger(TethysControl tethysControl, TethysLogDataBlock pamDataBlock) { + super(pamDataBlock); + this.tethysControl = tethysControl; + this.logDataBlock = pamDataBlock; + tableDefinition = new PamTableDefinition("TethysLog"); + tableDefinition.addTableItem(collection = new PamTableItem("Collection", Types.VARCHAR)); + tableDefinition.addTableItem(documentId = new PamTableItem("DocumentId", Types.VARCHAR)); + tableDefinition.addTableItem(action = new PamTableItem("Action", Types.VARCHAR)); + tableDefinition.addTableItem(status = new PamTableItem("Status", Types.VARCHAR)); + tableDefinition.addTableItem(comment = new PamTableItem("Comment", Types.VARCHAR)); + tableDefinition.setUpdatePolicy(UPDATE_POLICY_OVERWRITE); + setTableDefinition(tableDefinition); + } + + public static TethysLogger getTethysLogger(TethysControl tethysControl) { + if (tethysLogger == null) { + tethysLogger = createTethysLogger(tethysControl); + } + return tethysLogger; + } + + private boolean checkTable() { + if (tableChecked == true) { + return true; + } + if (findDBProcess() == null) { + return false; + } + else { + tableChecked = findDBProcess().checkTable(tableDefinition); + } + return tableChecked; + } + + public boolean logAction(String collection, String documentId, TethysActions action, boolean success, String comment) { + PamConnection con = findDBConnection(); + if (con == null) { + return false; + } + if (checkTable() == false) { + return false; + } + + TethysLogDataUnit dataUnit = new TethysLogDataUnit(System.currentTimeMillis(), collection, documentId, action, success, comment); + return this.logData(con, dataUnit); + } + + private PamConnection findDBConnection() { + return DBControlUnit.findConnection(); + } + + /** + * Find the database controlled unit.
Must exist in viewer mode surely, but perhaps + * created after the Tethys module if the user is really crafty ! + * @return the DB controlled unit. + */ + private DBControlUnit findDBControl() { + return DBControlUnit.findDatabaseControl(); + } + + /** + * Fine the database process. Should exist. + * @return + */ + private DBProcess findDBProcess() { + DBControlUnit dbControl = findDBControl(); + if (dbControl == null) { + return null; + } + return dbControl.getDbProcess(); + } + + private static TethysLogger createTethysLogger(TethysControl tethysControl) { + TethysLogDataBlock datablock = new TethysLogDataBlock(tethysControl); + TethysLogger newLogger = new TethysLogger(tethysControl, datablock); + return newLogger; + } + + + @Override + public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) { + TethysLogDataUnit tldu = (TethysLogDataUnit) pamDataUnit; + collection.setValue(tldu.getCollection()); + documentId.setValue(tldu.getDocumentId()); + action.setValue(tldu.getAction().toString()); + status.setValue(tldu.isSuccess() ? "Success" : "Fail"); + comment.setValue(tldu.getComment()); + } + +// public TethysLogger(TethysControl tethysControl) { +// this.tethysControl = tethysControl; +// } + + +} diff --git a/src/tethys/dbxml/DBQueryResult.java b/src/tethys/dbxml/DBQueryResult.java new file mode 100644 index 00000000..80a27246 --- /dev/null +++ b/src/tethys/dbxml/DBQueryResult.java @@ -0,0 +1,62 @@ +package tethys.dbxml; + +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +public class DBQueryResult { + + public long queryTimeMillis; + + public String queryResult; + + public String schemaPlan; + + public Exception queryException; + + public DBQueryResult(long queryTimeMillis, String queryResult, String schemaPlan) { + super(); + this.queryTimeMillis = queryTimeMillis; + this.queryResult = queryResult; + this.schemaPlan = schemaPlan; + } + + public DBQueryResult(long queryTimeMillis, Exception queryException) { + super(); + this.queryTimeMillis = queryTimeMillis; + this.queryException = queryException; + } + + /** + * Get the result as an XML document. + * @return XML document + * @throws ParserConfigurationException + * @throws SAXException + * @throws IOException + */ + public Document getDocument() throws ParserConfigurationException, SAXException, IOException { + if (queryResult == null) { + return null; + } + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + //API to obtain DOM Document instance + DocumentBuilder builder = null; + + //Create DocumentBuilder with default configuration + builder = factory.newDocumentBuilder(); + + //Parse the content to Document object + Document doc = builder.parse(new InputSource(new StringReader(queryResult))); + return doc; + } + +} diff --git a/src/tethys/dbxml/DBXMLConnect.java b/src/tethys/dbxml/DBXMLConnect.java new file mode 100644 index 00000000..e13b05fd --- /dev/null +++ b/src/tethys/dbxml/DBXMLConnect.java @@ -0,0 +1,546 @@ +package tethys.dbxml; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.util.ArrayList; + +import javax.xml.bind.JAXBException; + +import dbxml.JerseyClient; +import dbxml.Queries; +import dbxml.uploader.Importer; +import nilus.MarshalXML; +import tethys.Collection; +import tethys.TethysControl; +import tethys.database.TethysActions; +import tethys.database.TethysLogger; +import tethys.output.TethysExportParams; + +/** + * Class containing functions for managing the database connection. Opening, closing, + * writing, keeping track of performance, etc. + * @author Doug Gillespie, Katie O'Laughlin + * + */ +public class DBXMLConnect { + + private TethysControl tethysControl; + private File tempDirectory; + + private JerseyClient jerseyClient; + + private Queries queries; + + private String currentSiteURL; + +// public static String[] collections = {"Deployments", "Detections", "Localizations", "Calibrations", "SpeciesAbbreviations"}; + + public DBXMLConnect(TethysControl tethysControl) { + this.tethysControl = tethysControl; + + checkTempFolder(); + } + + /** + * Check the jersey client and the queries. Need to recreate + * if the url has changed. + * @return + */ + private boolean checkClient() { + if (jerseyClient == null || queries == null || currentSiteURL == null) { + return false; + } + TethysExportParams params = tethysControl.getTethysExportParams(); + if (!currentSiteURL.equalsIgnoreCase(params.getFullServerName())) { + return false; + } + return true; + } + + + /** + * Get the client. The client will only be recreated if the url changes + * @return Jersy client + */ + public synchronized JerseyClient getJerseyClient() { + if (!checkClient()) { + openConnections(); + } + return jerseyClient; + } + + /** + * Get the Queries object. This will only be recreated if the client changes. + * @return + */ + public synchronized Queries getTethysQueries() { + if (!checkClient()) { + openConnections(); + } + return queries; + } + + /** + * Convert a nilus Object into a file + * @param nilusObject nilus object + * @param file file (should not exist) + * @return file (will be the same as input file) + * @throws TethysException + */ + public File createXMLDocument(Object nilusObject, File file) throws TethysException { + Class objClass = nilusObject.getClass(); + try { + MarshalXML marshal = new MarshalXML(); + marshal.createInstance(objClass); + marshal.marshal(nilusObject, file.toString()); + } catch(IllegalArgumentException e) { + throw new TethysException("IllegalArgumentException posting to Tethys: " + e.getMessage(), null); + } catch (IOException e) { + throw new TethysException("IOException posting to Tethys: " + e.getMessage(), null); + } catch (JAXBException e) { + throw new TethysException("JAXBException posting to Tethys: " + e.getMessage(), null); + } + return file; + } + + /** + * Create a temporary nilus file. + * @param nilusObject + * @return + * @throws TethysException + */ + public File createTempXMLDocument(Object nilusObject) throws TethysException { + String tempName = getTempFileName(nilusObject); + tempName = tempDirectory.getAbsolutePath() + File.separator + tempName + ".xml"; + File tempFile = new File(tempName); + File retFile = createXMLDocument(nilusObject, tempFile); + retFile.deleteOnExit(); + return retFile; + } + + + public boolean postAndLog(Object nilusObject) throws TethysException + { + return postAndLog(nilusObject, null); + } + + /** + * I don't think this should ever be used since everything goes a bit pear + * shaped if the documentName isn't the same as the Id. However, for Calibration + * documents this is no longer the case, since a Calibration can have multiple + * entries on different dates, so allow it ! + * @param nilusObject + * @param documentName + * @return + * @throws TethysException + */ + public boolean postAndLog(Object nilusObject, String documentName) throws TethysException + { + TethysException e = null; + boolean success = false; + try { + success = postToTethys(nilusObject, documentName); + } + catch (TethysException ex) { + e = ex; + } + TethysLogger logger = TethysLogger.getTethysLogger(tethysControl); + Class objClass = nilusObject.getClass(); + Collection collection = Collection.fromClass(objClass); + String documentId = getDocumentId(nilusObject); + logger.logAction(collection.collectionName(), documentId, TethysActions.ADDDOCUMENT, success, ""); + if (e != null) { + throw (e); + } + return success; + } + + /** + * take a nilus object loaded with PamGuard data and post it to the Tethys database + * + * @param pamGuardObjs a nilus object loaded with PamGuard data + * @return error string, null string means there are no errors + * @throws TethysException + */ + private boolean postToTethys(Object nilusObject, String documentName) throws TethysException + { + Class objClass = nilusObject.getClass(); + Collection collection = Collection.fromClass(nilusObject.getClass()); + TethysExportParams params = new TethysExportParams(); + String importReturn = null; + if (documentName == null) { + documentName = getTempFileName(nilusObject); + } + documentName = tempDirectory.getAbsolutePath() + File.separator + documentName + ".xml"; + File tempFile = new File(documentName); + String bodgeName = documentName;//"C:\\Users\\dg50\\AppData\\Local\\Temp\\PAMGuardTethys\\Meygen2022_10a.xml"; + try { + MarshalXML marshal = new MarshalXML(); + marshal.createInstance(objClass); + marshal.marshal(nilusObject, tempFile.toString()); + // tempFile = stripXMLHeader(tempFile); + importReturn = Importer.ImportFiles(params.getFullServerName(), collection.collectionName(), + new String[] { bodgeName }, "", "", false); + + + tempFile.deleteOnExit(); + } catch(IllegalArgumentException e) { + throw new TethysException("IllegalArgumentException posting to Tethys: " + e.getMessage(), null); + } catch (IOException e) { + throw new TethysException("IOException posting to Tethys: " + e.getMessage(), null); + } catch (JAXBException e) { + throw new TethysException("JAXBException posting to Tethys: " + e.getMessage(), null); + } + + /* + * The returned string consists of the file name, then an XML report. + * Quite hard to see much common structure in this, so just look for + * two words, and + */ + boolean error = importReturn.contains(""); +// error = !success; might be a better options. + if (error) { + throw new TethysException("Error posting to Tethys", importReturn); + } + return success; + } + + /** + * Update a document within Tethys. We're assuming that a + * document with the same name in the same collection already + * exists. If it doesn't / has a different name, then use + * the removedocument function + * @param nilusDocument + * @return + * @throws TethysException + */ + public boolean updateDocument(Object nilusDocument) throws TethysException { + deleteDocument(nilusDocument); + return postToTethys(nilusDocument, null); + } + + /** + * Delete a nilus document from the database. The only field which + * needs to be populated here is the Id. The code also uses the object + * class to identify the correct collection. + * @param nilusDocument + * @return + * @throws TethysException + */ + public boolean deleteDocument(Object nilusDocument) throws TethysException { + + Class objClass = nilusDocument.getClass(); + Collection collection = Collection.fromClass(objClass); + String docId = getDocumentId(nilusDocument); + String result = null; + try { + result = jerseyClient.removeDocument(collection.collectionName(), docId ); + /** + * Return from a sucessful delete is something like + * + deployment = getTethysControl().getDeploymentHandler().createDeploymentDocument(freeId++, recordPeriod); + + ['ECoastNARW0'] + +An error will throw an exception. + */ + } + catch (Exception e) { +// System.out.printf("Error deleting %s %s: %s\n", collection, docId, e.getMessage()); + String msg = String.format("Error deleting %s:%s", collection, docId); + throw new TethysException(msg, e.getLocalizedMessage()); + } + // forceFlush(); + return true; + } + + /** + * Delete a Deploymnet and any contained Detections document. Doesn't work ! + * @param deploymentId + * @return + * @throws TethysException + */ + public boolean deleteDeployment(String deploymentId) throws TethysException { + ArrayList detDocNames = tethysControl.getDbxmlQueries().getDetectionsDocuments(deploymentId); + JerseyClient jerseyClient = getJerseyClient(); + Queries queries = null; + String result = null; + try { + result = jerseyClient.removeDocument("Deployments", deploymentId ); + } + catch (Exception e) { + throw new TethysException("Error deleting deployment document " + deploymentId, e.getMessage()); + } + return true; + } + + /** + * Remove a document based on a collection name and a cdocument Id. + * @param collection collection name. + * @param documentName document name (not the internal Document Id) + * @return + * @throws TethysException + */ + public boolean removeDocument(Collection collection, String documentName) throws TethysException { + return removeDocument(collection.collectionName(), documentName); + } + + /** + * Remove a document based on a collection name and a document namw. + * @param collectionName collection name. + * @param documentName document name (not the internal Document Id) + * @return + * @throws TethysException + */ + public boolean removeDocument(String collectionName, String documentName) throws TethysException { + try { + Object result = jerseyClient.removeDocument(collectionName, documentName ); + /** + * Return from a sucessful delete is something like + * + deployment = getTethysControl().getDeploymentHandler().createDeploymentDocument(freeId++, recordPeriod); + + ['ECoastNARW0'] + + An error will throw an exception. + */ + } + catch (Exception e) { + String msg = String.format("Error deleting %s:%s", collectionName, documentName); + throw new TethysException(msg, e.getLocalizedMessage()); + } + return true; + } + + /** + * check the return string from importFiles and if it's an + * error, throw an exception. Otherwise do nothing. + * @param fileError + */ + private void checkReturnString(String fileError) { + /** + * Example good string is + * +C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xml: 7360 bytes + + + added + + + 20080311_2DSimplex_0 + + + + +Example error (file not existing) +C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot: 0 bytes + + + C:\Users\dg50\AppData\Local\Temp\PAMGuardTethys\20080311_2DSimplex_0.xmlnot + does not exist + + + + + + */ + + + } + + /** + * Seems we have to get rid of the line + * which is being put there by the marshaller ? + * @param tempFile + */ + private File stripXMLHeader(File tempFile) { + // TODO Auto-generated method stub + + File tempTemp = new File(tempFile.getAbsolutePath().replace(".temp.xml", ".xml")); + try { + BufferedReader reader = new BufferedReader(new FileReader(tempFile)); + BufferedWriter writer = new BufferedWriter(new FileWriter(tempTemp)); + String line = reader.readLine(); + while (line != null) { + // see if the line has any unicode in it + int len = line.length(); + byte[] bytes = line.getBytes(); + if (len == bytes.length) { + System.out.println(line); + } + + if (line.startsWith(" getCollectionDocumentList(Collection collection) { + if (collection == null) { + return null; + } + + /** + * xQuery string based on examples in email from MR on 27/9/2023 + */ +// String baseQuery = " {\r\n" + String baseQuery = " {\r\n" + + " for $doc in collection(\"COLLECTIONAME\")/DOCUMENTNAME\r\n" + + " return\r\n" + + " {\r\n" + + " base-uri($doc), \r\n" + + " $doc/Id\r\n" + + " }\r\n" + + " \r\n" + + "} \r\n" + + ""; + String xQuery = baseQuery.replace("COLLECTIONAME", collection.collectionName()); + xQuery = xQuery.replace("DOCUMENTNAME", collection.documentName()); + + Queries queries = dbXMLConnect.getTethysQueries(); + String result = null; + try { + result = queries.QueryTethys(xQuery); + } + catch (Exception e) { +// e.printStackTrace(); + } + if (result == null) { + return null; + } +// System.out.println(result); + ArrayList documentInfos = new ArrayList<>(); + + Document doc = convertStringToXMLDocument(result); + if (doc == null) { + return null; + } +// PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); +// System.out.println(pamXMLWriter.getAsString(doc)); + /** + * lots of elements along lines of + * dbxml:///Deployments/Meygen20229Meygen20229 + */ + NodeList returns = doc.getElementsByTagName("doc"); + int n = returns.getLength(); + String toStrip = "dbxml:///"+collection.collectionName()+"/"; + for (int i = 0; i < n; i++) { + Node aNode = returns.item(i); + String nameStr = null; + String id = null; + NodeList kids = aNode.getChildNodes(); + for (int k = 0; k < kids.getLength(); k++) { + Node kidNode = kids.item(k); + String name = kidNode.getNodeName(); + String cont = kidNode.getTextContent(); + switch(name) { + case "#text": + nameStr = cont; + nameStr = nameStr.replaceFirst(toStrip, ""); + break; + case "Id": + id = kidNode.getTextContent(); + break; + default: + System.out.printf("Uknonwn node in Collection list %s item %d, Node %d name %s content %s\n", + collection, i, k, name, cont); + } + } +// if (i > 428) { +// System.out.println("MARU cal doc"); +// } + // this is the doc name with a load of stuff in front, + // e.g. dbxml:///Deployments/1705_Array-2017-09-261705_Array-2017-09-26 + if (nameStr == null) { + nameStr = aNode.getTextContent(); + nameStr = nameStr.replaceFirst(toStrip, ""); + } +// if (aNode instanceof Element) { + // nameStr = getElementData((Element) aNode, "#text"); + // } + + if (id == null) { + if (aNode instanceof Element) { + id = getElementData((Element) aNode, "Id"); + } + } + + DocumentInfo docInfo = new DocumentInfo(collection, nameStr, id); + documentInfos.add(docInfo); +// System.out.println(nameStr + " : " + id); + } + return documentInfos; + + + + // if (collection.endsWith("s")) { + // collection = collection.substring(0, collection.length()-1); + // } +// String baseQuery = "{\"return\":[\"COLLECTIONNAME/Id\"],\"select\":[],\"enclose\":1}"; +// baseQuery = baseQuery.replace("COLLECTIONNAME", collection); +// String tagName = "Id"; +// +// if (collection.equals("SpeciesAbbreviations")) { +// baseQuery = "{\"return\":[\"Abbreviations/Name\"],\"select\":[],\"enclose\":1}"; +// tagName = "Name"; +// } +// +// DBQueryResult result; +// try { +// result = executeQuery(baseQuery); +// } catch (TethysQueryException e) { +// System.out.println("Error with query: " + baseQuery); +// tethysControl.showException(e); +// return null; +// } +// +// if (result == null || result.queryResult == null) { +// return null; +// } +// Document doc = convertStringToXMLDocument(result.queryResult); +// if (doc == null) { +// return null; +// } +// NodeList returns = doc.getElementsByTagName(tagName); +// ArrayList docIds = new ArrayList<>(); +// int n = returns.getLength(); +// for (int i = 0; i < n; i++) { +// Node aNode = returns.item(i); +// String docId = aNode.getTextContent(); +// docIds.add(docId); +// } +// +// return docIds; + } + + /** + * Get a list of project names. + * @return + */ + public ArrayList getProjectNames() { + + String projectQuery = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}"; + + DBQueryResult result; + try { + result = executeQuery(projectQuery); + } catch (TethysQueryException e) { + tethysControl.showException(e); + return null; + } + + if (result == null || result.queryResult == null) { + return null; + } + + // System.out.println("Project query execution time millis = " + result.queryTimeMillis); + + ArrayList projectNames = new ArrayList<>(); + // iterate through the document and make a list of names, then make them unique. + /* looking for elements like this: + * + * check out the jaxb unmarshaller ... + + + LJ + + + */ + Document doc = convertStringToXMLDocument(result.queryResult); + if (doc == null) { + return null; + } + NodeList returns = doc.getElementsByTagName("Project"); + // System.out.println("N projects = " + returns.getLength()); + int n = returns.getLength(); + for (int i = 0; i < n; i++) { + Node aNode = returns.item(i); + String projName = aNode.getTextContent(); + if (projName != null) { + if (!projectNames.contains(projName)) { + projectNames.add(projName); + } + } + // } + // if (aNode instanceof Element) { + // Node depEl = ((Element) aNode).getFirstChild(); + // if (depEl == null) { + // continue; + // } + // if (depEl instanceof Element) { + // Element projEl = (Element) ((Element) depEl).getFirstChild(); + // String projName = projEl.getTextContent(); + // if (projName != null) { + // if (!projectNames.contains(projName)) { + // projectNames.add(projName); + // } + // } + // } + // } + } + + Collections.sort(projectNames); + + return projectNames; + } + + /** + * Get project deployments that use a specific instrument id. More use than the call without this + * extra clause since it can handle overlapping deployments. + * @param projectName + * @param instrumentId + * @return + */ + public ArrayList getProjectDeployments(String projectName, String instrumentId) { + if (projectName == null) { + return null; + } + String qBase = "{\"return\":[\"Deployment\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"%s\"],\"optype\":\"binary\"},{\"op\":\"=\"," + + "\"operands\":[\"Deployment/Instrument/InstrumentId\",\"%s\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String qStr = String.format(qBase, projectName, instrumentId); + + return runProjectDeploymentsQuery(projectName, qStr); + } + /** + * Get some basic (not all) data for deployments associated with a project. Note that + * this may include deployments which are NOT part of the current dataset. That requires + * a search on Instrument as well. + * @param projectName + * @return + */ + public ArrayList getProjectDeployments(String projectName) { + if (projectName == null) { + return null; + } + String qBase = "{\"return\":[\"Deployment\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"%s\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String qStr = String.format(qBase, projectName); + return runProjectDeploymentsQuery(projectName, qStr); + } + + /** + * Run the actual projects query from either of the two above functions. + * @param projectName + * @param qStr + * @return + */ + private ArrayList runProjectDeploymentsQuery(String projectName, String qStr) { + DBQueryResult result = null; + try { + result = executeQuery(qStr); + } catch (TethysQueryException e1) { + tethysControl.showException(e1); + } + if (result == null) { + return null; + } + // System.out.println("Deployment query execution time millis = " + result.queryTimeMillis); + + PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + + Document doc = convertStringToXMLDocument(result.queryResult); + if (doc == null) { + return null; + } + + // System.out.println(pamXMLWriter.getAsString(doc)); + + ArrayList deployments = new ArrayList<>(); + + NodeList returns = doc.getElementsByTagName("Deployment"); + // if (returns.getLength() == 0) { + // // try REsult instead ! + // returns = doc.getElementsByTagName("Result"); + // } + // System.out.println("N projects = " + returns.getLength()); + int n = returns.getLength(); + + // Queries queries = new Queries(null) + for (int i = 0; i < n; i++) { + Node aNode = returns.item(i); + if (aNode instanceof Element) { + Element returnedEl = (Element) aNode; + + String Id = getElementData(returnedEl, "Id"); + String project = getElementData(returnedEl, "Project"); + String DeploymentId = getElementData(returnedEl, "DeploymentId"); + String instrType = getElementData(returnedEl, "Instrument.Type"); + String instrId = getElementData(returnedEl, "Instrument.InstrumentId"); + String geometry = getElementData(returnedEl, "Instrument.GeometryType"); + String audioStart = getElementData(returnedEl, "DeploymentDetails.AudioTimeStamp"); + String audioEnd = getElementData(returnedEl, "RecoveryDetails.AudioTimeStamp"); + String region = getElementData(returnedEl, "Region"); + Deployment deployment = new Deployment(); + try { + Helper.createRequiredElements(deployment); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + deployment.setId(Id); + deployment.setProject(projectName); + deployment.setDeploymentId(Integer.valueOf(DeploymentId)); + XMLGregorianCalendar gcStart = TethysTimeFuncs.fromGregorianXML(audioStart); + XMLGregorianCalendar gcEnd = TethysTimeFuncs.fromGregorianXML(audioEnd); + // System.out.printf("Converted %s to %s\n", audioStart, + // PamCalendar.formatDBDateTime(TethysTimeFuncs.millisFromGregorianXML(gcStart), true)); + deployment.getDeploymentDetails().setAudioTimeStamp(gcStart); + if (deployment.getRecoveryDetails() == null) { + deployment.setRecoveryDetails(new DeploymentRecoveryDetails()); + } + deployment.getRecoveryDetails().setAudioTimeStamp(gcEnd); + if (instrType != null || instrId != null) { + Instrument instrument = new Instrument(); + instrument.setType(instrType); + instrument.setInstrumentId(instrId); + instrument.setGeometryType(geometry); + deployment.setInstrument(instrument); + } + deployment.setRegion(region); + deployments.add(deployment); + } + } + return deployments; + } + + /** + * Get a list of Detections documents which associate with a datablock and a deploymentId. + * @param dataBlock + * @param deploymentId can be null to get all docs for data block + * @return + */ + public ArrayList getDetectionsDocuments(PamDataBlock dataBlock, String deploymentId) { + /** + * first query for Detections documents associated with this deployment and datablock. + * updated May 23 + */ + String queryNoDepl = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String queryWithDepl = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"TheDeploymentId\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String query; + if (deploymentId == null) { + query = queryNoDepl; + } + else { + query = queryWithDepl.replace("TheDeploymentId", deploymentId); + } + query = query.replace("LongDataName", dataBlock.getLongDataName()); + DBQueryResult queryResult = null; + try { + queryResult = executeQuery(query); + } catch (TethysQueryException e1) { + tethysControl.showException(e1); + return null; + } + if (queryResult ==null) { + return null; + } + Document doc; + try { + doc = queryResult.getDocument(); + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + return null; + } + if (doc == null) { + return null; + } + ArrayList detectionsNames = new ArrayList(); + int count = 0; + NodeList returns = doc.getElementsByTagName("Detections"); + // if (returns.getLength() == 0) { + // returns = doc.getElementsByTagName("Result"); + // } + for (int i = 0; i < returns.getLength(); i++) { + Node aNode = returns.item(i); + String docName = aNode.getTextContent(); + detectionsNames.add(docName); + } + return detectionsNames; + } + + + /** + * Get the names of all detection documents for a given deployment for all data streams. + * @param deploymentId + * @return + */ + public ArrayList getDetectionsDocuments(String deploymentId) { + String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String queryStr = queryBase.replace("SomeDeploymentId", deploymentId); + DBQueryResult queryResult = null; + try { + queryResult = executeQuery(queryStr); + } catch (TethysQueryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (queryResult == null || queryResult.queryException != null) { + return null; + } + + // PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + + Document doc = convertStringToXMLDocument(queryResult.queryResult); + if (doc == null) { + return null; + } + + ArrayList detectionDocs = new ArrayList<>(); + + NodeList returns = doc.getElementsByTagName("Record"); + if (returns.getLength() == 0) { + returns = doc.getElementsByTagName("Record"); + } + for (int i = 0; i < returns.getLength(); i++) { + Node aNode = returns.item(i); + detectionDocs.add(aNode.getTextContent()); + } + return detectionDocs; + } + + public int countData(PamDataBlock dataBlock, String deploymentId) { + // /** + // * first query for Detections documents associated with this deployment and datablock. + // */ + // String queryNoDepl = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // String queryWithDepl = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Algorithm/Software\",\"LongDataName\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"TheDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // String query; + // if (deploymentId == null) { + // query = queryNoDepl; + // } + // else { + // query = queryWithDepl.replace("TheDeploymentId", deploymentId); + // } + // query = query.replace("LongDataName", dataBlock.getLongDataName()); + // DBQueryResult queryResult = executeQuery(query); + // if (queryResult ==null) { + // return 0; + // } + // Document doc; + // try { + // doc = queryResult.getDocument(); + // } catch (ParserConfigurationException | SAXException | IOException e) { + // e.printStackTrace(); + // return 0; + // } + // + // int count = 0; + // NodeList returns = doc.getElementsByTagName("Return"); + ArrayList documentNames = getDetectionsDocuments(dataBlock, deploymentId); + if (documentNames == null) { + return 0; + } + int count = 0; + for (String docName : documentNames) { + // System.out.println(aNode.getTextContent()); + int count2 = countDetections2(docName); + count += count2; //countDetecionsData(docName); + + } + return count; + } + + public String getDocument(String collection, String documentId) { + // String queryBase = "return:(collection(\"replaceCollectionName\")/Detections[Id=\"ReplaceDocumentId\"])"; + // queryBase = queryBase.replace("replaceCollectionName", collection); + // queryBase = queryBase.replace("ReplaceDocumentId", documentId); + // + // String result = null; + // try { + // Queries queries = dbXMLConnect.getTethysQueries(); + // result = queries.QueryTethys(queryBase); + //// System.out.println(result); + // } + // catch (Exception e) { + // System.out.println("Error executing " + queryBase); + //// e.printStackTrace(); + // return null; + // } + // return result; + + Queries queries = dbXMLConnect.getTethysQueries(); + String result = null; + try { + result = queries.getDocument(collection, documentId); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return result; + + // String queryBase = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}"; + } + + /** + * Find out if a document exists ? + * @param collection + * @param documentId + * @return + */ + public boolean documentExists(String collection, String documentId) { + Queries queries = dbXMLConnect.getTethysQueries(); + String result = null; + try { + result = queries.getDocument(collection, documentId); + } catch (Exception e) { + return false; + } + if (result == null || result.length() == 0) { + return false; + } + + return result.contains(documentId); + } + + /** + * Count on effort detections in a Detections document + * @param docName + * @return + */ + public int countDetections2(String docName) { + TethysExportParams params = tethysControl.getTethysExportParams(); + String queryBase = "count(collection(\"Detections\")/Detections[Id=\"ReplaceDocumentId\"]/OnEffort/Detection)"; + String query = queryBase.replace("ReplaceDocumentId", docName); + + String result = null; + try { + Queries queries = dbXMLConnect.getTethysQueries(); + result = queries.QueryTethys(query); + // System.out.println(result); + } + catch (Exception e) { + System.out.println("Error executing " + query); + // e.printStackTrace(); + return -1; + } + int count = 0; + try { + count = Integer.valueOf(result); + } + catch (NumberFormatException e) { + System.out.println("Unable to interpret count data " + result); + return 0; + } + return count; + } + + // /** + // * Get a count of the detections in a detections document. + // * Only looking in onEffort so far. + // * @param deploymentId + // * @param detectionDocId + // * @param dataBlock + // * @return + // */ + // public int getDetectionsDetectionCount(String deploymentId, String detectionDocId, PamDataBlock dataBlock) { + // String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"SomeDetectionsId\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"SomeDeploymentId\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // String queryStr = queryBase.replace("SomeDetectionsId", detectionDocId); + // queryStr = queryStr.replace("SomeDeploymentId", deploymentId); + // DBQueryResult queryResult = executeQuery(queryStr); + // if (queryResult == null || queryResult.queryException != null) { + // return 0; + // } + //// System.out.println("Detections query time ms = " + queryResult.queryTimeMillis); + // + // PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + // + // Document doc = convertStringToXMLDocument(queryResult.queryResult); + // if (doc == null) { + // return 0; + // } + // + //// System.out.println(pamXMLWriter.getAsString(doc)); + // + //// ArrayList detectionDocs = new ArrayList<>(); + // + // NodeList returns = doc.getElementsByTagName("Start"); + // int n = returns.getLength(); + // return n; + // } + + // /** + // * This is the quickest way of counting data in a project, but it will load the start + // * times for every detection in a project at once, so might use a lot of memory. Also + // * it wll probably get data for all deployments in a project, which may not be what we want. + // * @param projectName + // * @param dataPrefixes + // * @return + // */ + // public int[] countDataForProject(String projectName, String[] dataPrefixes) { + // int[] n = new int[dataPrefixes.length]; + // ArrayList matchedDeployments = tethysControl.getDeploymentHandler().getMatchedDeployments(); + //// ArrayList deployments = getProjectDeployments(projectName); + // if (matchedDeployments == null) { + // return null; + // } + // for (PDeployment aDeployment : matchedDeployments) { + //// ArrayList detectionsIds = getDetectionsDocsIds(aDeployment.getId()); + //// for (String detId : detectionsIds) { + //// n += getDetectionsDetectionCount(aDeployment.getId(), detId, dataBlock); + //// } + // int[] newN = countDataForDeployment(projectName, aDeployment.deployment.getId(), dataPrefixes); + // for (int i = 0; i < n.length; i++) { + // n[i] += newN[i]; + // } + // } + // return n; + // } + + /** + * Count data within a deployment document which is associated with a set of datablocks + * Since the detections all come back in one query, it's easier to count all datablocks at once so + * that it can all happen off a single query. + * @param id + * @param dataBlockPrefixes + * @return + */ + private int[] countDataForDeployment(String projectId, String deploymentId, String[] dataPrefixes) { + String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\",\"Detections/OnEffort/Detection/Start\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/DataSource/DeploymentId\",\"ReplaceDeploymentIdString\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String queryString = queryBase.replace("ReplaceDeploymentIdString", deploymentId); + DBQueryResult result; + try { + result = executeQuery(queryString); + } catch (TethysQueryException e) { + tethysControl.showException(e); + return null; + } + if (result == null || result.queryResult == null) { + return null; + } + PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + + Document doc = convertStringToXMLDocument(result.queryResult); + if (doc == null) { + return null; + } + + // System.out.println(pamXMLWriter.getAsString(doc)); + + NodeList detsDocs = doc.getElementsByTagName("Detections"); + int[] blockCounts = new int[dataPrefixes.length]; + + // String detDocPrefix = projectId + "_" + dataBlock.getDataName(); + + // int totalCalls = 0; + int detCount = 0; + int dataIndex; + for (int i = 0; i < detsDocs.getLength(); i++) { + Node detNode = detsDocs.item(i); + + NodeList childNodes = detNode.getChildNodes(); + detCount = childNodes.getLength()-1; + dataIndex = -1; + for (int n = 0; n < childNodes.getLength(); n++) { + Node aNode = childNodes.item(n); + if (aNode instanceof Element) { + Element el = (Element) aNode; + String nodeName = el.getNodeName(); + if (nodeName.equals("Id")) { + String id = el.getTextContent(); + for (int j = 0; j < dataPrefixes.length; j++) { + if (id != null && id.startsWith(dataPrefixes[j])) { + dataIndex = j; + } + } + // if (id != null && id.startsWith(detDocPrefix) == false) { + // detCount = 0; + // break; + // } + } + } + } + if (dataIndex >= 0) { + blockCounts[dataIndex] += detCount; + } + // System.out.printf("%d Added %d for new total %d\n",i, detCount, totalCalls); + } + + return blockCounts; + } + + public String getElementData(Element root, String elName) { + String[] tree = elName.split("\\."); + for (String element : tree) { + NodeList nodeList = root.getElementsByTagName(element); + // should only be one node for what we're unpacking. + if (nodeList == null || nodeList.getLength() == 0) { + return null; + } + int count = nodeList.getLength(); + for (int i = 0; i < count; i++) { + Node firstNode = nodeList.item(i); + if (firstNode instanceof Element) { + root = (Element) firstNode; + break; + } + } + } + return root.getTextContent(); + } + + + public String getElementAttribute(Element root, String elName, String attribute) { + String[] tree = elName.split("\\."); + for (String element : tree) { + NodeList nodeList = root.getElementsByTagName(element); + // should only be one node for what we're unpacking. + if (nodeList == null || nodeList.getLength() == 0) { + return null; + } + int count = nodeList.getLength(); + for (int i = 0; i < count; i++) { + Node firstNode = nodeList.item(i); + if (firstNode instanceof Element) { + root = (Element) firstNode; + break; + } + } + } + return root.getAttribute(attribute); + } + + public Document convertStringToXMLDocument(String xmlString) { + //Parser that produces DOM object trees from XML content + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + //API to obtain DOM Document instance + DocumentBuilder builder = null; + try { + //Create DocumentBuilder with default configuration + builder = factory.newDocumentBuilder(); + + //Parse the content to Document object + Document doc = builder.parse(new InputSource(new StringReader(xmlString))); + return doc; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * Get the basic information about a Detections document. This is basically everything apart from + * the actual detections themselves. + * @param aDoc + * @return + */ + public Detections getDetectionsDocInfo(String detectionsDocName) { +// String oldqueryBase = "{\"species\":{\"query\":{\"op\":\"lib:abbrev2tsn\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]},\"return\":{\"op\":\"lib:tsn2abbrev\",\"optype\":\"function\",\"operands\":[\"%s\",\"SIO.SWAL.v1\"]}},\"return\":[\"Detections/Id\",\"Detections/Description\",\"Detections/DataSource\",\"Detections/Algorithm\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"DetectionsDocName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + // updated May 23 + String queryBase = "{\"species\":{\"query\":{\"op\":\"lib:completename2tsn\",\"optype\":\"function\",\"operands\":[\"%s\"]},\"return\":{\"op\":\"lib:tsn2completename\",\"optype\":\"function\",\"operands\":[\"%s\"]}},\"return\":[\"Detections/Id\",\"Detections/Description\",\"Detections/DataSource\",\"Detections/Algorithm\",\"Detections/QualityAssurance\",\"Detections/UserId\",\"Detections/MetadataInfo\",\"Detections/Effort\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Detections/Id\",\"DetectionsDocName\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String query = queryBase.replace("DetectionsDocName", detectionsDocName); + DBQueryResult queryResult; + try { + queryResult = executeQuery(query); + } catch (TethysQueryException e) { + tethysControl.showException(e); + return null; + } + Document doc; + try { + doc = queryResult.getDocument(); + } catch (ParserConfigurationException | SAXException | IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + // System.out.println(queryResult.queryResult); + + Detections detections = new Detections(); + try { + Helper.createRequiredElements(detections); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + + NodeList returns = doc.getElementsByTagName("Result"); + // System.out.println("N projects = " + returns.getLength()); + int n = returns.getLength(); + if (n == 0) { + return null; + } + Element result = (Element) returns.item(0); + + DescriptionType description = detections.getDescription(); + if (description == null) { + description = new DescriptionType(); + detections.setDescription(description); + } + detections.setId(getElementData(result, "Id")); + description.setAbstract(getElementData(result, "Description.Abstract")); + description.setMethod(getElementData(result, "Description.Method")); + description.setObjectives(getElementData(result, "Description.Objectives")); + + String deployment = getElementData(result, "DataSource.DeploymentId"); + if (deployment != null) { + DataSourceType dataSource = detections.getDataSource(); + if (dataSource == null) { + dataSource = new DataSourceType(); + detections.setDataSource(dataSource); + } + dataSource.setDeploymentId(deployment); + } + + // get the effort start an end + String effStart = getElementData(result, "Effort.Start"); + String effEnd = getElementData(result, "Effort.End"); + detections.getEffort().setStart(TethysTimeFuncs.fromGregorianXML(effStart)); + detections.getEffort().setEnd(TethysTimeFuncs.fromGregorianXML(effEnd)); + // try to find the granularity. + String granularityString = getElementData(result, "Effort.Kind.Granularity"); + GranularityEnumType granularity = null; + if (granularityString != null) { + granularity = GranularityEnumType.fromValue(granularityString); + List kinds = detections.getEffort().getKind(); + DetectionEffortKind kind = new DetectionEffortKind(); + GranularityType granularityType = new GranularityType(); + granularityType.setValue(granularity); + kind.setGranularity(granularityType); + // try to find the rest of the granularity information. + String binSize_m = getElementAttribute(result, "Effort.Kind.Granularity", "BinSize_m"); + String encounterGap_m = getElementAttribute(result, "Effort.Kind.Granularity", "EncounterGap_m"); + String firstBinStart = getElementAttribute(result, "Effort.Kind.Granularity", "FirstBinStart"); + try { + granularityType.setBinSizeMin(Double.valueOf(binSize_m)); + } + catch (NumberFormatException e) { + } + try { + granularityType.setEncounterGapMin(Double.valueOf(encounterGap_m)); + } + catch (NumberFormatException e) { + } + + kinds.add(kind); + } + // String + + + + // TODO Auto-generated method stub + return detections; + } + +} diff --git a/src/tethys/dbxml/DMXMLQueryTest.java b/src/tethys/dbxml/DMXMLQueryTest.java new file mode 100644 index 00000000..e16e202a --- /dev/null +++ b/src/tethys/dbxml/DMXMLQueryTest.java @@ -0,0 +1,79 @@ +package tethys.dbxml; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +import PamController.settings.output.xml.PamguardXMLWriter; +import dbxml.JerseyClient; +import tethys.output.TethysExportParams; + +public class DMXMLQueryTest { + + public static void main(String[] args) { + new DMXMLQueryTest().runTest(); + } + + private void runTest() { + TethysExportParams params = new TethysExportParams(); + + JerseyClient jerseyClient = new JerseyClient(params.getFullServerName()); + +// String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/DeploymentId\",\"Deployment/Site\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\"],\"select\":[],\"enclose\":1}"; +// String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/Region\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/DeploymentId\",\"2\"],\"optype\":\"binary\"}],\"enclose\":1}"; + //String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/Region\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/DeploymentId\",\"2\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"DCLDE2022\"],\"optype\":\"binary\"}],\"enclose\":1}"; +// String testJson = "{\"return\":[\"Deployment/Project\",\"Deployment/Region\",\"Deployment/DeploymentDetails/AudioTimeStamp\",\"Deployment/RecoveryDetails/AudioTimeStamp\",\"Deployment/DeploymentId\"],\"select\":[{\"op\":\"=\",\"operands\":[\"Deployment/DeploymentId\",\"2\"],\"optype\":\"binary\"},{\"op\":\"=\",\"operands\":[\"Deployment/Project\",\"DCLDE2022\"],\"optype\":\"binary\"}],\"enclose\":1}"; + String testJson = "{\"return\":[\"Deployment/Project\"],\"select\":[],\"enclose\":1}"; + // web browse to http://localhost:9779/Client + + String testResult = jerseyClient.queryJSON(testJson); + + Document doc = convertStringToXMLDocument(testResult); + + PamguardXMLWriter pamXMLWriter = PamguardXMLWriter.getXMLWriter(); + String formettedXML = pamXMLWriter.getAsString(doc, true); + + System.out.println(testResult); + System.out.println(formettedXML); +// try { +// Transformer serializer = SAXTransformerFactory.newInstance() +// .newTransformer(); +// Source source = new StreamSource(testResult); +// ByteArrayOutputStream bytes = new ByteArrayOutputStream(); +// StreamResult res = new StreamResult(bytes); +// serializer.transform(source, res); +// System.out.println(bytes.toString()); +// } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) { +// e.printStackTrace(); +// } +// // System.err.println(testResult); +// catch (TransformerException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + + } + + private Document convertStringToXMLDocument(String xmlString) { + //Parser that produces DOM object trees from XML content + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + + //API to obtain DOM Document instance + DocumentBuilder builder = null; + try { + //Create DocumentBuilder with default configuration + builder = factory.newDocumentBuilder(); + + //Parse the content to Document object + Document doc = builder.parse(new InputSource(new StringReader(xmlString))); + return doc; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/tethys/dbxml/ServerStatus.java b/src/tethys/dbxml/ServerStatus.java new file mode 100644 index 00000000..25c9ebbf --- /dev/null +++ b/src/tethys/dbxml/ServerStatus.java @@ -0,0 +1,35 @@ +package tethys.dbxml; + +public class ServerStatus { + + public boolean ok; + + public Exception error; + + public ServerStatus(boolean ok, Exception error) { + super(); + this.ok = ok; + this.error = error; + } + + public String getFormatted() { + if (ok) { + return "Server OK"; + } + if (error == null) { + return "Unknown error"; + } + String msg = error.getLocalizedMessage(); + if (msg.startsWith("Exception")) { + msg.substring(9); + } + return msg; + } + + @Override + public String toString() { + return getFormatted(); + } + + +} diff --git a/src/tethys/dbxml/TethysException.java b/src/tethys/dbxml/TethysException.java new file mode 100644 index 00000000..034a1970 --- /dev/null +++ b/src/tethys/dbxml/TethysException.java @@ -0,0 +1,18 @@ +package tethys.dbxml; + +public class TethysException extends Exception { + + private static final long serialVersionUID = 1L; + + private String xmlError; + + public TethysException(String message, String xmlError) { + super(message); + this.xmlError = xmlError; + } + + public String getXmlError() { + return xmlError; + } + +} diff --git a/src/tethys/dbxml/TethysQueryException.java b/src/tethys/dbxml/TethysQueryException.java new file mode 100644 index 00000000..7f46d7bc --- /dev/null +++ b/src/tethys/dbxml/TethysQueryException.java @@ -0,0 +1,19 @@ +package tethys.dbxml; + +public class TethysQueryException extends TethysException { + + + private static final long serialVersionUID = 1L; + + private String queryString; + + public TethysQueryException(String message, String queryString) { + super(message, null); + this.queryString = queryString; + } + + public String getQueryString() { + return queryString; + } + +} diff --git a/src/tethys/deployment/DeploymentExportOpts.java b/src/tethys/deployment/DeploymentExportOpts.java new file mode 100644 index 00000000..18fa461f --- /dev/null +++ b/src/tethys/deployment/DeploymentExportOpts.java @@ -0,0 +1,43 @@ +package tethys.deployment; + +import java.io.Serializable; + +/** + * options for Deployment export collected by the export Wizard. + * @author dg50 + * + */ +public class DeploymentExportOpts implements Serializable, Cloneable { + + public static final long serialVersionUID = 1L; + + public boolean separateDeployments; + + /** + * Minimum number of seconds between GPS points in a track. + */ + public double trackPointInterval; + + /** + * Max gap before recording periods are separated, potentially into + * separate Deployment documents + */ + public int maxRecordingGapSeconds = 60; + + /** + * A recording section after joining with max gap parameter is too short + * to be worth keeping. + */ + public int minRecordingLengthSeconds = 10; + + @Override + protected DeploymentExportOpts clone() { + try { + return (DeploymentExportOpts) super.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + return null; + } + } + +} diff --git a/src/tethys/deployment/DeploymentHandler.java b/src/tethys/deployment/DeploymentHandler.java new file mode 100644 index 00000000..85f834c3 --- /dev/null +++ b/src/tethys/deployment/DeploymentHandler.java @@ -0,0 +1,1270 @@ +package tethys.deployment; + +import java.awt.Window; +import java.io.Serializable; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.ListIterator; + +import javax.xml.bind.JAXBException; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.apache.commons.beanutils.converters.BigIntegerConverter; + +import Acquisition.AcquisitionControl; +import Acquisition.AcquisitionParameters; +import Acquisition.DaqStatusDataUnit; +import Acquisition.DaqSystem; +import Acquisition.FolderInputSystem; +import Array.ArrayManager; +import Array.Hydrophone; +import Array.HydrophoneLocator; +import Array.PamArray; +import Array.Streamer; +import Array.ThreadingHydrophoneLocator; +import GPS.GPSControl; +import GPS.GPSDataBlock; +import GPS.GpsData; +import GPS.GpsDataUnit; +import PamController.PamSensor; +import PamController.PamSettingManager; +import PamController.PamSettings; +import PamController.PamControlledUnit; +import PamController.PamControlledUnitSettings; +import PamController.PamController; +import PamUtils.PamUtils; +import PamguardMVC.PamDataBlock; +import PamguardMVC.PamRawDataBlock; +import binaryFileStorage.BinaryStore; +import dataMap.OfflineDataMap; +import dataMap.OfflineDataMapPoint; +import generalDatabase.DBControlUnit; +import metadata.MetaDataContol; +import metadata.PamguardMetaData; +import nilus.Audio; +import nilus.ChannelInfo; +import nilus.ChannelInfo.DutyCycle; +import nilus.ChannelInfo.DutyCycle.Regimen.RecordingDurationS; +import nilus.ChannelInfo.DutyCycle.Regimen.RecordingIntervalS; +import nilus.ChannelInfo.Sampling; +import nilus.ChannelInfo.Sampling.Regimen; +import nilus.Deployment; +import nilus.Deployment.Data; +import nilus.Deployment.Data.Tracks; +import nilus.Deployment.Data.Tracks.Track; +import nilus.Deployment.Data.Tracks.Track.Point; +import nilus.Deployment.Data.Tracks.Track.Point.BearingDegN; +import nilus.Deployment.Instrument; +import nilus.Deployment.SamplingDetails; +import nilus.Deployment.Sensors; +import nilus.DeploymentRecoveryDetails; +import nilus.DescriptionType; +import nilus.GeometryTypeM; +import nilus.Helper; +import nilus.MetadataInfo; +import nilus.UnknownSensor; +import pamMaths.PamVector; +import pamMaths.STD; +import tethys.Collection; +import tethys.TethysControl; +import tethys.TethysLocationFuncs; +import tethys.TethysState; +import tethys.TethysStateObserver; +import tethys.TethysTimeFuncs; +import tethys.calibration.CalibrationHandler; +import tethys.TethysState.StateType; +import tethys.dbxml.DBXMLConnect; +import tethys.dbxml.TethysException; +import tethys.deployment.swing.DeploymentWizard; +import tethys.deployment.swing.RecordingGapDialog; +import tethys.niluswraps.PDeployment; +import tethys.output.TethysExportParams; +import tethys.pamdata.AutoTethysProvider; +import tethys.swing.DeploymentTableObserver; + +/** + * Functions to gather data for the deployment document from all around PAMGuard. + * There should be just one of these, available from TethysControl and it will try + * to sensible handle when and how it updates it's list of PAMGuard and Tethys information + *
Any part of PAMGuard wanting information on Deployments should come here. + * @author dg50 + * + */ +public class DeploymentHandler implements TethysStateObserver, DeploymentTableObserver { + + private TethysControl tethysControl; + + /** + * @return the tethysControl + */ + public TethysControl getTethysControl() { + return tethysControl; + } + + private EffortFunctions effortFunctions; + + private DeploymentOverview deploymentOverview; + + private ArrayList projectDeployments; + + private Helper nilusHelper; + + private DeploymentExportOpts deploymentExportOptions = new DeploymentExportOpts(); + + public DeploymentHandler(TethysControl tethysControl) { + super(); + + this.tethysControl = tethysControl; + + this.effortFunctions = new EffortFunctions(tethysControl); + + tethysControl.addStateObserver(this); + try { + nilusHelper = new Helper(); + } catch (JAXBException e) { + e.printStackTrace(); + } + + PamSettingManager.getInstance().registerSettings(new SettingsHandler()); + } + + /** + * Gather up all track information both from the GPS module (if it exists) and + * the type of hydrophone array (or many!) + * @return + */ + public TrackInformation getTrackInformation() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nStreamers = array.getStreamerCount(); + HydrophoneLocator locator = null; + for (int i = 0; i < nStreamers; i++) { + Streamer aStreamer = array.getStreamer(i); + locator = aStreamer.getHydrophoneLocator(); +// locator.getLocatorSettings(). + } + // try to find a GPS datablock and see what's in it's datamap. + OfflineDataMap gpsDataMap = null; + GPSControl gpsControl = (GPSControl) PamController.getInstance().findControlledUnit(GPSControl.gpsUnitType); + if (gpsControl != null) { + GPSDataBlock gpsDataBlock = gpsControl.getGpsDataBlock(); + gpsDataMap = gpsDataBlock.getPrimaryDataMap(); + } + TrackInformation trackInformation = new TrackInformation(gpsDataMap, locator); + return trackInformation; + } + + @Override + public void updateState(TethysState tethysState) { + switch (tethysState.stateType) { + case NEWPROJECTSELECTION: + updateProjectDeployments(); + break; + case EXPORTRDATA: + case DELETEDATA: + updateProjectDeployments(); + break; + case UPDATESERVER: + updateProjectDeployments(); + break; + default: + break; + } + } + + /** + * Update the list of Tethys deployments + * @return true if OK + */ + public boolean updateProjectDeployments() { + Deployment projData = tethysControl.getGlobalDeplopymentData(); + ArrayList tethysDocs = tethysControl.getDbxmlQueries().getProjectDeployments(projData.getProject(), getInstrumentId()); + if (tethysDocs == null) { + return false; + } + projectDeployments = new ArrayList<>(); + for (Deployment deployment : tethysDocs) { + projectDeployments.add(new PDeployment(deployment)); + } + matchPamguard2Tethys(deploymentOverview, projectDeployments); + tethysControl.sendStateUpdate(new TethysState(TethysState.StateType.NEWPAMGUARDSELECTION)); + return true; + } + + /** + * Get a list of Tethys deployment docs. Note that this + * doesn't update the list, but uses the one currently in memory + * so call updateTethysDeployments() first if necessary. + * @return list of (wrapped) nilus Deployment objects. + */ + public ArrayList getProjectDeployments() { + if (projectDeployments == null) { + updateProjectDeployments(); + } + return projectDeployments; + } + +// /** +// * Get an overview of all the deployments. +// * @return +// */ +// public DeploymentOverview createPamguardOverview() { +// // first find an acquisition module. +// PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null); +// if (!(aModule instanceof AcquisitionControl)) { +// // will return if it's null. Impossible for it to be the wrong type. +// // but it's good practice to check anyway before casting. +// return null; +// } +// // cast it to the right type. +// AcquisitionControl daqControl = (AcquisitionControl) aModule; +// AcquisitionParameters daqParams = daqControl.getAcquisitionParameters(); +// /** +// * The daqParams class has most of what we need about the set up in terms of sample rate, +// * number of channels, instrument type, ADC input range (part of calibration), etc. +// * It also has a hydrophone list, which maps the input channel numbers to the hydrophon numbers. +// * Realistically, this list is always 0,1,2,etc or it goes horribly wrong ! +// */ +// // so write functions here to get information from the daqParams. +//// System.out.printf("Sample regime: %s input with rate %3.1fHz, %d channels, gain %3.1fdB, ADCp-p %3.1fV\n", daqParams.getDaqSystemType(), +//// daqParams.getSampleRate(), daqParams.getNChannels(), daqParams.preamplifier.getGain(), daqParams.voltsPeak2Peak); +// /** +// * then there is the actual sampling. This is a bit harder to find. I thought it would be in the data map +// * but the datamap is a simple count of what's in the databasase which is not quite what we want. +// * we're going to have to query the database to get more detailed informatoin I think. +// * I'll do that here for now, but we may want to move this when we better organise the code. +// * It also seems that there are 'bad' dates in the database when it starts new files, which are the date +// * data were analysed at. So we really need to check the start and stop records only. +// */ +// PamDataBlock daqInfoDataBlock = daqControl.getAcquisitionProcess().getDaqStatusDataBlock(); +// // just load everything. Probably OK for the acqusition, but will bring down +// daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null); +// ArrayList allStatusData = daqInfoDataBlock.getDataCopy(); +// /** +// * Due to seird file overlaps we need to resort this by id if we can. +// * +// */ +// Collections.sort(allStatusData, new Comparator() { +// +// @Override +// public int compare(DaqStatusDataUnit o1, DaqStatusDataUnit o2) { +// if (o1.getDatabaseIndex() == 0) { +// return (int) (o1.getTimeMilliseconds()-o2.getTimeMilliseconds()); +// } +// return o1.getDatabaseIndex()-o2.getDatabaseIndex(); +// } +// }); +// +// ArrayList tempPeriods = null; +// +// if (allStatusData == null || allStatusData.size() == 0) { +// System.out.println("Data appear to have no logged recording periods. Try to extract from raw audio ..."); +// tempPeriods = extractTimesFromFiles(daqControl); +// } +// else { +// tempPeriods = extractTimesFromStatus(allStatusData); +// } +// if (tempPeriods == null || tempPeriods.size() == 0) { +// System.out.println("Data appear to have no logged recording periods available either from the database or the raw recordings."); +// tempPeriods = extractTimesFromOutputMaps(); +// } +// if (tempPeriods == null || tempPeriods.size() == 0) { +// System.out.println("Data appear to have no logged recording periods available either from the database or the raw recordings."); +// return null; +// } +// +// int nPeriods = tempPeriods.size(); +//// int i = 0; +//// for (RecordingPeriod aP : tempPeriods) { +//// System.out.printf("Pre merge %d : %s to %s\n", i++, PamCalendar.formatDBDateTime(aP.getRecordStart()), +//// PamCalendar.formatDBDateTime(aP.getRecordStop())); +//// } +// // now go through those and merge into longer periods where there is no gap between files. +// ListIterator iterator = tempPeriods.listIterator(); +// RecordingPeriod prevPeriod = null; +// while (iterator.hasNext()) { +// RecordingPeriod nextPeriod = iterator.next(); +// long nextDur = nextPeriod.getRecordStop()-nextPeriod.getRecordStart(); +// if (nextDur == 0) { +// continue; +// } +// if (prevPeriod != null) { +// long gap = nextPeriod.getRecordStart() - prevPeriod.getRecordStop(); +// long prevDur = prevPeriod.getRecordStop()-prevPeriod.getRecordStart(); +// if (gap < exportOptions.maxGapSeconds*1000) { +// // ignoring up to 3s gap or a sample error < 2%.Dunno if this is sensible or not. +// prevPeriod.setRecordStop(nextPeriod.getRecordStop()); +// iterator.remove(); +// nextPeriod = prevPeriod; +// } +// } +// prevPeriod = nextPeriod; +// } +// // now remove ones which are too short even after merging. +// iterator = tempPeriods.listIterator(); +// while (iterator.hasNext()) { +// RecordingPeriod nextPeriod = iterator.next(); +// long duration = nextPeriod.getDuration(); +// if (duration < exportOptions.minLengthSeconds*1000L) { +// iterator.remove(); +// } +// } +//// i = 0; +//// for (RecordingPeriod aP : tempPeriods) { +//// System.out.printf("Post merge %d : %s to %s\n", i++, PamCalendar.formatDBDateTime(aP.getRecordStart()), +//// PamCalendar.formatDBDateTime(aP.getRecordStop())); +//// } +//// System.out.printf("Data have %d distinct files, but only %d distinct recording periods\n", nPeriods, tempPeriods.size()); +// DutyCycleInfo dutyCycleinfo = assessDutyCycle(tempPeriods); +// // if it's duty cycles, then we only want a single entry. +// ArrayList deploymentPeriods; +// if (dutyCycleinfo.isDutyCycled == false) { +// deploymentPeriods = tempPeriods; +// } +// else { +// deploymentPeriods = new ArrayList<>(); +// deploymentPeriods.add(new RecordingPeriod(tempPeriods.get(0).getRecordStart(), tempPeriods.get(tempPeriods.size()-1).getRecordStop())); +// } +// /* +// * do another sort of the deploymentPeriods. The start stops were in the order they went into the +// * database in the hope that pairs were the right way round. Now check all data are/ +// */ +// Collections.sort(deploymentPeriods, new Comparator() { +// @Override +// public int compare(RecordingPeriod o1, RecordingPeriod o2) { +// return (int) (o1.getRecordStart()-o2.getRecordStart()); +// } +// }); +// +// DeploymentOverview deploymentOverview = new DeploymentOverview(dutyCycleinfo, deploymentPeriods); +// matchPamguard2Tethys(deploymentOverview, projectDeployments); +// this.deploymentOverview = deploymentOverview; +// return deploymentOverview; +// // find the number of times it started and stopped .... +//// System.out.printf("Input map of sound data indicates data from %s to %s with %d starts and %d stops over %d files\n", +//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), nStart, nStop, nFile+1); +// // now work out where there are genuine gaps and make up a revised list of recording periods. +// +// +// } + + public void showOptions(Window parent) { + if (parent == null) { + parent = tethysControl.getGuiFrame(); + } + DeploymentExportOpts newOpts = RecordingGapDialog.showDiloag(parent, deploymentExportOptions); + if (newOpts != null) { + deploymentExportOptions = newOpts; + createPamguardOverview(); + } + } + + public void createPamguardOverview() { + deploymentOverview = effortFunctions.makeRecordingOverview(); + updateProjectDeployments(); + matchPamguard2Tethys(deploymentOverview, projectDeployments); + } + + /** + * Export button pressed on GUI. Run wizard.... + */ + public void exportDeployments() { + Deployment deployment = MetaDataContol.getMetaDataControl().getMetaData().getDeployment(); + DeploymentExportOpts exportOptions = DeploymentWizard.showWizard(getTethysControl().getGuiFrame(), tethysControl, deployment, this.deploymentExportOptions); + if (exportOptions != null) { + this.deploymentExportOptions = exportOptions; + deploymentOverview = getDeploymentOverview(); + ArrayList allPeriods = deploymentOverview.getRecordingPeriods(); + exportDeployments(allPeriods); + } + } + + /** + * Export deployments docs. Playing with a couple of different ways of doing this. + * @param selectedDeployments + */ + public void exportDeployments(ArrayList selectedDeployments) { + if (deploymentExportOptions.separateDeployments) { + exportSeparateDeployments(selectedDeployments); + } + else { + exportOneDeploymnet(selectedDeployments); + } + } + + /** + * Make one big deployment document with all the recording periods in it. + */ + private void exportOneDeploymnet(ArrayList selectedDeployments) { + // do the lot, whatever ... + selectedDeployments = getDeploymentOverview().getRecordingPeriods(); + int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId(); + RecordingPeriod onePeriod = new RecordingPeriod(selectedDeployments.get(0).getRecordStart(), + selectedDeployments.get(selectedDeployments.size()-1).getRecordStop()); + TethysExportParams exportParams = tethysControl.getTethysExportParams(); + String id = String.format("%s_%s", exportParams.getDatasetName(), "all"); + Deployment deployment = createDeploymentDocument(freeId, onePeriod, id); + // fill in a few things from here + Deployment globalMeta = getTethysControl().getGlobalDeplopymentData(); + deployment.setCruise(globalMeta.getCruise()); + deployment.setSite(globalMeta.getSite()); + if (selectedDeployments.size() > 1) { + // now need to remove the + SamplingDetails samplingDetails = deployment.getSamplingDetails(); + samplingDetails.getChannel().clear(); + for (int i = 0; i < selectedDeployments.size(); i++) { + addSamplingDetails(deployment, selectedDeployments.get(i)); + } + } + DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect(); + PDeployment exDeploymnet = onePeriod.getMatchedTethysDeployment(); + try { + if (exDeploymnet != null) { + deployment.setId(exDeploymnet.deployment.getId()); + dbxmlConnect.updateDocument(deployment); + } + else { + dbxmlConnect.postAndLog(deployment); + } + } + catch (TethysException e) { + getTethysControl().showException(e); + } + getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER, Collection.Deployments)); + } + + /** + * Make a separate deployment document for every recording period. + */ + private void exportSeparateDeployments(ArrayList selectedDeployments) { + + int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId(); + // fill in a few things from here + Deployment globalMeta = getTethysControl().getGlobalDeplopymentData(); + TethysExportParams exportParams = tethysControl.getTethysExportParams(); + for (int i = 0; i < selectedDeployments.size(); i++) { + RecordingPeriod recordPeriod = selectedDeployments.get(i); + PDeployment exDeploymnet = recordPeriod.getMatchedTethysDeployment(); + Deployment deployment = null; + String id = String.format("%s_%d", exportParams.getDatasetName(), i); + if (exDeploymnet != null) { + deployment = createDeploymentDocument(freeId, recordPeriod, id); + deployment.setId(exDeploymnet.deployment.getId()); + } + if (deployment == null) { + deployment = createDeploymentDocument(freeId++, recordPeriod, id); + } + deployment.setCruise(globalMeta.getCruise()); + deployment.setSite(globalMeta.getSite()); + // also need to sort out track data here, etc. + DBXMLConnect dbxmlConnect = getTethysControl().getDbxmlConnect(); + try { + if (exDeploymnet != null) { + dbxmlConnect.updateDocument(deployment); + } + else { + dbxmlConnect.postAndLog(deployment); + } + } + catch (TethysException e) { + getTethysControl().showException(e); + } + } + getTethysControl().sendStateUpdate(new TethysState(StateType.UPDATESERVER, Collection.Deployments)); + } + + + + public DeploymentOverview getDeploymentOverview() { + return deploymentOverview; + } + + /** + * Match what we think the PAMGuard deployment times are with Tethys Deployments read back + * from the database. + * @param deploymentOverview + * @param deployments + */ + private void matchPamguard2Tethys(DeploymentOverview deploymentOverview, ArrayList deployments) { + if (deployments == null || deploymentOverview == null) { + return; + } + ArrayList recordingPeriods = deploymentOverview.getRecordingPeriods(); + for (RecordingPeriod aPeriod : recordingPeriods) { + PDeployment closestDeployment = findClosestDeployment(aPeriod, deployments); + aPeriod.setMatchedTethysDeployment(closestDeployment); + if (closestDeployment != null) { + closestDeployment.setMatchedPAMGaurdPeriod(aPeriod); + } + } + } + + /** + * find the Tethys deployment that most closely matches the PAMGuard recording period. + * @param aPeriod + * @param deployments + * @return + */ + private PDeployment findClosestDeployment(RecordingPeriod aPeriod, ArrayList deployments) { + double overlap = -1; + PDeployment bestDeployment = null; + for (PDeployment aDeployment : deployments) { + double newOverlap = getDeploymentOverlap(aDeployment, aPeriod); + if (newOverlap > overlap) { + bestDeployment = aDeployment; + overlap = newOverlap; + } + } + return bestDeployment; + } + + /** + * Get the overlap in mills between a nilus Deployment and a PAMGuard recording period + * @param aDeployment nilus Deployment from Tethys + * @param aPeriod PAMGuard recording period + * @return overlap in milliseconds + */ + public long getDeploymentOverlap(PDeployment aDeployment, RecordingPeriod aPeriod) { + long start = aPeriod.getRecordStart(); // recording period. + long stop = aPeriod.getRecordStop(); + Long depStart = aDeployment.getAudioStart(); + Long depStop = aDeployment.getAudioEnd(); + if (depStart == null || depStop == null) { + return -1; + } + long overlap = (Math.min(stop, depStop)-Math.max(start, depStart)); + return overlap; + } + + + + + /** + * Get a list of Tethys Deployment docs that match the current PAMGuard data. Watch for repeats + * if a single deployment doc covers many perdiods. + * @return + */ + public ArrayList getMatchedDeployments() { + ArrayList matched = new ArrayList<>(); + if (deploymentOverview == null) { + return matched; + } + for (RecordingPeriod period : deploymentOverview.getRecordingPeriods()) { + PDeployment deployment = period.getMatchedTethysDeployment(); + if (deployment != null) { + if (matched.contains(deployment) == false) { + matched.add(period.getMatchedTethysDeployment()); + } + } + } + return matched; + } + + /** + * Get a list of instruments from the current project deployments. + * This may be a shorter list than the list of deployments. + * @return + */ + public ArrayList getProjectInstruments() { + if (projectDeployments == null) { + return null; + } + ArrayList instruments = new ArrayList<>(); + for (PDeployment aDepl : projectDeployments) { + Instrument intr = aDepl.deployment.getInstrument(); + if (intr == null) { + continue; + } + PInstrument pInstr = new PInstrument(intr.getType(), intr.getInstrumentId()); + if (instruments.contains(pInstr) == false) { + instruments.add(pInstr); + } + } + return instruments; + } + //in each channel +// public ArrayList getDeployments() { +// +// DeploymentOverview recordingOverview = this.deploymentOverview; +// +// // first find an acquisition module. +// PamControlledUnit aModule = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null); +// if (!(aModule instanceof AcquisitionControl)) { +// // will return if it's null. Impossible for it to be the wrong type. +// // but it's good practice to check anyway before casting. +// return null; +// } +// // cast it to the right type. +// AcquisitionControl daqControl = (AcquisitionControl) aModule; +// AcquisitionParameters daqParams = daqControl.getAcquisitionParameters(); +// /** +// * The daqParams class has most of what we need about the set up in terms of sample rate, +// * number of channels, instrument type, ADC input range (part of calibration), etc. +// * It also has a hydrophone list, which maps the input channel numbers to the hydrophon numbers. +// * Realistically, this list is always 0,1,2,etc or it goes horribly wrong ! +// */ +// // so write functions here to get information from the daqParams. +//// System.out.printf("Sample regime: %s input with rate %3.1fHz, %d channels, gain %3.1fdB, ADCp-p %3.1fV\n", daqParams.getDaqSystemType(), +//// daqParams.getSampleRate(), daqParams.getNChannels(), daqParams.preamplifier.getGain(), daqParams.voltsPeak2Peak); +// /** +// * then there is the actual sampling. This is a bit harder to find. I thought it would be in the data map +// * but the datamap is a simple count of what's in the databasase which is not quite what we want. +// * we're going to have to query the database to get more detailed informatoin I think. +// * I'll do that here for now, but we may want to move this when we better organise the code. +// * It also seems that there are 'bad' dates in the database when it starts new files, which are the date +// * data were analysed at. So we really need to check the start and stop records only. +// */ +// PamDataBlock daqInfoDataBlock = daqControl.getAcquisitionProcess().getDaqStatusDataBlock(); +// // just load everything. Probably OK for the acqusition, but will bring down +// daqInfoDataBlock.loadViewerData(0, Long.MAX_VALUE, null); +// ArrayList allStatusData = daqInfoDataBlock.getDataCopy(); +// long dataStart = Long.MAX_VALUE; +// long dataEnd = Long.MIN_VALUE; +// if (allStatusData != null && allStatusData.size() > 0) { +// // find the number of times it started and stopped .... +// int nStart = 0, nStop = 0, nFile=0; +// for (DaqStatusDataUnit daqStatus : allStatusData) { +// switch (daqStatus.getStatus()) { +// case "Start": +// nStart++; +// dataStart = Math.min(dataStart, daqStatus.getTimeMilliseconds()); +// break; +// case "Stop": +// nStop++; +// dataEnd = Math.max(dataEnd, daqStatus.getEndTimeInMilliseconds()); +// break; +// case "NextFile": +// nFile++; +// break; +// } +// } +// +//// System.out.printf("Input map of sound data indicates data from %s to %s with %d starts and %d stops over %d files\n", +//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), nStart, nStop, nFile+1); +// +// } +// +//// // and we find the datamap within that ... +//// OfflineDataMap daqMap = daqInfoDataBlock.getOfflineDataMap(DBControlUnit.findDatabaseControl()); +//// if (daqMap != null) { +//// // iterate through it. +//// long dataStart = daqMap.getFirstDataTime(); +//// long dataEnd = daqMap.getLastDataTime(); +//// List mapPoints = daqMap.getMapPoints(); +//// System.out.printf("Input map of sound data indicates data from %s to %s with %d individual files\n", +//// PamCalendar.formatDateTime(dataStart), PamCalendar.formatDateTime(dataEnd), mapPoints.size()); +//// /* +//// * clearly in the first database I've been looking at of Tinas data, this is NOT getting sensible start and +//// * end times. Print them out to see what's going on. +//// */ +////// for () +//// } +// DeploymentRecoveryPair pair = new DeploymentRecoveryPair(); +// DeploymentRecoveryDetails deployment = new DeploymentRecoveryDetails(); +// DeploymentRecoveryDetails recovery = new DeploymentRecoveryDetails(); +// pair.deploymentDetails = deployment; +// pair.recoveryDetails = recovery; +// +// deployment.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart)); +// deployment.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataStart)); +// recovery.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd)); +// recovery.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(dataEnd)); +// +// ArrayList drPairs = new ArrayList<>(); +// drPairs.add(pair); +// return drPairs; +// +// } + + /** + * Get the first free deploymendId. This will get appended to + * the ProjectName to make and id for each Deployment document + * @return + */ + public int getFirstFreeDeploymentId() { + /** + * This is an integer used for the DeploymentId. Note that the String Id (currentl9) is just the Project name + * appended with this number. + */ + int firstFree = 0; + if (projectDeployments != null) { + for (PDeployment dep : projectDeployments) { + firstFree = Math.max(firstFree, dep.deployment.getDeploymentId()+1); + } + } + return firstFree; + } + + public Deployment createDeploymentDocument(int i, RecordingPeriod recordingPeriod, String deploymentId) { + Deployment deployment = new Deployment(); + try { + nilus.Helper.createRequiredElements(deployment); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + PamguardMetaData pamguardMetaData = MetaDataContol.getMetaDataControl().getMetaData(); + Deployment templateDeployment = pamguardMetaData.getDeployment(); + +// Deployment globalDeplData = tethysControl.getGlobalDeplopymentData(); + deployment.setId(deploymentId); + deployment.setDeploymentId(i); + + DeploymentRecoveryDetails deploymentDetails = deployment.getDeploymentDetails(); + if (deploymentDetails == null) { + deploymentDetails = new DeploymentRecoveryDetails(); + } + DeploymentRecoveryDetails recoveryDetails = deployment.getRecoveryDetails(); + if (recoveryDetails == null) { + recoveryDetails = new DeploymentRecoveryDetails(); + } + + deploymentDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart())); + recoveryDetails.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop())); + // handle situation where deployment and recovery times are not the same as the audio times. + if (pamguardMetaData.useAudioForDeploymentTimes == false) { + if (templateDeployment.getDeploymentDetails().getAudioTimeStamp() != null) { + deploymentDetails.setTimeStamp(templateDeployment.getDeploymentDetails().getAudioTimeStamp()); + } + if (templateDeployment.getRecoveryDetails().getAudioTimeStamp() != null) { + recoveryDetails.setTimeStamp(templateDeployment.getRecoveryDetails().getAudioTimeStamp()); + } + } + + deploymentDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStart())); + recoveryDetails.setAudioTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recordingPeriod.getRecordStop())); + + deployment.setDeploymentDetails(deploymentDetails); + deployment.setRecoveryDetails(recoveryDetails); + + getProjectData(deployment); + + TethysLocationFuncs.getTrackAndPositionData(deployment); + + getTrackDetails(deployment); + + /** + * Get some of the meta data from the centralised source. + */ + MetadataInfo metaData = templateDeployment.getMetadataInfo(); + metaData.setDate(TethysTimeFuncs.xmlGregCalFromMillis(System.currentTimeMillis())); + metaData.setUpdateFrequency("as-needed"); + deployment.setMetadataInfo(metaData); + + deployment.setDescription(templateDeployment.getDescription()); +// DescriptionType description = deployment.getDescription(); +// if (description == null ) { +// description = new DescriptionType(); +// deployment.setDescription(description); +// description.setAbstract("No abstract"); +// description.setMethod("no methods"); +// description.setObjectives("No objectives"); +// } +// description.set + + addSamplingDetails(deployment, recordingPeriod); + + getSensorDetails(deployment); + + getSensors(deployment); + + /** + * Stuff that may need to be put into the UI: + * Audio: can easily get current loc of raw and binary data, but may need to override these. I think + * this may be for the export UI ? + * Tracks: trackline information. General problem in PAMGUard. + */ + getDataDetails(deployment); + + + return deployment; + } + + /** + * Add the track to the deployment, if there is one (i.e. not for + * a fixed sensor). + * @param deployment + */ + private void getTrackDetails(Deployment deployment) { + TrackInformation trackInfo = getTrackInformation(); + if (trackInfo.haveGPSTrack() == false) { + return; + } + GPSDataBlock gpsDataBlock = (GPSDataBlock) trackInfo.getGpsDataMap().getParentDataBlock(); + if (gpsDataBlock == null) { + return; + } + /* + * should have some track information. Do a load from the + * database for the whole deployment. this may be the entire GPS record, but + * we should be able to cope with that. + */ + long trackStart = TethysTimeFuncs.millisFromGregorianXML(deployment.getDeploymentDetails().getTimeStamp()); + long trackEnd = TethysTimeFuncs.millisFromGregorianXML(deployment.getRecoveryDetails().getTimeStamp()); + long dataWin =(long) (Math.max(1./trackInfo.getGPSDataRate(), deploymentExportOptions.trackPointInterval)); + + // get the tracks object. + Tracks tracks = deployment.getData().getTracks(); + if (tracks == null) { + tracks = new Tracks(); + deployment.getData().setTracks(tracks); + } + List trackList = tracks.getTrack(); // lists are usually there. + + Track aTrack = new Track(); + trackList.add(aTrack); + List points = aTrack.getPoint(); + + gpsDataBlock.loadViewerData(trackStart-dataWin, trackEnd+dataWin, null); + long lastPointTime = 0; + ListIterator it = gpsDataBlock.getListIterator(0); + while (it.hasNext()) { + GpsDataUnit gpsDataUnit = it.next(); + if (gpsDataUnit.getTimeMilliseconds()-lastPointTime < deploymentExportOptions.trackPointInterval*1000) { + continue; + } + GpsData gpsData = gpsDataUnit.getGpsData(); + Point gpsPoint = new Point(); + gpsPoint.setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(gpsDataUnit.getTimeMilliseconds())); + gpsPoint.setLatitude(gpsData.getLatitude()); + gpsPoint.setLongitude(PamUtils.constrainedAngle(gpsData.getLongitude())); + BearingDegN bdn = gpsPoint.getBearingDegN(); + if (bdn == null) { + bdn = new BearingDegN(); + gpsPoint.setBearingDegN(bdn); + } + bdn.setValue(AutoTethysProvider.roundDecimalPlaces(PamUtils.constrainedAngle(gpsData.getHeading()),1)); + gpsPoint.setSpeedKn(AutoTethysProvider.roundDecimalPlaces(gpsData.getSpeed(),2)); + + points.add(gpsPoint); + lastPointTime = gpsDataUnit.getTimeMilliseconds(); + } + } + + public String getBinaryDataURI() { + BinaryStore binStore = BinaryStore.findBinaryStoreControl(); + if (binStore != null) { + return binStore.getBinaryStoreSettings().getStoreLocation(); + } + return null; + } + + public String getDatabaseURI() { + DBControlUnit databaseControl = DBControlUnit.findDatabaseControl(); + if (databaseControl != null) { + return databaseControl.getLongDatabaseName(); + } + return null; + } + + public String getRawDataURI() { + try { + PamControlledUnit daq = PamController.getInstance().findControlledUnit(AcquisitionControl.class, null); + if (daq instanceof AcquisitionControl) { + AcquisitionControl daqCtrl = (AcquisitionControl) daq; + DaqSystem system = daqCtrl.findDaqSystem(null);// getAcquisitionProcess().getRunningSystem(); + if (system instanceof FolderInputSystem) { + FolderInputSystem fip = (FolderInputSystem) system; + return fip.getFolderInputParameters().recentFiles.get(0); + } + } + } + catch (Exception e) { + } + return "unknown"; + } + + private void getDataDetails(Deployment deployment) { + Data data = deployment.getData(); + if (data == null) { + data = new Data(); + deployment.setData(data); + } + nilus.Deployment.Data.Audio audio = data.getAudio(); + if (audio == null) { + audio = new nilus.Deployment.Data.Audio(); + data.setAudio(audio); + } + audio.setURI(getRawDataURI()); + String processed = "Database:"+getDatabaseURI(); + String binary = getBinaryDataURI(); + if (binary != null) { + binary += ";Binary:"+binary; + } + audio.setProcessed(processed); + + } + + /** + * Get sensor information. The Soundtrap CTD will count as a sensor. + * Modules that are sensors will have to implement a PAMSensor interface + * @param deployment + */ + private void getSensors(Deployment deployment) { + ArrayList sensorModules = PamController.getInstance().findControlledUnits(PamSensor.class, true); + if (sensorModules == null || sensorModules.size() == 0) { + return; + } + Sensors sensors = deployment.getSensors(); + if (sensors == null) { + sensors = new Sensors(); + deployment.setSensors(sensors); + } + List sensorList = sensors.getSensor(); + for (PamControlledUnit aUnit : sensorModules) { + PamSensor pamSensor = (PamSensor) aUnit; + UnknownSensor nilusSensor = new UnknownSensor(); + try { + Helper.createRequiredElements(nilusSensor); + } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } +// nilusSensor.setName(pamSensor.getUnitName()); + nilusSensor.setType(pamSensor.getUnitType()); + nilusSensor.setNumber(BigInteger.ZERO); + nilusSensor.setDescription(pamSensor.getSensorDescription()); + nilusSensor.setSensorId(pamSensor.getUnitType()); + + sensorList.add(nilusSensor); + } + } + + /** + * Add project Metadata to a Deploymnet document. This is currently being + * made available in the MetaDataControl module which should be added to PAMGuard + * as well as the Tethys output module. + * @param deployment + */ + private boolean getProjectData(Deployment deployment) { +// PamControlledUnit aUnit = PamController.getInstance().findControlledUnit(MetaDataContol.class, null); +// if (aUnit instanceof MetaDataContol == false || true) { +// deployment.setProject("thisIsAProject"); +// deployment.setPlatform("Yay a platform"); +// Instrument instrument = new Instrument(); +// instrument.setType("machiney"); +// instrument.setInstrumentId("12345555"); +// deployment.setInstrument(instrument); +// return false; +// } +// +// MetaDataContol metaControl = (MetaDataContol) aUnit; + PamguardMetaData metaData = MetaDataContol.getMetaDataControl().getMetaData(); + Deployment deploymentData = tethysControl.getGlobalDeplopymentData(); + deployment.setProject(deploymentData.getProject()); + deployment.setDeploymentAlias(deploymentData.getDeploymentAlias()); + deployment.setSite(deploymentData.getSite()); + deployment.setCruise(deploymentData.getCruise()); + deployment.setPlatform(getPlatform()); + deployment.setRegion(deploymentData.getRegion()); + Instrument instrument = new Instrument(); + instrument.setType(getInstrumentType()); + instrument.setInstrumentId(getInstrumentId()); + // get the geometry type from the array manager. + String geomType = getGeometryType(); + instrument.setGeometryType(geomType); + deployment.setInstrument(instrument); + + // overwrite the default deployment and recovery times if there is non null data + XMLGregorianCalendar depTime = deploymentData.getDeploymentDetails().getTimeStamp(); + if (depTime != null) { + deployment.getDeploymentDetails().setTimeStamp(depTime); + } + if (deploymentData.getRecoveryDetails() != null) { + XMLGregorianCalendar recMillis = deploymentData.getRecoveryDetails().getTimeStamp(); + if (recMillis != null) { + deployment.getRecoveryDetails().setTimeStamp(recMillis); + } + double recLat = deploymentData.getRecoveryDetails().getLatitude(); + double recLong = deploymentData.getRecoveryDetails().getLongitude(); + if (recLat != 0 & recLong != 0.) { + deployment.getRecoveryDetails().setLatitude(recLat); + deployment.getRecoveryDetails().setLongitude(PamUtils.constrainedAngle(recLong)); + } + } + + return true; + } + + /** + * Instrument identifier, e.g. serial number + * @return + */ + private String getInstrumentId() { + return ArrayManager.getArrayManager().getCurrentArray().getInstrumentId(); + } + + /** + * Test to see if it's possible to export Deployment documents. This is basically a test of + * various metadata fields that are required, such as instrument id's. + * @return null if OK, or a string describing the first encountered error + */ + public String canExportDeployments() { + + Deployment globalDeplData = tethysControl.getGlobalDeplopymentData(); + if (globalDeplData.getProject() == null) { + return "You must set a project name"; + } + + PInstrument arrayInstrument = getCurrentArrayInstrument(); + if (arrayInstrument == null) { + return "No 'Instrument' set. Goto array manager"; + } + return null; + } + + /** + * Get the Instrument info for the current array. + * @return + */ + public PInstrument getCurrentArrayInstrument() { + PamArray currentArray = ArrayManager.getArrayManager().getCurrentArray(); + String currType = currentArray.getInstrumentType(); + String currId = currentArray.getInstrumentId(); + PInstrument currentInstrument = null; + if (currType != null || currId != null) { + currentInstrument = new PInstrument(currType, currId); + } + return currentInstrument; + } + + /** + * On what platform is the instrument deployed? (e.g. mooring, tag) + * @return + */ + private String getPlatform() { + return getGeometryType(); + } + /** + * Instrument type, e.g. HARP, EAR, Popup, DMON, Rock Hopper, etc. + * @return + */ + private String getInstrumentType() { + return ArrayManager.getArrayManager().getCurrentArray().getInstrumentType(); + } + + /** + * Get a geometry type string for Tethys based on information in the array manager. + * @return + */ + private String getGeometryType() { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + int nStreamer = array.getStreamerCount(); + for (int i = 0; i < nStreamer; i++) { + Streamer streamer = array.getStreamer(i); + HydrophoneLocator locator = streamer.getHydrophoneLocator(); + if (locator == null) { + continue; + } + if (locator instanceof ThreadingHydrophoneLocator) { + return "cabled"; + } + else { + return "rigid"; + } + } + return "unknown"; + } + + private boolean getSensorDetails(Deployment deployment) { + PamArray array = ArrayManager.getArrayManager().getCurrentArray(); + Sensors sensors = new Sensors(); + List