mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-21 22:52:22 +00:00
Merge branch 'main' into restart
This commit is contained in:
commit
5cdf408f84
@ -6,9 +6,8 @@
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
|
70
.gitignore
vendored
70
.gitignore
vendored
@ -41,3 +41,73 @@ settings.xml
|
||||
.classpath
|
||||
.classpath
|
||||
.classpath
|
||||
.metadata/version.ini
|
||||
.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
|
||||
.metadata/.plugins/org.eclipse.ui.intro/introstate
|
||||
.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml
|
||||
.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup
|
||||
.metadata/.plugins/org.eclipse.m2e.logback/logback.2.1.100.20230106-1511.xml
|
||||
.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser
|
||||
.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
|
||||
.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
|
||||
.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
|
||||
.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat
|
||||
.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
|
||||
.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt
|
||||
.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache
|
||||
.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache
|
||||
.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs
|
||||
.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
|
||||
.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
|
||||
.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location
|
||||
.metadata/.lock
|
||||
.metadata/version.ini
|
||||
.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml
|
||||
.metadata/.plugins/org.eclipse.ui.intro/introstate
|
||||
.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml
|
||||
.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup
|
||||
.metadata/.plugins/org.eclipse.m2e.logback/logback.2.1.100.20230106-1511.xml
|
||||
.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser
|
||||
.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml
|
||||
.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml
|
||||
.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
|
||||
.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat
|
||||
.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
|
||||
.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt
|
||||
.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache
|
||||
.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache
|
||||
.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs
|
||||
.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs
|
||||
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs
|
||||
.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index
|
||||
.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version
|
||||
.settings/org.eclipse.jdt.core.prefs
|
||||
.settings/org.eclipse.core.resources.prefs
|
||||
.classpath
|
||||
.classpath
|
||||
.project
|
||||
.classpath
|
||||
.classpath
|
||||
.classpath
|
||||
.classpath
|
||||
.classpath
|
||||
.classpath
|
||||
.settings/org.eclipse.jdt.core.prefs
|
||||
|
0
.metadata/.lock
Normal file
0
.metadata/.lock
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
||||
|
Binary file not shown.
@ -0,0 +1 @@
|
||||
|
BIN
.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
Normal file
BIN
.metadata/.plugins/org.eclipse.core.resources/.root/1.tree
Normal file
Binary file not shown.
Binary file not shown.
@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding=UTF-8
|
||||
version=1
|
@ -0,0 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.ui.formatterprofiles.version=23
|
||||
spelling_locale=en_GB
|
||||
spelling_locale_initialized=true
|
||||
typefilter_migrated_2=true
|
||||
useAnnotationsPrefPage=true
|
||||
useQuickDiffPrefPage=true
|
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.m2e.discovery.pref.projects=
|
@ -0,0 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
platformState=1678968029917
|
||||
quickStart=false
|
||||
tipsAndTricks=true
|
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
showIntro=false
|
@ -0,0 +1,12 @@
|
||||
//org.eclipse.ui.commands/state/org.eclipse.ui.navigator.resources.nested.changeProjectPresentation/org.eclipse.ui.commands.radioState=false
|
||||
PLUGINS_NOT_ACTIVATED_ON_STARTUP=;org.eclipse.m2e.discovery;
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_END=41,41,41
|
||||
org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_START=43,44,45
|
||||
org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_TEXT_COLOR=204,204,204
|
||||
org.eclipse.ui.workbench.ACTIVE_TAB_BG_END=41,41,41
|
||||
org.eclipse.ui.workbench.ACTIVE_TAB_BG_START=43,44,45
|
||||
org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR=221,221,221
|
||||
org.eclipse.ui.workbench.INACTIVE_TAB_BG_END=49,53,56
|
||||
org.eclipse.ui.workbench.INACTIVE_TAB_BG_START=59,64,66
|
||||
org.eclipse.ui.workbench.INACTIVE_TAB_TEXT_COLOR=187,187,187
|
2360
.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
Normal file
2360
.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
Binary file not shown.
BIN
.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache
Normal file
BIN
.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache
Normal file
Binary file not shown.
@ -0,0 +1 @@
|
||||
java
|
BIN
.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
Normal file
BIN
.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache
Normal file
Binary file not shown.
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<typeInfoHistroy/>
|
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<qualifiedTypeNameHistroy/>
|
10
.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
Normal file
10
.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section name="Workbench">
|
||||
<section name="org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart">
|
||||
<item key="group_libraries" value="true"/>
|
||||
<item key="layout" value="2"/>
|
||||
<item key="rootMode" value="1"/>
|
||||
<item key="linkWithEditor" value="false"/>
|
||||
<item key="memento" value="<?xml version="1.0" encoding="UTF-8"?>
<packageExplorer group_libraries="1" layout="2" linkWithEditor="0" rootMode="1" workingSetName="Aggregate for window 1678968099026">
<customFilters userDefinedPatternsEnabled="false">
<xmlDefinedFilters>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.StaticsFilter" isEnabled="false"/>
<child filterId="org.eclipse.buildship.ui.packageexplorer.filter.gradle.buildfolder" isEnabled="true"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonJavaProjectsFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer_patternFilterId_.*" isEnabled="true"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonSharedProjectsFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.SyntheticMembersFilter" isEnabled="true"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.ContainedLibraryFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.internal.ui.PackageExplorer.HideInnerClassFilesFilter" isEnabled="true"/>
<child filterId="org.eclipse.jdt.internal.ui.PackageExplorer.EmptyInnerPackageFilter" isEnabled="true"/>
<child filterId="org.eclipse.m2e.MavenModuleFilter" isEnabled="false"/>
<child filterId="org.eclipse.buildship.ui.packageexplorer.filter.gradle.subProject" isEnabled="true"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.ClosedProjectsFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.DeprecatedMembersFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.EmptyLibraryContainerFilter" isEnabled="true"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.PackageDeclarationFilter" isEnabled="true"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.ImportDeclarationFilter" isEnabled="true"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonJavaElementFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.LibraryFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.CuAndClassFileFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.internal.ui.PackageExplorer.EmptyPackageFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.NonPublicFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.LocalTypesFilter" isEnabled="false"/>
<child filterId="org.eclipse.jdt.ui.PackageExplorer.FieldsFilter" isEnabled="false"/>
</xmlDefinedFilters>
</customFilters>
</packageExplorer>"/>
|
||||
</section>
|
||||
</section>
|
BIN
.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser
Normal file
BIN
.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser
Normal file
Binary file not shown.
@ -0,0 +1,41 @@
|
||||
<configuration scan="true">
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>OFF</level> <!-- change to DEBUG to mimic '-consolelog' behaviour -->
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<File>${org.eclipse.m2e.log.dir}/0.log</File>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
|
||||
<FileNamePattern>${org.eclipse.m2e.log.dir}/%i.log</FileNamePattern>
|
||||
<MinIndex>1</MinIndex>
|
||||
<MaxIndex>10</MaxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<MaxFileSize>10MB</MaxFileSize>
|
||||
</triggeringPolicy>
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="EclipseLog" class="org.eclipse.m2e.logback.appender.EclipseLogAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>WARN</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<appender name="MavenConsoleLog" class="org.eclipse.m2e.logback.appender.MavenConsoleAppender">
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="FILE" />
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="EclipseLog" />
|
||||
<appender-ref ref="MavenConsoleLog" />
|
||||
</root>
|
||||
</configuration>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<setup:Workspace
|
||||
xmi:version="2.0"
|
||||
xmlns:xmi="http://www.omg.org/XMI"
|
||||
xmlns:setup="http://www.eclipse.org/oomph/setup/1.0"
|
||||
name="workspace"/>
|
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section name="Workbench">
|
||||
</section>
|
2
.metadata/.plugins/org.eclipse.ui.intro/introstate
Normal file
2
.metadata/.plugins/org.eclipse.ui.intro/introstate
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<state reopen="false"/>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<workingSetManager>
|
||||
<workingSet editPageId="org.eclipse.jdt.internal.ui.DynamicSourcesWorkingSet" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1678968098501_0" label="Java Main Sources" name="Java Main Sources"/>
|
||||
<workingSet editPageId="org.eclipse.jdt.internal.ui.DynamicSourcesWorkingSet" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1678968098508_1" label="Java Test Sources" name="Java Test Sources"/>
|
||||
<workingSet aggregate="true" factoryID="org.eclipse.ui.internal.WorkingSetFactory" id="1678968099026_2" label="Window Working Set" name="Aggregate for window 1678968099026"/>
|
||||
</workingSetManager>
|
3
.metadata/version.ini
Normal file
3
.metadata/version.ini
Normal file
@ -0,0 +1,3 @@
|
||||
#Thu Mar 16 12:01:36 GMT 2023
|
||||
org.eclipse.core.runtime=2
|
||||
org.eclipse.platform=4.27.0.v20230302-0300
|
2
.project
2
.project
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>PamGuard Main Tethys</name>
|
||||
<name>PAMGuard</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
|
@ -1,4 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/rawDeepLearningClassifer/segmenter/SegmenterProcess.java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
encoding/src=UTF-8
|
||||
|
@ -1,9 +1,9 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.compliance=17
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
@ -13,4 +13,4 @@ org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=11
|
||||
org.eclipse.jdt.core.compiler.source=17
|
||||
|
183
README.html
183
README.html
@ -387,8 +387,11 @@ PamguardBeta_ViewerMode.exe):</p>
|
||||
|
||||
<h1><a name="_LATEST_VERSION_2.02.03"></a><a name="_VERSION_2.02.07_January"></a><a
|
||||
name="_Latest_Version_2.02.10"></a><em><span style='font-size:12.0pt;
|
||||
font-family:"Cambria",serif;font-style:normal'><a
|
||||
href="#_Version_2.02.10_January">Latest Version 2.02.10 January 2024</a></span></em></h1>
|
||||
font-family:"Cambria",serif;font-style:normal'><a href="#_Version_2.02.11_April">Latest
|
||||
Version 2.02.11 April 2024</a></span></em></h1>
|
||||
|
||||
<h1><em><span style='font-size:12.0pt;font-family:"Cambria",serif;font-style:
|
||||
normal'><a href="#_Version_2.02.10_January">Version 2.02.10 January 2024</a></span></em></h1>
|
||||
|
||||
<h1><em><span style='font-size:12.0pt;font-family:"Cambria",serif;font-style:
|
||||
normal'><a href="#_Version_2.02.09_June">Version 2.02.09 June 2023</a></span></em></h1>
|
||||
@ -461,14 +464,47 @@ Version 2.00.10 June 2017</a></span></h1>
|
||||
<h1><a name="_Latest_Version_2.02.03_1"></a><a name="_Latest_Version_2.02.05"></a><a
|
||||
name="_Latest_Version_2.02.06"></a><a name="_Latest_Version_2.02.07"></a><a
|
||||
name="_Latest_Version_2.02.08"></a><a name="_Version_2.02.09_June"></a><a
|
||||
name="_Version_2.02.10_January"></a>Version 2.02.10 January 2024</h1>
|
||||
name="_Version_2.02.10_January"></a><a name="_Version_2.02.11_April"></a>Version
|
||||
2.02.11 April 2024</h1>
|
||||
|
||||
<p class=MsoNormal> </p>
|
||||
|
||||
<h2>New Features</h2>
|
||||
|
||||
<p class=MsoNormal>Click detector: Remembers locations of displays and doesn’t
|
||||
continually reset them. </p>
|
||||
|
||||
<p class=MsoNormal>Help for Matched Click Classifier</p>
|
||||
|
||||
<h2>Bug Fixes</h2>
|
||||
|
||||
<p class=MsoNormal>Linking clicks to offline clicks table. We had a database
|
||||
that had become corrupted so added code to relink offline clicks to their corresponding
|
||||
clicks from binary data. </p>
|
||||
|
||||
<p class=MsoNormal>Drawing non-acoustic data: Data that were not associated
|
||||
with any hydrophones, e.g. visual sightings in Logger forms were not drawing on
|
||||
the map. This fixed and PAMGuard will use the vessels GPS position as
|
||||
reference. </p>
|
||||
|
||||
<p class=MsoNormal>Lookup tables: fix feature which was causing table entries
|
||||
to repeat. </p>
|
||||
|
||||
<p class=MsoNormal>Click Train Detector: Add exception handlers to avoid errors
|
||||
as PAMGuard stops / restarts. </p>
|
||||
|
||||
<p class=MsoNormal>Group Detection starts and ends: Check data integrity
|
||||
function fixed and now inserts correct times of start and ends of events into
|
||||
database. </p>
|
||||
|
||||
<h1>Version 2.02.10 January 2024</h1>
|
||||
|
||||
<h2><span lang=EN-US>New Features</span></h2>
|
||||
|
||||
<p class=MsoNormal><b><span lang=EN-US>Importing modules</span></b><span
|
||||
lang=EN-US> from other configurations: New options from file menu allowing
|
||||
import of specific modules, or module settings from other configurations. E.g.
|
||||
if you had three similar configurations and had set one of them up with a new
|
||||
lang=EN-US> from other configurations: New options from file menu allowing import
|
||||
of specific modules, or module settings from other configurations. E.g. if you
|
||||
had three similar configurations and had set one of them up with a new
|
||||
detector, or got the click classifier settings set up just right in one of
|
||||
those configurations, you can import the additional modules or the click
|
||||
detector settings easily into the other configurations. </span></p>
|
||||
@ -496,9 +532,9 @@ correctly saving updated bearings to the database. Now fixed. </span></p>
|
||||
|
||||
<p class=MsoNormal><b><span lang=EN-US>ROCCA Classifier fixes</span></b></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Allow Rocca to run without classifiers:
|
||||
Fixed bug that threw an error if no classifier files were specified in
|
||||
Rocca Params dialog</span></p>
|
||||
<p class=MsoNormal><span lang=EN-US>Allow Rocca to run without classifiers: Fixed
|
||||
bug that threw an error if no classifier files were specified in Rocca
|
||||
Params dialog</span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Fix memory issue with
|
||||
RoccaContourDataBlocks not being released for garbage collection</span></p>
|
||||
@ -596,9 +632,9 @@ angle offsets applied to static hydrophones in viewer mode. This is now fixed. <
|
||||
<p class=MsoNormal><span lang=EN-US>Click tool bar: Correctly shows event
|
||||
selection options even if no species classification options are in place. </span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Fixed Landmarks: Earlier versions were ‘losing’
|
||||
these every time PAMGuard started or new data were loaded in viewer mode. Now
|
||||
fixed. </span></p>
|
||||
<p class=MsoNormal><span lang=EN-US>Fixed Landmarks: Earlier versions were
|
||||
‘losing’ these every time PAMGuard started or new data were loaded in viewer
|
||||
mode. Now fixed. </span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>ROCCA: Fixed (another) memory leak which
|
||||
caused PAMGuard to crash when processing large data sets with the ROCCA
|
||||
@ -767,8 +803,9 @@ the TF FX display to crash if no data were displayed.</span></p>
|
||||
<p class=MsoNormal><span lang=EN-US>See major release notes for V 2.02.01
|
||||
below. </span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Bug 495: TD FX display throws NullPointerException
|
||||
if user has removed all data units and then moves mouse over display area.</span></p>
|
||||
<p class=MsoNormal><span lang=EN-US>Bug 495: TD FX display throws
|
||||
NullPointerException if user has removed all data units and then moves mouse
|
||||
over display area.</span></p>
|
||||
|
||||
<h1><a name="_Latest_Version_2.02.01"></a><span lang=EN-US>Version 2.02.01
|
||||
October 2021</span></h1>
|
||||
@ -791,11 +828,11 @@ font-family:"Times New Roman",serif'> </span></p>
|
||||
|
||||
<h2>File Format Change</h2>
|
||||
|
||||
<p class=MsoNormal>Changes have been made to the binary file format to support the
|
||||
output of additional noise outputs for certain detectors (See below). Binary
|
||||
files created with this version will not be compatible with earlier versions
|
||||
2.01.### and below. This version will read and may convert earlier format
|
||||
binary files.</p>
|
||||
<p class=MsoNormal>Changes have been made to the binary file format to support
|
||||
the output of additional noise outputs for certain detectors (See below).
|
||||
Binary files created with this version will not be compatible with earlier
|
||||
versions 2.01.### and below. This version will read and may convert earlier
|
||||
format binary files.</p>
|
||||
|
||||
<p class=MsoNormal style='margin-bottom:0cm'><span style='font-size:12.0pt;
|
||||
font-family:"Times New Roman",serif'> </span></p>
|
||||
@ -1181,10 +1218,10 @@ lang=EN-US> </span>Add functionality for bluetooth headsets. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Add user-facing option to adjust the startup delay for the
|
||||
time-correction (Global Time module). This provides a workaround to speed up
|
||||
analysis of thousands of wav files (i.e. by setting startup delay to 0 instead
|
||||
of default value of 2000 ms). </p>
|
||||
lang=EN-US> </span>Add user-facing option to adjust the startup delay for the time-correction
|
||||
(Global Time module). This provides a workaround to speed up analysis of
|
||||
thousands of wav files (i.e. by setting startup delay to 0 instead of default
|
||||
value of 2000 ms). </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
@ -1415,9 +1452,9 @@ be compatible with this version, and vice-versa.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Java 12 is better at handling Windows scaling issues on high-DPI displays.
|
||||
Beyond that, users should not notice much of a difference between this version
|
||||
and previous beta releases.</p>
|
||||
Java 12 is better at handling Windows scaling issues on high-DPI displays. Beyond
|
||||
that, users should not notice much of a difference between this version and
|
||||
previous beta releases.</p>
|
||||
|
||||
<!-- ************************************************************************************************************************** --><!-- ************************************************************************************************************************** -->
|
||||
|
||||
@ -1706,8 +1743,8 @@ with installation and use of this version.</span></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 338. Problem displaying coastlines and bathymetric contours around the
|
||||
dateline (+/- 180 longitude) in the map.</p>
|
||||
</span>Bug 338. Problem displaying coastlines and bathymetric contours around
|
||||
the dateline (+/- 180 longitude) in the map.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -2218,8 +2255,8 @@ UID
|
||||
<p class=MsoNormal><span lang=EN-US>If old data are opened with the PAMGuard
|
||||
viewer they will automatically be converted. For safety, the original binary
|
||||
files will not be overwritten and the new data will be placed in a new folder
|
||||
on your computer with the same path as the old data, but suffixed with ‘_WithUID’,
|
||||
e.g. if your binary data were previously stored in the folder
|
||||
on your computer with the same path as the old data, but suffixed with
|
||||
‘_WithUID’, e.g. if your binary data were previously stored in the folder
|
||||
C:\MySurvey\binarydata the new data will be written to
|
||||
C:\MySurvey\binarydata_WithUID. </span></p>
|
||||
|
||||
@ -2295,8 +2332,8 @@ Hawaii/Temperate Pacific/North Atlantic datasets. This has been corrected.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 320. Pamguard stopped reading Click Detector Event data from database
|
||||
when target motion analysis information was encountered. Corrected.</p>
|
||||
</span>Bug 320. Pamguard stopped reading Click Detector Event data from
|
||||
database when target motion analysis information was encountered. Corrected.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -2578,9 +2615,9 @@ main click detector display. </span></p>
|
||||
|
||||
<p class=MsoNormal><b><span lang=EN-US>Target Motion Analysis</span></b></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>A major piece of work has been undertaken
|
||||
to improve the Target Motion tracking with PAMGuard. Details are available in
|
||||
the online help. Users of the Click Detector will notice the following changes:</span></p>
|
||||
<p class=MsoNormal><span lang=EN-US>A major piece of work has been undertaken to
|
||||
improve the Target Motion tracking with PAMGuard. Details are available in the
|
||||
online help. Users of the Click Detector will notice the following changes:</span></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -2752,8 +2789,8 @@ being imported into the new database. Problem 2 was that indexing of imported
|
||||
click events in the new database was incorrect. Both these issues have now been
|
||||
fixed. </span></p>
|
||||
|
||||
<h1><a name="_Latest_Version_1.15.02"></a><span lang=EN-US>Version 1.15.02 March
|
||||
2016</span></h1>
|
||||
<h1><a name="_Latest_Version_1.15.02"></a><span lang=EN-US>Version 1.15.02
|
||||
March 2016</span></h1>
|
||||
|
||||
<p class=MsoNormal>A number of small bug fixes following release of 1.15.00.</p>
|
||||
|
||||
@ -2905,13 +2942,13 @@ for details. </span></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span><span lang=EN-US>GPS Loading into PAMGuard Viewer. This has been modified
|
||||
so that the rules governing GPS data collection and storage also apply when
|
||||
loading data from the database. For instance, if you've stored all GPS data,
|
||||
you've probably got a record every second in the database which can create
|
||||
memory overflows if you try to load a lot of data in the viewer. You can now
|
||||
tell PAMGuard to only load a data point every n seconds which will reduce the
|
||||
number of points loaded. Useful when making large scale overview maps of a
|
||||
</span><span lang=EN-US>GPS Loading into PAMGuard Viewer. This has been
|
||||
modified so that the rules governing GPS data collection and storage also apply
|
||||
when loading data from the database. For instance, if you've stored all GPS
|
||||
data, you've probably got a record every second in the database which can
|
||||
create memory overflows if you try to load a lot of data in the viewer. You can
|
||||
now tell PAMGuard to only load a data point every n seconds which will reduce
|
||||
the number of points loaded. Useful when making large scale overview maps of a
|
||||
survey. </span></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4.</span><span
|
||||
@ -3018,8 +3055,8 @@ allocation to allow more memory for the database interface. Hopefully Fixed. </p
|
||||
|
||||
<p class=MsoListParagraph style='margin-left:38.25pt;text-indent:-20.25pt'><span
|
||||
lang=EN-AU>9.</span><span lang=EN-AU style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 239. <span lang=EN-AU>Fixed bug in the DIFAR module that was
|
||||
incorrectly preventing cross-fixes for some calls.</span></p>
|
||||
</span>Bug 239. <span lang=EN-AU>Fixed bug in the DIFAR module that was incorrectly
|
||||
preventing cross-fixes for some calls.</span></p>
|
||||
|
||||
<p class=MsoNormal>Details of these bugs can be found at <a
|
||||
href="https://sourceforge.net/p/pamguard/bugs">https://sourceforge.net/p/pamguard/bugs</a></p>
|
||||
@ -3210,8 +3247,9 @@ to read on a time. Fixed</p>
|
||||
|
||||
<p class=MsoNormal><i>Menu Layout</i></p>
|
||||
|
||||
<p class=MsoNormal>The PAMGuard menus have been rearranged into a more intuitive
|
||||
grouping which we believe will help users find functionality more easily. </p>
|
||||
<p class=MsoNormal>The PAMGuard menus have been rearranged into a more
|
||||
intuitive grouping which we believe will help users find functionality more
|
||||
easily. </p>
|
||||
|
||||
<p class=MsoNormal>'Detection' menu has been renamed to 'Settings' since many
|
||||
menu items within this menu were not directly to do with 'Detection'.</p>
|
||||
@ -3302,9 +3340,9 @@ of third octave noise bands. See online help for details. </p>
|
||||
|
||||
<p class=MsoNormal><i>Filtered Noise Measurement</i> (Sound Processing Group)</p>
|
||||
|
||||
<p class=MsoNormal>This module, developed by Douglas Gillespie, measures noise levels
|
||||
in a single frequency band using a variety of filter functions. See online help
|
||||
for details. </p>
|
||||
<p class=MsoNormal>This module, developed by Douglas Gillespie, measures noise
|
||||
levels in a single frequency band using a variety of filter functions. See
|
||||
online help for details. </p>
|
||||
|
||||
<p class=MsoNormal><i>Envelope Tracing</i> (Beta Only, Sound Processing Group)</p>
|
||||
|
||||
@ -3340,10 +3378,11 @@ different. Details are available in the online help. </p>
|
||||
<p class=MsoNormal><i>FLAC File Support</i></p>
|
||||
|
||||
<p class=MsoNormal>Can now read raw audio data direct from FLAC files. <a
|
||||
href="http://en.wikipedia.org/wiki/FLAC">FLAC</a> is a lossless compression algorithm
|
||||
for audio data. Files, or folders of files are accessed in the same way as WAV
|
||||
and AIFF files in the Sound Acquisition module. In a future release we also
|
||||
hope to provide support for writing FLAC files from the sound recorder module. </p>
|
||||
href="http://en.wikipedia.org/wiki/FLAC">FLAC</a> is a lossless compression
|
||||
algorithm for audio data. Files, or folders of files are accessed in the same
|
||||
way as WAV and AIFF files in the Sound Acquisition module. In a future release
|
||||
we also hope to provide support for writing FLAC files from the sound recorder
|
||||
module. </p>
|
||||
|
||||
<p class=MsoNormal><i>Sound Recorder Module</i></p>
|
||||
|
||||
@ -3476,9 +3515,9 @@ to these menus to provide additional information to users. </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:36.0pt'><i>Radar Display</i></p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:36.0pt'>Functionality has been added to
|
||||
the radar display so that bearings can be shown relative to either the vessel
|
||||
or to true North. </p>
|
||||
<p class=MsoNormal style='margin-left:36.0pt'>Functionality has been added to the
|
||||
radar display so that bearings can be shown relative to either the vessel or to
|
||||
true North. </p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:36.0pt'>Better control of data in viewer
|
||||
mode, making is easy to scroll through and view data for short time periods. </p>
|
||||
@ -4116,8 +4155,8 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>This results in a major speed up of data exchange between modules and can
|
||||
lead to a x4 improvement in overall performance. </p>
|
||||
</span>This results in a major speed up of data exchange between modules and
|
||||
can lead to a x4 improvement in overall performance. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -4230,9 +4269,9 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Channel lists in output data streams of Decimator and other modules fixed,
|
||||
so that when channel numbers change, downstream modules configurations get the
|
||||
correct list of available channels. </p>
|
||||
</span>Channel lists in output data streams of Decimator and other modules
|
||||
fixed, so that when channel numbers change, downstream modules configurations
|
||||
get the correct list of available channels. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -4263,11 +4302,11 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>New menu functionality by right clicking on any of the tabs of the main
|
||||
tab control will allow the user to copy the tab contents to the system
|
||||
clipboard from where it can be copied into other programs (e.g. Word,
|
||||
Powerpoint, etc.).Some modules, such as the map, have this implemented in other
|
||||
menus (right click) and also allow printing. </p>
|
||||
</span>New menu functionality by right clicking on any of the tabs of the main tab
|
||||
control will allow the user to copy the tab contents to the system clipboard
|
||||
from where it can be copied into other programs (e.g. Word, Powerpoint,
|
||||
etc.).Some modules, such as the map, have this implemented in other menus
|
||||
(right click) and also allow printing. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -4335,8 +4374,8 @@ online help. </p>
|
||||
|
||||
<p class=MsoNormal><b>PAMGUARD Mixed Mode operation</b></p>
|
||||
|
||||
<p class=MsoNormal>Analyses data from wav or AIF file and synchronises it with
|
||||
GPS data reloaded from a database so that detected sounds may be correctly
|
||||
<p class=MsoNormal>Analyses data from wav or AIF file and synchronises it with GPS
|
||||
data reloaded from a database so that detected sounds may be correctly
|
||||
localised. Multiple display frames - enables PAMGUARD GUI to be split into
|
||||
multiple display windows, displayed on multiple monitors if desired. Enables
|
||||
the operator to simultaneously view the map and the click detector for example,
|
||||
@ -4855,8 +4894,8 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
|
||||
<p class=MsoNormal> </p>
|
||||
|
||||
<p class=MsoNormal><a name="_Toc312065304"></a><a name="_Toc312063949"></a><span
|
||||
class=Heading2Char><span style='font-size:13.0pt'>1.0Beta 22 Jan 2008 - Pamguard
|
||||
starts two releases, core and beta release</span></span>, </p>
|
||||
class=Heading2Char><span style='font-size:13.0pt'>1.0Beta 22 Jan 2008 -
|
||||
Pamguard starts two releases, core and beta release</span></span>, </p>
|
||||
|
||||
<p class=MsoNormal>this is the beta release</p>
|
||||
|
||||
|
@ -3,16 +3,17 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>Pamguard</artifactId>
|
||||
<name>Pamguard Java12+</name>
|
||||
<version>2.02.10b</version>
|
||||
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
|
||||
<name>Pamguard</name>
|
||||
<version>2.02.11d</version>
|
||||
<description>Pamguard using Maven to control dependencies</description>
|
||||
<url>www.pamguard.org</url>
|
||||
<organization>
|
||||
<name>Sea Mammal Research Unit, University of St. Andrews</name>
|
||||
<url>http://www.smru.st-andrews.ac.uk</url>
|
||||
</organization>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<sourceDirectory>${basedir}/src</sourceDirectory>
|
||||
<testSourceDirectory>${basedir}/src/test</testSourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src</directory>
|
||||
@ -54,7 +55,7 @@
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>3.12.1</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.tycho</groupId>
|
||||
@ -63,22 +64,14 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<release>11</release>
|
||||
<release>21</release>
|
||||
<compilerId>jdt</compilerId>
|
||||
<compilerArguments>
|
||||
<properties>.settings/org.eclipse.jdt.core.prefs</properties>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.6</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<release>17</release>
|
||||
</configuration>
|
||||
<version>0.0.8</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
@ -165,11 +158,8 @@
|
||||
<url>https://artifacts.unidata.ucar.edu/repository/unidata-all/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>bedatadriven</id>
|
||||
<name>bedatadriven_renjin</name>
|
||||
<name>bedatadriven public repo</name>
|
||||
<url>https://nexus.bedatadriven.com/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
@ -198,7 +188,7 @@
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<javafx.version>16</javafx.version>
|
||||
<javafx.version>21</javafx.version>
|
||||
<jaxb.runtime.version>2.4.0-b180830.0438</jaxb.runtime.version>
|
||||
<jaxb.xjc.version>2.4.0-b180830.0438</jaxb.xjc.version>
|
||||
<jaxb.api.version>2.4.0-b180830.0359</jaxb.api.version>
|
||||
|
BIN
nullPamguardSettings_20171106_185953.psfx
Normal file
BIN
nullPamguardSettings_20171106_185953.psfx
Normal file
Binary file not shown.
BIN
nullPamguardSettings_20240401_141954.psfx
Normal file
BIN
nullPamguardSettings_20240401_141954.psfx
Normal file
Binary file not shown.
BIN
nullPamguardSettings_20240401_143317.psfx
Normal file
BIN
nullPamguardSettings_20240401_143317.psfx
Normal file
Binary file not shown.
202
pom.xml
202
pom.xml
@ -1,13 +1,12 @@
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>Pamguard</artifactId>
|
||||
<version>2.02.10ad</version>
|
||||
<name>Pamguard Java12+</name>
|
||||
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
|
||||
<version>2.02.11d</version>
|
||||
<name>Pamguard</name>
|
||||
<description>Pamguard using Maven to control dependencies</description>
|
||||
<url>www.pamguard.org</url>
|
||||
<organization>
|
||||
<name>Sea Mammal Research Unit, University of St. Andrews</name>
|
||||
@ -16,17 +15,20 @@
|
||||
|
||||
|
||||
<properties>
|
||||
<javafx.version>16</javafx.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<javafx.version>21</javafx.version>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- Tethys version control -->
|
||||
<jaxb.runtime.version>2.4.0-b180830.0438</jaxb.runtime.version>
|
||||
<jaxb.api.version>2.4.0-b180830.0359</jaxb.api.version>
|
||||
<jaxb.xjc.version>2.4.0-b180830.0438</jaxb.xjc.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<!-- Define where the source and test directories are -->
|
||||
<sourceDirectory>${basedir}/src</sourceDirectory>
|
||||
<testSourceDirectory>${basedir}/src/test</testSourceDirectory> <!-- where the Unit tets are located -->
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src</directory>
|
||||
@ -37,10 +39,9 @@
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
|
||||
<!-- original maven compiler definition - uses the JRE's javac compiler, not the one Eclipse uses
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
@ -54,19 +55,15 @@
|
||||
https://wiki.eclipse.org/JDT/FAQ#Can_I_use_JDT_outside_Eclipse_to_compile_Java_code.3F
|
||||
https://wiki.eclipse.org/Tycho/FAQ#Can_I_use_the_Tycho_compiler_support_in_non-OSGi_projects.2C_too.3F
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<version>3.12.1</version>
|
||||
<configuration>
|
||||
|
||||
<!-- set compiler to use Java version 11 API https://docs.oracle.com/javase/9/tools/javac.htm#JSWOR627 -->
|
||||
<release>11</release>
|
||||
<release>21</release>
|
||||
<compilerId>jdt</compilerId>
|
||||
<compilerArguments>
|
||||
<properties>.settings/org.eclipse.jdt.core.prefs</properties> <!-- make sure to use same params as what Eclipse uses -->
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.eclipse.tycho/tycho-compiler-jdt -->
|
||||
<dependency>
|
||||
@ -75,18 +72,13 @@
|
||||
<version>1.5.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</plugin>
|
||||
|
||||
<!-- Set up javafx properly. -->
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.6</version>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<release>17</release>
|
||||
</configuration>
|
||||
<version>0.0.8</version>
|
||||
</plugin>
|
||||
|
||||
<!-- Maven Shade plugin - for creating the uberjar / fatjar -->
|
||||
@ -136,6 +128,7 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
<!-- The Maven-JDEPS plugin, to analyze necessary JDK dependencies. See
|
||||
this site for details: https://maven.apache.org/plugins/maven-jdeps-plugin/index.html -->
|
||||
<plugin>
|
||||
@ -163,7 +156,6 @@
|
||||
<overWriteIfNewer>true</overWriteIfNewer>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
<!-- this deletes all the dependencies in the local repository and downloads them again.
|
||||
Run a Maven > Update after doing this in order to properly reset the dependencies. Also, you
|
||||
will need to add the 3 jar files (x3, JasioHost and jave) back into the local repository after
|
||||
@ -188,8 +180,9 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
|
||||
</plugins>
|
||||
|
||||
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
|
||||
@ -242,7 +235,6 @@
|
||||
|
||||
<!-- ************************* Extra Repositories ************************************* -->
|
||||
<repositories>
|
||||
|
||||
<!-- Project repo to hold the custom jar files that are not available in Maven. Do
|
||||
this so that we don't have to do the extra step of manually installing jar files in the local repo -->
|
||||
<repository>
|
||||
@ -257,23 +249,6 @@
|
||||
<url>file://${project.basedir}/repo</url>
|
||||
</repository>
|
||||
|
||||
<!-- Repo for Jamie's code -->
|
||||
<!-- IMPORTANT: SOMEHOW THIS REPO INTERFERES WITH THE
|
||||
JAVAFX DEPENDENCIES. Don't understand how, but it
|
||||
does. If Maven is not downloading the JavaFX dependencies
|
||||
and is instead throwing errors, try commenting out this
|
||||
repository. Let Maven download the JavaFX files, and
|
||||
then uncomment this repo again.
|
||||
Same thing seems to be occurring if I try to update the postgresql library. -->
|
||||
<!-- <repository> -->
|
||||
<!-- <snapshots> -->
|
||||
<!-- <enabled>false</enabled> -->
|
||||
<!-- </snapshots> -->
|
||||
<!-- <id>central</id> -->
|
||||
<!-- <name>a0u0ltozdsehx-artifactory-primary-0-releases</name> -->
|
||||
<!-- <url>https://jmachund.jfrog.io/artifactory/jpam2</url> -->
|
||||
<!-- </repository> -->
|
||||
|
||||
<!-- Repo for netCDF -->
|
||||
<repository>
|
||||
<snapshots>
|
||||
@ -296,14 +271,12 @@
|
||||
|
||||
<!-- Repo for Renjin Script Engine -->
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>bedatadriven</id>
|
||||
<name>bedatadriven_renjin</name>
|
||||
<name>bedatadriven public repo</name>
|
||||
<url>https://nexus.bedatadriven.com/content/groups/public/</url>
|
||||
</repository>
|
||||
|
||||
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
@ -328,18 +301,14 @@
|
||||
<dependency>
|
||||
<groupId>io.github.macster110</groupId>
|
||||
<artifactId>jpamutils</artifactId>
|
||||
<version>0.0.56</version>
|
||||
<version>0.0.59</version>
|
||||
</dependency>
|
||||
|
||||
<!--jpam project - Deep learning java library
|
||||
DG has commented this out since there are problems with access to the maven repo
|
||||
on JDJM's Github. For now a jar file is included in the build and we'll go back to
|
||||
Maven when we can ... DG 15 Jan 2022.
|
||||
Repo for jpam code- this used for deep learning [15:17] Jamie MacAulay-->
|
||||
<!--jpam project - Deep learning java library -->
|
||||
<dependency>
|
||||
<groupId>io.github.macster110</groupId>
|
||||
<artifactId>jdl4pam</artifactId>
|
||||
<version>0.0.94</version>
|
||||
<version>0.0.99a</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/gov.nist.math/jama -->
|
||||
@ -401,11 +370,11 @@
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Decorates JavaFX components-->
|
||||
<!-- Decorates JavaFX components with error icons if inputs are incorrect-->
|
||||
<dependency>
|
||||
<groupId>net.synedra</groupId>
|
||||
<artifactId>validatorfx</artifactId>
|
||||
<version>0.4.0</version>
|
||||
<version>0.4.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
|
||||
@ -461,7 +430,7 @@
|
||||
<dependency>
|
||||
<groupId>org.controlsfx</groupId>
|
||||
<artifactId>controlsfx</artifactId>
|
||||
<version>11.0.0</version>
|
||||
<version>11.2.0</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.openjfx</groupId>
|
||||
@ -492,49 +461,52 @@
|
||||
<dependency>
|
||||
<groupId>org.kordamp.ikonli</groupId>
|
||||
<artifactId>ikonli-javafx</artifactId>
|
||||
<version>12.2.0</version>
|
||||
<version>12.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Ikonli FontAwesome5 font pack https://kordamp.org/ikonli/cheat-sheet-fontawesome5.html -->
|
||||
<!--
|
||||
<!-- Icon symbol pack for swing icons . -->
|
||||
<dependency>
|
||||
<groupId>org.kordamp.ikonli</groupId>
|
||||
<artifactId>ikonli-fontawesome5-pack</artifactId>
|
||||
<version>12.2.0</version>
|
||||
<artifactId>ikonli-swing</artifactId>
|
||||
<version>12.3.1</version>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<!-- Ikonli MaterialDesign2 (Latest) font pack https://kordamp.org/ikonli/cheat-sheet-materialdesign2.html -->
|
||||
<dependency>
|
||||
<groupId>org.kordamp.ikonli</groupId>
|
||||
<artifactId>ikonli-materialdesign2-pack</artifactId>
|
||||
<version>12.2.0</version>
|
||||
<version>12.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/net.sf.geographiclib/GeographicLib-Java -->
|
||||
<!-- Ikonli File Icons (Latest) font pack https://kordamp.org/ikonli/cheat-sheet-materialdesign2.html -->
|
||||
<dependency>
|
||||
<groupId>org.kordamp.ikonli</groupId>
|
||||
<artifactId>ikonli-fileicons-pack</artifactId>
|
||||
<version>12.3.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/net.sf.geographiclib/GeographicLib-Java
|
||||
Used in the video range module-->
|
||||
<dependency>
|
||||
<groupId>net.sf.geographiclib</groupId>
|
||||
<artifactId>GeographicLib-Java</artifactId>
|
||||
<version>1.50</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.jogamp.gluegen/gluegen -->
|
||||
<!-- https://mvnrepository.com/artifact/org.jogamp.gluegen/gluegen
|
||||
<dependency>
|
||||
<groupId>org.jogamp.gluegen</groupId>
|
||||
<artifactId>gluegen-rt-main</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/java3d/j3dutils -->
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/java3d/j3dcore -->
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.healthmarketscience.jackcess/jackcess -->
|
||||
<!-- https://mvnrepository.com/artifact/com.healthmarketscience.jackcess/jackcess
|
||||
<dependency>
|
||||
<groupId>com.healthmarketscience.jackcess</groupId>
|
||||
<artifactId>jackcess</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||
<dependency>
|
||||
@ -543,12 +515,12 @@
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.jogamp.jogl/jogl-all-main -->
|
||||
<!-- https://mvnrepository.com/artifact/org.jogamp.jogl/jogl-all-main
|
||||
<dependency>
|
||||
<groupId>org.jogamp.jogl</groupId>
|
||||
<artifactId>jogl-all-main</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
</dependency>-->
|
||||
|
||||
<!-- NOT SURE IF WE NEED THE JAXB LIBRARIES HERE - NO ERRORS WHEN REMOVED
|
||||
<dependency>
|
||||
@ -624,12 +596,6 @@
|
||||
<version>1.6.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.diffplug.matsim/matfilerw -->
|
||||
<dependency>
|
||||
<groupId>com.diffplug.matsim</groupId>
|
||||
<artifactId>matfilerw</artifactId>
|
||||
<version>3.1.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.drewnoakes/metadata-extractor -->
|
||||
<dependency>
|
||||
@ -691,7 +657,8 @@
|
||||
<version>42.2.24</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.renjin/renjin-script-engine -->
|
||||
<!-- https://mvnrepository.com/artifact/org.renjin/renjin-script-engine
|
||||
Used to export data to R structures-->
|
||||
<dependency>
|
||||
<groupId>org.renjin</groupId>
|
||||
<artifactId>renjin-script-engine</artifactId>
|
||||
@ -716,6 +683,7 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.docx4j/docx4j-JAXB-ReferenceImpl -->
|
||||
<!-- note that we are excluding slf4j-api here, because if we don't then one of the
|
||||
transitive dependencies of docx4j (jcl-over-slf4j) will try to load an older
|
||||
@ -741,14 +709,14 @@
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.28.0</version>
|
||||
<version>3.45.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/net.sf.ucanaccess/ucanaccess -->
|
||||
<dependency>
|
||||
<groupId>net.sf.ucanaccess</groupId>
|
||||
<artifactId>ucanaccess</artifactId>
|
||||
<version>5.0.1</version>
|
||||
<version>4.0.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/nz.ac.waikato.cms.weka/weka-dev -->
|
||||
@ -788,6 +756,7 @@
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
|
||||
<!-- From NilusXMLGenerator POM at https://bitbucket.org/tethysacousticmetadata/nilusxmlgenerator/src/master/-->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.persistence</groupId>
|
||||
@ -809,92 +778,112 @@
|
||||
<artifactId>jaxb-xjc</artifactId>
|
||||
<version>${jaxb.xjc.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- dependencies copied from TethysJavaClient -->
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-multipart</artifactId>
|
||||
<version>1.18.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>3.10-beta1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>1.18.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-apache-client</artifactId>
|
||||
<version>1.18.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.miglayout</groupId>
|
||||
<artifactId>miglayout</artifactId>
|
||||
<version>3.7.4</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>ca.juliusdavies</groupId>
|
||||
<artifactId>not-yet-commons-ssl</artifactId>
|
||||
<version>0.3.11</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<version>2.1.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.2.11</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<version>2.2.11</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-core</artifactId>
|
||||
<version>2.2.11</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-common</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.9</version>
|
||||
</dependency>
|
||||
|
||||
<!-- dependencies copied from TethysJavaClient END -->
|
||||
|
||||
<!-- not in Maven repository
|
||||
you may need to copy files from your downloaded PAMGuard source code, e.g. C:\Users\*yourreposfolder*\source\repos\PAMGuardPAMGuard\repo\pamguard\org\x3\2.2.2 to
|
||||
C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2-->
|
||||
<dependency>
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.2.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Also not in Maven, so you may need to copy the javaclient and nilus folders from
|
||||
<!-- Thethy library not in Maven central, so you may need to copy the javaclient and nilus folders from
|
||||
e.g. C:\Users\dg50\source\repos\**your projectfolder**\repo\tethys\org
|
||||
to C:\Users\dg50\.m2\repository\tethys\org -->
|
||||
|
||||
<dependency>
|
||||
<groupId>tethys.org</groupId>
|
||||
<artifactId>nilus</artifactId>
|
||||
@ -907,6 +896,18 @@ to C:\Users\dg50\.m2\repository\tethys\org -->
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
X3 library for decompressing sud files. Not in Maven repository
|
||||
you may need to copy files from your downloaded PAMGuard source code,
|
||||
e.g. C:\Users\*yourreposfolder*\source\repos\PAMGuardPAMGuard\repo\pamguard\org\x3\2.2.2 to
|
||||
C:\Users\*yourusername*\.m2\repository\pamguard\org\x3\2.2.2
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.2.7</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/it.sauronsoftware/jave -->
|
||||
<dependency>
|
||||
@ -954,13 +955,20 @@ to C:\Users\dg50\.m2\repository\tethys\org -->
|
||||
<version>1.6.5-1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Theme for JavaFX -->
|
||||
|
||||
<!-- Extra 3D bits for JavaFX -->
|
||||
<dependency>
|
||||
<groupId>org.fxyz3d</groupId>
|
||||
<artifactId>fxyz3d</artifactId>
|
||||
<version>0.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Atlanta style for JavaFX -->
|
||||
<dependency>
|
||||
<groupId>io.github.mkpaz</groupId>
|
||||
<artifactId>atlantafx-base</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>2.0.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</project>
|
72
readme.md
72
readme.md
@ -1,5 +1,73 @@
|
||||
This is the main code repository for the PAMGuard software.
|
||||
# PAMGuard
|
||||
PAMGuard is a bioacoustics analysis program designed for use in real time research contexts and for the processing of large datasets. PAMGuard provides users access to a suite of state-of-the-art auotmated analysis algorithms alongside displays for visualisation data and a comprehensive data management systems.
|
||||
|
||||
This repository was created on 7 January 2022 from sourceforge SVN repository at https://sourceforge.net/p/pamguard/svn/HEAD/tree/ revision r6278.
|
||||
# Why do we need PAMGuard?
|
||||
PAMGuard fufills two main requirements within marine bioacoustics
|
||||
|
||||
1) **Real time operation** - Almost all PAMGuard features and modules work in real time - this allows scientists and industry to detect, classify and loclaise animals in real time on a standard consumer laptop, enabling mitigations and research survey without expensive bespoke software solutions and the transparncy of open source software.
|
||||
|
||||
2) **Processing and visuslisation of large datasets** -
|
||||
|
||||
|
||||
## Installation
|
||||
PAMGuard is available on Windows and can be downloaded from the [PAMGuard website](www.pamguard.org). Note that we are considering MacOS installers but they are not available at this time.
|
||||
|
||||
## Tutorial
|
||||
PAMGuard is a modular program with two modes; real-time and viewer. Typically a user will start with real-time model, either in the field collecting data or post processing sound files from a recorder. Once data are processed, users move on to viewer mode where data can be explored and further processed.
|
||||
|
||||
Upon opening PAMGuard for the first time you are greeted with a blank screen. You must add a series of modules to create the desired acosutic workflow. For example if processing sound files then first add the Sound Acquisition module **_File->Add Modules->Sound Processing->Sound Acquisition_**. Then add the desired detection algorothms e.g. **_File->Add Modules->Detector->Click Detectors_**. Some modules (such as the click detector) have their own displays, others are added to more generalised displays. For example, the whislte and moan detector module shows detections on a spectrgram display. First add a new tab using **_File->Add Modules->Displays->User Display**. Click on the user display tab and then from the top menu select **_User display-> New Spectrgram_**. Right click on the added spectrgram and select whistle and moan contours to show whistle detections overlaid on the raw spectrgram.
|
||||
|
||||
Make sure to add the database and binary file storage modules **_File->Add Modules->Utilities->..._**) to save data then press the run button (red button) and data will process. PAMGuard can handle huge datasets so runing might take hours or even days. Progress is shown on the bottom of the screen.
|
||||
|
||||
## Features
|
||||
|
||||
### Hardware integration
|
||||
PAMGuard connects with hardware such as various GPS and AIS systems and a multitude of different sound cards (e.g. [National Instruments](www.ni.com) devices, [SAIL DAQ cards](www.smruconsulting.com/contact-us), almost all ASIO sound cards and standard computer sound cards) for real time data collection and processing. PAMGuard also works with some very bespoke hardware such as [DIFAR Sonobuoys]();
|
||||
|
||||
### Real time operation
|
||||
PAMGuard takes advanatge of multi-core processors to run multiple signal processing automatic analysis algorithms in real time to detect whales, dolphins, bats etc. Data are shown in different displayes, including interactive spectrograms and maps. You might be using PAMGuard for simply viewing a spectrgram and making recordings or running deep learning algorithms for multiple species and loclaising the results to view locations on a map. Whatever acosutic workflow a user creates, PAMGuard can run it in real time.
|
||||
|
||||
### Support for compressed audio
|
||||
PAMGuard supports processing audio data from standard files (e.g. wav, aif) and also compressed files (e.g. .flac and .sud). Notew that sud files are created on SoundTraps widely used marine recorders and can be read by PAMGuard without decompressing - PAMGuard will automtically import click detections if present in sud files. PAMGuard also supports importing detection data from CPODs and FPODs.
|
||||
|
||||
### Comprehensive data management system
|
||||
PAMGuard is designed to collect/process data from large acosutic datasets. PAMGuard stores data in an SQLite databases and "Binary" files. The database stores important metadata such as when data has been processed and some low volume data streams such as GPS. Binary files are not human readbale but efficient to access - PAMGuard stores detection data (e.g. clicks, whistles, noise, etc) in these files. this allows PAMGuard to rapidly access data from large datasets. Data from binary files can be viewed in PAMGuard viewer mode or can be exported to MATLAB using the PAMGuard-MATLAB library or the exported to R using the R PAMBinaries package.
|
||||
|
||||
### Access to detection and classification algorithms
|
||||
PAMGuard allows users to inegrate automated detection and classification algorithms directly into their acosutic workflow. There are a multitude of differwent algorothms to choose from, including a basic click detector, whislte and moan detector, GPL detector, click train detectors and many others. The idea behind PAMGuard is allow researchers to access open source state-of-the-art algorithms devleoped within the scientific community - if you want to contribute and get your algorithm into PAMGuard get in touch.
|
||||
|
||||
###Localisation
|
||||
PAMGuard has a mutltude of different options for acoustic loclaisation. There's a comprehesnive beam forming module for beam forming arrays, a large aperture localiser for 3D loclaisation and target motion analysis for towed hydrophone arrays.
|
||||
|
||||
###Soundscape analysis
|
||||
PAMGuard has a noise band (which supports third octave noise bands) and long term spectral average module for soundscape analysis.
|
||||
|
||||
### GIS
|
||||
Almsot all detection data can be visualised on a map. PAMGaurd also supports plotting GPS and AIS data.
|
||||
|
||||
### Suite of data visualisation tools
|
||||
An important aspect of PAMGuard is the ability for users to explore porcessed data. This is
|
||||
|
||||
### Advanced manual annotation
|
||||
The displays within PAMGuard support a variety of manual annottion tools. A simple spectrogram
|
||||
|
||||
### Deep learning integration
|
||||
|
||||
### Meatadata standard and Tethys compatibility
|
||||
|
||||
## Feature roadmap
|
||||
There's lots of features we would like to add to PAMGuard. If you want to add a feature you can either code it up yourself in Java and submit a pull request or get in touch with us to discuss how to it might be integrated. Some smaller features might be in our roadmap anyway but larger features usually require funding. Some features we are thinking about (but do not necassarily have time for yet) are;
|
||||
|
||||
* Support for decidecade noise bands (base 10 filter bank) in noise band monitor to meet Euopean standards
|
||||
* Capabaility to export data directly from PAMGaurd e.g. as MAT files.
|
||||
* Automated test suite to make releases more stable. Note that unit and integration tests are also being slowly incorporated.
|
||||
|
||||
## Development
|
||||
This is the main code repository for the PAMGuard software and was created on 7 January 2022 from a [sourceforge SVN repository](https://sourceforge.net/p/pamguard/svn/HEAD/tree/) revision r6278.
|
||||
|
||||
If you are a PAMGuard developer, you should clone and branch this repository and share with any collaborators in your own workspace. When your work is ready, contact the PAMGuard team to have your changes merged back into this repo.
|
||||
|
||||
PAMGuard uses Maven as build tool.
|
||||
|
||||
# Organisation and License
|
||||
PAMGuard is open source under an MIT license. It is currently primarily managed by the Sea Mammal Research Unit within the [University of St Andrews](https://www.st-andrews.ac.uk/). Please get in touch if you have any questions.
|
||||
|
@ -1,9 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<<<<<<<< HEAD:repo/tethys/org/javaclient/3.0/javaclient-3.0.pom
|
||||
<groupId>tethys.org</groupId>
|
||||
<artifactId>javaclient</artifactId>
|
||||
<version>3.0</version>
|
||||
========
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.2.6</version>
|
||||
>>>>>>>> upstream/main:repo/pamguard/org/x3/2.2.6/x3-2.2.6.pom
|
||||
<description>POM was created from install:install-file</description>
|
||||
</project>
|
||||
|
@ -2,8 +2,14 @@
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<<<<<<<< HEAD:repo/tethys/org/nilus/3.0/nilus-3.0.pom
|
||||
<groupId>tethys.org</groupId>
|
||||
<artifactId>nilus</artifactId>
|
||||
<version>3.0</version>
|
||||
========
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.2.7</version>
|
||||
>>>>>>>> upstream/main:repo/pamguard/org/x3/2.2.7/x3-2.2.7.pom
|
||||
<description>POM was created from install:install-file</description>
|
||||
</project>
|
||||
|
@ -0,0 +1,16 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Thu Mar 07 12:09:00 GMT 2024
|
||||
@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1705320262317
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.lastUpdated=1705320259110
|
||||
https\://repo1.maven.org/maven2/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1705320260572
|
||||
https\://repo1.maven.org/maven2/.lastUpdated=1705320262598
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:javaclient\:jar\:javadoc\:3.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.lastUpdated=1705569305037
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1705320262257
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1709813340827
|
@ -0,0 +1,16 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Thu Mar 07 12:08:16 GMT 2024
|
||||
@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1703957320119
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.error=
|
||||
https\://repo1.maven.org/maven2/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.lastUpdated=1705074190844
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1703957319870
|
||||
https\://repo1.maven.org/maven2/.lastUpdated=1703957320395
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:javaclient\:jar\:sources\:3.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.lastUpdated=1703957318729
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1703957320102
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1709813296623
|
@ -2,8 +2,14 @@
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<<<<<<<< HEAD:repo/tethys/org/javaclient/3.0/javaclient-3.0.pom
|
||||
<groupId>tethys.org</groupId>
|
||||
<artifactId>javaclient</artifactId>
|
||||
<version>3.0</version>
|
||||
========
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.2.6</version>
|
||||
>>>>>>>> upstream/main:repo/pamguard/org/x3/2.2.6/x3-2.2.6.pom
|
||||
<description>POM was created from install:install-file</description>
|
||||
</project>
|
||||
|
15
repo/tethys/org/javaclient/3.0/m2e-lastUpdated.properties
Normal file
15
repo/tethys/org/javaclient/3.0/m2e-lastUpdated.properties
Normal file
@ -0,0 +1,15 @@
|
||||
#Thu Mar 07 12:09:00 GMT 2024
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|javadoc=1709813340828
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo|javadoc=1705320262599
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo|javadoc=1709813340828
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo|javadoc=1705569305040
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1709813296626
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo|sources=1709813296626
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1709813296626
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1709813296626
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo|sources=1703957320396
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo|sources=1705074190848
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|javadoc=1709813340828
|
||||
central|https\://repo1.maven.org/maven2|sources=1709813296626
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|javadoc=1709813340828
|
||||
central|https\://repo1.maven.org/maven2|javadoc=1709813340828
|
@ -1,4 +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
|
||||
#Thu Mar 07 11:55:57 GMT 2024
|
||||
nilus-3.0.pom>=
|
||||
nilus-3.0.jar>=
|
||||
|
@ -1,11 +1,15 @@
|
||||
#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
|
||||
#Thu Jan 18 09:15:05 GMT 2024
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|javadoc=1705569305022
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo|javadoc=1705320259098
|
||||
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/repo|javadoc=1705569305022
|
||||
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
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1705074190830
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1705074190830
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1705074190830
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo|sources=1703957318711
|
||||
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo|sources=1705074190830
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|javadoc=1705569305022
|
||||
central|https\://repo1.maven.org/maven2|sources=1705074190830
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|javadoc=1705569305022
|
||||
central|https\://repo1.maven.org/maven2|javadoc=1705569305022
|
||||
|
@ -1,12 +1,16 @@
|
||||
#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
|
||||
#Thu Jan 18 09:15:05 GMT 2024
|
||||
@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
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.lastUpdated=1705320259096
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.error=
|
||||
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
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.lastUpdated=1705569305018
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1703177110940
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1703177112519
|
||||
|
@ -1,12 +1,16 @@
|
||||
#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
|
||||
#Fri Jan 12 15:43:10 GMT 2024
|
||||
@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
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.lastUpdated=1705074190824
|
||||
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
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.lastUpdated=1703957318705
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.error=
|
||||
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG_2/repo/.lastUpdated=1703157322932
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1703157323770
|
||||
|
Binary file not shown.
@ -2,8 +2,14 @@
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<<<<<<<< HEAD:repo/tethys/org/nilus/3.0/nilus-3.0.pom
|
||||
<groupId>tethys.org</groupId>
|
||||
<artifactId>nilus</artifactId>
|
||||
<version>3.0</version>
|
||||
========
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.2.7</version>
|
||||
>>>>>>>> upstream/main:repo/pamguard/org/x3/2.2.7/x3-2.2.7.pom
|
||||
<description>POM was created from install:install-file</description>
|
||||
</project>
|
||||
|
@ -7,6 +7,6 @@
|
||||
<versions>
|
||||
<version>3.0</version>
|
||||
</versions>
|
||||
<lastUpdated>20231221111413</lastUpdated>
|
||||
<lastUpdated>20240307115557</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
||||
|
@ -429,6 +429,8 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
// acquisitionDialog.NotifyChange();
|
||||
if (file.isFile() && !file.isHidden() && acquisitionDialog != null) {
|
||||
try {
|
||||
|
||||
System.out.println("FileInputSystem - interpretNewFile");
|
||||
AudioInputStream audioStream = PamAudioFileManager.getInstance().getAudioInputStream(file);
|
||||
|
||||
// // Get additional information from the header if it's a wav file.
|
||||
@ -600,6 +602,8 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
audioStream.close();
|
||||
}
|
||||
|
||||
System.out.println("FileInputSystem - prepareInputFile");
|
||||
|
||||
audioStream = PamAudioFileManager.getInstance().getAudioInputStream(currentFile);
|
||||
|
||||
if (audioStream instanceof SudAudioInputStream) {
|
||||
@ -810,6 +814,10 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
protected void collectFlacData() {
|
||||
FileInputStream fileStream;
|
||||
try {
|
||||
File currFile = getCurrentFile();
|
||||
if (currFile == null) {
|
||||
return;
|
||||
}
|
||||
fileStream = new FileInputStream(getCurrentFile());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -602,6 +602,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
|
||||
@Override
|
||||
public File getCurrentFile() {
|
||||
//System.out.println("All files: " + allFiles);
|
||||
// System.out.printf("Folder: getCurrentfile. on %d of %d\n", currentFile, allFiles.size());
|
||||
if (allFiles != null && allFiles.size() > currentFile) {
|
||||
return allFiles.get(currentFile);
|
||||
}
|
||||
@ -689,7 +690,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
|
||||
}
|
||||
if (currentFile < allFiles.size()) {
|
||||
// only restart if the file ended - not if it stopped
|
||||
if (getStreamStatus() == STREAM_ENDED) {
|
||||
if (getStreamStatus() == STREAM_ENDED && PamController.getInstance().isManualStop() == false) {
|
||||
// System.out.println(String.format("Start new file timer (file %d/%d)",currentFile+1,allFiles.size()));
|
||||
newFileTimer.start();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package Acquisition.filedate;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
@ -15,7 +16,11 @@ import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import org.kordamp.ikonli.materialdesign2.MaterialDesignC;
|
||||
import org.kordamp.ikonli.swing.FontIcon;
|
||||
|
||||
import PamUtils.PamCalendar;
|
||||
import PamView.component.PamSettingsIconButton;
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
|
||||
/**
|
||||
@ -35,7 +40,9 @@ public class FileDateDialogStrip {
|
||||
|
||||
private JButton settingsButton;
|
||||
|
||||
private ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png"));
|
||||
// private ImageIcon settingsIcon = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png"));
|
||||
public static FontIcon settingsIcon = FontIcon.of(PamSettingsIconButton.SETTINGS_IKON, PamSettingsIconButton.NORMAL_SIZE, Color.DARK_GRAY);
|
||||
|
||||
|
||||
private Window parent;
|
||||
|
||||
|
@ -135,6 +135,8 @@ public class StandardFileDate implements FileDate, PamSettings {
|
||||
@Override
|
||||
public long getTimeFromFile(File file) {
|
||||
|
||||
// System.out.println("Get time from file: getTimeFromFile" );
|
||||
|
||||
// if the user wants to force the local PC time, return immediately
|
||||
if (settings.isForcePCTime()) return 0;
|
||||
|
||||
|
@ -290,7 +290,7 @@ public class AcquisitionPaneFX extends SettingsPane<AcquisitionParameters>{
|
||||
//custom pane for each aquisition system.
|
||||
systemPane=new PamBorderPane();
|
||||
|
||||
offlineDAQPaneFX= new OfflineDAQPane(acquisitionControl, this);
|
||||
offlineDAQPaneFX= new OfflineDAQPane(acquisitionControl);
|
||||
|
||||
//the main pane is for reference only in viewer mode.
|
||||
Pane samplingPane=createSamplingPane();
|
||||
|
@ -147,7 +147,12 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
else {
|
||||
folderName.setText(folderInputSystem.getCurrentFolder());
|
||||
}
|
||||
|
||||
if (folderInputSystem.getCurrentFolder()!=null){
|
||||
folder = new File(folderInputSystem.getCurrentFolder());
|
||||
}
|
||||
else folder = null;
|
||||
|
||||
textArea.setText(" ");
|
||||
allFiles.clear();
|
||||
nFiles = countFiles(folder);
|
||||
@ -159,6 +164,7 @@ public class CheckWavHeadersPane extends PamBorderPane {
|
||||
|
||||
|
||||
private int countFiles(File folder) {
|
||||
if (folder == null) return 0;
|
||||
int nF = 0;
|
||||
File[] files = folder.listFiles(new PamAudioFileFilter());
|
||||
if (files == null) return 0;
|
||||
|
@ -215,7 +215,7 @@ public class FileDataDialogStripFX extends PamBorderPane {
|
||||
popOver.show(advSettingsButton);
|
||||
|
||||
((Parent) popOver.getSkin().getNode()).getStylesheets()
|
||||
.add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getSlidingDialogCSS());
|
||||
.addAll(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getSlidingDialogCSS());
|
||||
|
||||
advDatePane.setParams();
|
||||
}
|
||||
|
@ -193,20 +193,18 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
|
||||
//TODO
|
||||
});
|
||||
|
||||
browseFileButton.setGraphic(Glyph.create("FontAwesome|FILES_ALT").
|
||||
size(PamGuiManagerFX.iconSize).color(Color.WHITE.darker()));
|
||||
browseFileButton.setGraphic(PamGlyphDude.createPamIcon("mdi2f-file-multiple", PamGuiManagerFX.iconSize));
|
||||
browseFileButton.prefHeightProperty().bind(fileSelectBox.heightProperty()); //make browse button same height as combo box.
|
||||
browseFileButton.setMinWidth(35);
|
||||
browseFileButton.setMinWidth(40);
|
||||
browseFileButton.setOnAction( (action) ->{
|
||||
selectFolder(false);
|
||||
});
|
||||
browseFileButton.setTooltip(new Tooltip("Select a folder of files"));
|
||||
|
||||
|
||||
browseFolderButton.setGraphic(Glyph.create("FontAwesome|FOLDER").
|
||||
size(PamGuiManagerFX.iconSize).color(Color.WHITE.darker()));
|
||||
browseFolderButton.setGraphic(PamGlyphDude.createPamIcon("mdi2f-folder", PamGuiManagerFX.iconSize));
|
||||
browseFolderButton.prefHeightProperty().bind(fileSelectBox.heightProperty()); //make browse button same height as combo box.
|
||||
browseFolderButton.setMinWidth(35);
|
||||
browseFolderButton.setMinWidth(40);
|
||||
browseFolderButton.setOnAction( (action) ->{
|
||||
selectFolder(true);
|
||||
});
|
||||
|
@ -30,8 +30,7 @@ public class OfflineDAQPane extends SettingsPane<OfflineFileParameters>{
|
||||
private PamBorderPane mainPane;
|
||||
|
||||
|
||||
public OfflineDAQPane(OfflineFileDataStore acquisitionControl,
|
||||
AcquisitionPaneFX acquisitionPaneFX){
|
||||
public OfflineDAQPane(OfflineFileDataStore acquisitionControl){
|
||||
super(null);
|
||||
this.mainPane= new PamBorderPane();
|
||||
mainPane.setCenter(createOfflinePane());
|
||||
|
@ -135,7 +135,7 @@ public class PamAudioFileManager {
|
||||
}
|
||||
|
||||
if (stream == null) {
|
||||
System.err.println("PamAudioFileManager: unable to open an AudioStream for " + file.getName());
|
||||
System.err.println("PamAudioFileManager: unable to open an AudioStream for " + file.getName() + " size: " + file.length());
|
||||
}
|
||||
|
||||
return stream;
|
||||
@ -153,7 +153,7 @@ public class PamAudioFileManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audio file filter
|
||||
* Get the audio file filter.
|
||||
*
|
||||
* @return the audio file filter.
|
||||
*/
|
||||
@ -164,7 +164,7 @@ public class PamAudioFileManager {
|
||||
/**
|
||||
* Get the current audio file
|
||||
*
|
||||
* @return a list oif the current audio loaders.
|
||||
* @return a list of the current audio loaders.
|
||||
*/
|
||||
public ArrayList<PamAudioFileLoader> getAudioFileLoaders() {
|
||||
return this.pamAudioFileTypes;
|
||||
|
@ -254,7 +254,7 @@ public class WavAudioFile implements PamAudioFileLoader {
|
||||
|
||||
@Override
|
||||
public AudioInputStream getAudioStream(File soundFile) {
|
||||
if (soundFile.exists() == false) return null;
|
||||
if (soundFile.exists() == false || soundFile.length()<44) return null;
|
||||
if (soundFile != null && isSoundFile(soundFile)) {
|
||||
try {
|
||||
return WavFileInputStream.openInputStream(soundFile);
|
||||
@ -262,7 +262,7 @@ public class WavAudioFile implements PamAudioFileLoader {
|
||||
catch (UnsupportedAudioFileException | IOException e) {
|
||||
e.printStackTrace();
|
||||
// don't do anything and it will try the built in Audiosystem
|
||||
System.err.println("Could not open wav file: trying default audio stream: " + soundFile.getName());
|
||||
System.err.println("Could not open wav file: trying default audio stream: " + soundFile.getName() + " " + soundFile.length());
|
||||
}
|
||||
}
|
||||
try {
|
||||
@ -276,9 +276,24 @@ public class WavAudioFile implements PamAudioFileLoader {
|
||||
}
|
||||
|
||||
|
||||
public boolean isSoundFile(File soundFile) {
|
||||
public static boolean isSoundFile(File soundFile) {
|
||||
String extension = FileUtils.getExtension(soundFile.getName());
|
||||
return (extension.equals(".wav"));
|
||||
//2023-03-12 - for some reason this was .wav
|
||||
return (extension.equals("wav"));
|
||||
}
|
||||
|
||||
|
||||
public static void main(String args[]) {
|
||||
|
||||
File wavFile = new File("E:\\SoundNet\\1chan_analysis\\pamguard\\67150826\\mf_wav\\20180529\\PAM_20180529_055114_000.wav");
|
||||
try {
|
||||
WavFileInputStream.openInputStream(wavFile);
|
||||
System.out.println("Wav file opened successfully: " + isSoundFile(wavFile));
|
||||
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,6 +51,8 @@ public class WavFileInputStream extends AudioInputStream {
|
||||
if (wavHeader.readHeader(windowsFile) == false) {
|
||||
throw new UnsupportedAudioFileException("Unsupprted wav file format in " + file.getName());
|
||||
}
|
||||
|
||||
|
||||
long nFrames = wavHeader.getDataSize() / wavHeader.getBlockAlign();
|
||||
|
||||
//29/03/2017 Found that the block align read from header was wrong in SoundTrap. This solves the problem and is still OK for normal
|
||||
|
@ -45,11 +45,17 @@ public class SUDFileTime {
|
||||
// return Long.MIN_VALUE;
|
||||
// }
|
||||
// long t = sudMap.getFirstChunkTimeMillis();
|
||||
System.out.println("Error getting time from SUD file: " + file==null? null : (file.getName() + " size: " + file.length() / (1024 * 1024) + " MB"));
|
||||
|
||||
long t = SudAudioInputStream.quickFileTime(file);
|
||||
t=t/1000; //turn to milliseconds.
|
||||
if (t != 0) {
|
||||
if (t > 0) {
|
||||
sudTime = t;
|
||||
}
|
||||
else {
|
||||
//an error has occurred
|
||||
System.err.println("Error getting time from SUD file: " + file==null? null : (file.getName() + " size: " + file.length() / (1024 * 1024) + " MB"));
|
||||
}
|
||||
|
||||
// sudAudioInputStream.addSudFileListener((chunkID, sudChunk)->{
|
||||
// ChunkHeader chunkHead = sudChunk.chunkHeader;
|
||||
|
@ -10,13 +10,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import pamMaths.PamQuaternion;
|
||||
import pamMaths.PamVector;
|
||||
import userDisplay.UserDisplayControl;
|
||||
import depthReadout.DepthControl;
|
||||
import Array.importHydrophoneData.HydrophoneImport;
|
||||
import Array.importHydrophoneData.StreamerImport;
|
||||
import Array.layoutFX.ArrayGUIFX;
|
||||
@ -91,7 +87,7 @@ public class ArrayManager extends PamControlledUnit implements PamSettings, PamO
|
||||
|
||||
// private DepthControl depthControl;
|
||||
|
||||
private ImportDataSystem<ArrayList<Double>> hydrophoneImportManager;
|
||||
private ImportDataSystem<Hydrophone> hydrophoneImportManager;
|
||||
|
||||
private ImportDataSystem<ArrayList<Double>> streamerImportManager;
|
||||
|
||||
@ -140,7 +136,7 @@ public class ArrayManager extends PamControlledUnit implements PamSettings, PamO
|
||||
|
||||
//enable importing of time stamped hydrophone and streamer data if in viewer mode.
|
||||
if (isViewer){
|
||||
hydrophoneImportManager= new ImportDataSystem<ArrayList<Double>>(new HydrophoneImport(hydrophonesProcess.getHydrophoneDataBlock()));
|
||||
hydrophoneImportManager= new ImportDataSystem<Hydrophone>(new HydrophoneImport(hydrophonesProcess.getHydrophoneDataBlock()));
|
||||
hydrophoneImportManager.setName("Hydrophone Data Import");
|
||||
streamerImportManager = new ImportDataSystem<ArrayList<Double>>(new StreamerImport(hydrophonesProcess.getStreamerDataBlock()));
|
||||
streamerImportManager.setName("Streamer Data Import");
|
||||
@ -1054,12 +1050,17 @@ public class ArrayManager extends PamControlledUnit implements PamSettings, PamO
|
||||
/**
|
||||
* Rotate the hydrophone about the centre of it's streamer.
|
||||
*/
|
||||
Hydrophone hydrophone = currentArray.getHiddenHydrophone(i);
|
||||
// Hydrophone hydrophone = currentArray.getHiddenHydrophone(i);
|
||||
Hydrophone hydrophone = currentArray.getHydrophone(i, timeMillis);
|
||||
|
||||
|
||||
|
||||
if (hydrophone == null) {
|
||||
continue;
|
||||
}
|
||||
PamVector hydrophoneVec = hydrophone.getVector();
|
||||
PamVector hydrophoneErrorVec = hydrophone.getErrorVector();
|
||||
|
||||
if (streamerQuaternion != null) {
|
||||
hydrophoneVec = PamVector.rotateVector(hydrophoneVec, streamerQuaternion);
|
||||
hydrophoneErrorVec = PamVector.rotateVector(hydrophoneErrorVec, streamerQuaternion);
|
||||
@ -1111,7 +1112,7 @@ public class ArrayManager extends PamControlledUnit implements PamSettings, PamO
|
||||
referencePoint = shipPos.getGpsData();
|
||||
}
|
||||
}
|
||||
if (referencePoint == null) {
|
||||
if (referencePoint == null && MasterReferencePoint.getFixTime() != null && MasterReferencePoint.getLatLong() != null) {
|
||||
// running out of options, so fall back to the master reference point, interpolated (probably has zero speeed)
|
||||
referencePoint = new GpsData(MasterReferencePoint.getFixTime(), MasterReferencePoint.getLatLong()).getPredictedGPSData(timeMillis);
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
/**
|
||||
* @return error on the hydrophone x coordinate.
|
||||
*/
|
||||
protected double getdX() {
|
||||
public double getdX() {
|
||||
return getCoordinateError(0);
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
* Set the error on the hydrophone x coordinate
|
||||
* @param error error in metres.
|
||||
*/
|
||||
protected void setdX(double error) {
|
||||
public void setdX(double error) {
|
||||
setCoordinateError(0, error);
|
||||
}
|
||||
|
||||
@ -219,7 +219,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
/**
|
||||
* @return error on the hydrophone y coordinate.
|
||||
*/
|
||||
protected double getdY() {
|
||||
public double getdY() {
|
||||
return getCoordinateError(1);
|
||||
}
|
||||
|
||||
@ -227,14 +227,14 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
* Set the error on the hydrophone y coordinate
|
||||
* @param error error in metres.
|
||||
*/
|
||||
protected void setdY(double error) {
|
||||
public void setdY(double error) {
|
||||
setCoordinateError(1, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return error on the hydrophone depth coordinate.
|
||||
*/
|
||||
protected double getdZ(){
|
||||
public double getdZ(){
|
||||
return getCoordinateError(2);
|
||||
}
|
||||
|
||||
@ -242,19 +242,19 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
* Set the error on the hydrophone z coordinate
|
||||
* @param error error in metres.
|
||||
*/
|
||||
protected void setdZ(double error) {
|
||||
public void setdZ(double error) {
|
||||
setCoordinateError(2, error);
|
||||
}
|
||||
|
||||
protected double getX() {
|
||||
public double getX() {
|
||||
return coordinate[0];
|
||||
}
|
||||
|
||||
protected void setX(double x) {
|
||||
public void setX(double x) {
|
||||
this.coordinate[0] = x;
|
||||
}
|
||||
|
||||
protected double getY() {
|
||||
public double getY() {
|
||||
return coordinate[1];
|
||||
}
|
||||
|
||||
@ -289,7 +289,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
return y2;
|
||||
}
|
||||
|
||||
protected void setY(double y) {
|
||||
public void setY(double y) {
|
||||
this.coordinate[1] = y;
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
return coordinate[2];
|
||||
}
|
||||
|
||||
protected void setZ(double z) {
|
||||
public void setZ(double z) {
|
||||
this.coordinate[2] = z;
|
||||
}
|
||||
|
||||
@ -316,7 +316,7 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
// need to explicity create a new copy of the double[3] coordinate
|
||||
// and the double[2] bandwidth
|
||||
Hydrophone h = (Hydrophone) super.clone();
|
||||
h.setBandwidth(Arrays.copyOf(getBandwidth(), h.getBandwidth().length));
|
||||
h.setBandwidth(getBandwidth() == null ? null : Arrays.copyOf(getBandwidth(), h.getBandwidth().length));
|
||||
h.setCoordinate(Arrays.copyOf(getCoordinates(), 3));
|
||||
h.setCoordinateErrors(Arrays.copyOf(getCoordinateErrors(), 3));
|
||||
h.checkDepthInversion();
|
||||
@ -379,14 +379,14 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
/**
|
||||
* @return Returns the iD.
|
||||
*/
|
||||
protected int getID() {
|
||||
public int getID() {
|
||||
return iD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id The iD to set.
|
||||
*/
|
||||
protected void setID(int id) {
|
||||
public void setID(int id) {
|
||||
iD = id;
|
||||
}
|
||||
//
|
||||
@ -427,11 +427,11 @@ public class Hydrophone implements Serializable, Cloneable, ManagedParameters {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
protected int getStreamerId() {
|
||||
public int getStreamerId() {
|
||||
return streamerId;
|
||||
}
|
||||
|
||||
protected void setStreamerId(int streamerId) {
|
||||
public void setStreamerId(int streamerId) {
|
||||
this.streamerId = streamerId;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import java.util.ListIterator;
|
||||
import GPS.NavDataSynchronisation;
|
||||
import pamScrollSystem.ViewLoadObserver;
|
||||
import PamController.PamController;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
||||
@ -68,6 +69,11 @@ public class HydrophoneDataBlock extends PamDataBlock<HydrophoneDataUnit> {
|
||||
@Override
|
||||
public boolean loadViewerData(OfflineDataLoadInfo offlineDataLoadInfo,
|
||||
ViewLoadObserver loadObserver) {
|
||||
|
||||
// if (offlineDataLoadInfo!=null) {
|
||||
// System.out.print("Load Hydrophones: " + ((offlineDataLoadInfo.getEndMillis() - offlineDataLoadInfo.getStartMillis())/1000/60/60 + " hours"));
|
||||
// System.out.print("From: " +PamCalendar.formatDateTime(offlineDataLoadInfo.getStartMillis()) + " to " + PamCalendar.formatDateTime(offlineDataLoadInfo.getEndMillis()));
|
||||
// }
|
||||
/**
|
||||
* Always put in default data units at time zero.
|
||||
*/
|
||||
@ -103,6 +109,7 @@ public class HydrophoneDataBlock extends PamDataBlock<HydrophoneDataUnit> {
|
||||
}
|
||||
unit = listIterator.previous();
|
||||
difference = Math.abs(startTime - unit.getTimeMilliseconds());
|
||||
|
||||
while (listIterator.hasPrevious()) {
|
||||
preceedingUnit = listIterator.previous();
|
||||
if (preceedingUnit.getHydrophone().getID()!=ihydrophone) {
|
||||
@ -110,6 +117,7 @@ public class HydrophoneDataBlock extends PamDataBlock<HydrophoneDataUnit> {
|
||||
}
|
||||
newdifference = Math.abs(startTime- preceedingUnit.getTimeMilliseconds());
|
||||
if (newdifference > difference) {
|
||||
// System.out.println("Hydrophone datablock: newDifference: " + newdifference + " " + unit.getHydrophone().getZ());
|
||||
return unit;
|
||||
}
|
||||
else {
|
||||
|
@ -397,6 +397,8 @@ public class HydrophoneElementDialog extends PamDialog {
|
||||
dz.setText(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean getParams() {
|
||||
|
||||
double zCoeff = PamController.getInstance().getGlobalMediumManager().getZCoeff();
|
||||
|
@ -39,6 +39,7 @@ import PamModel.parametermanager.PamParameterSet.ParameterSetType;
|
||||
import PamModel.parametermanager.PrivatePamParameterData;
|
||||
import PamUtils.LatLong;
|
||||
import PamUtils.PamArrayUtils;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamView.PamSymbol;
|
||||
import PamguardMVC.ChannelIterator;
|
||||
import PamguardMVC.PamConstants;
|
||||
@ -265,7 +266,9 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters {
|
||||
}
|
||||
|
||||
protected Hydrophone getHydrophone(int iPhone, long timeMilliseconds) {
|
||||
// Debug.println("PAMArray: Get hydrophone coords: " + timeMilliseconds + " iPhone: " + iPhone);
|
||||
// System.out.println("PAMArray: Get hydrophone coords: " + PamCalendar.formatDateTime(timeMilliseconds) + " iPhone: " + iPhone);
|
||||
|
||||
|
||||
if (hydrophoneInterpolation == ORIGIN_USE_LATEST) {
|
||||
return getHydrophone(iPhone);
|
||||
}
|
||||
@ -276,11 +279,13 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters {
|
||||
//FIXME - for some reason the above lines were always returning the first hydrophone in the datablock ^
|
||||
HydrophoneDataUnit hdu = ArrayManager.getArrayManager().getHydrophoneDataBlock().getClosestHydrophone(timeMilliseconds, iPhone);
|
||||
|
||||
// System.out.println("PAMArray: hdu: " + hdu + " " + (hdu==null? null: PamCalendar.formatDateTime(hdu.getTimeMilliseconds()) + " Z" + hdu.getHydrophone().getdZ()));
|
||||
|
||||
if (hdu != null) {
|
||||
// Debug.println("PAMArray: found unit: " + hdu.getTimeMilliseconds());
|
||||
// System.out.println("PAMArray: found unit: " + hdu.getTimeMilliseconds());
|
||||
// long firstTime = ArrayManager.getArrayManager().getHydrophoneDataBlock().getFirstUnit().getTimeMilliseconds();
|
||||
// long lastTime = ArrayManager.getArrayManager().getHydrophoneDataBlock().getLastUnit().getTimeMilliseconds();
|
||||
// Debug.println("PAMArray: found unit: " + firstTime + " " + lastTime + " no: units: " + ArrayManager.getArrayManager().getHydrophoneDataBlock().getUnitsCount());
|
||||
// System.out.println("PAMArray: found unit: " + firstTime + " " + lastTime + " no: units: " + ArrayManager.getArrayManager().getHydrophoneDataBlock().getUnitsCount());
|
||||
// TODO should maybe do something here to average out two hydrophones if interpolation option is selected.
|
||||
return hdu.getHydrophone();
|
||||
}
|
||||
@ -1305,7 +1310,6 @@ public class PamArray implements Serializable, Cloneable, ManagedParameters {
|
||||
* @return
|
||||
*/
|
||||
public int addStreamer(Streamer streamer) {
|
||||
|
||||
synchronized (streamers) {
|
||||
streamers.add(streamer);
|
||||
checkStreamerIndexes();
|
||||
|
@ -571,7 +571,7 @@ public class Streamer implements Serializable, Cloneable, ManagedParameters {
|
||||
/**
|
||||
* Make a streamer data unit and add it to the data block.
|
||||
*/
|
||||
protected void makeStreamerDataUnit() {
|
||||
public void makeStreamerDataUnit() {
|
||||
StreamerDataUnit sdu = new StreamerDataUnit(PamCalendar.getTimeInMillis(), this);
|
||||
ArrayManager.getArrayManager().getStreamerDatabBlock().addPamData(sdu);
|
||||
}
|
||||
@ -667,8 +667,8 @@ public class Streamer implements Serializable, Cloneable, ManagedParameters {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + "; OriginSettings: " + getOriginSettings().toString() + "," + getHydrophoneOrigin().getOriginSettings().toString() +
|
||||
"; Locator " + getLocatorSettings().toString();
|
||||
return super.toString() + "; OriginSettings: " + getOriginSettings()==null ? "null" : getOriginSettings().toString() + "," + getHydrophoneOrigin().getOriginSettings().toString() +
|
||||
"; Locator " + getLocatorSettings()==null ? "null" : getLocatorSettings().toString();
|
||||
}
|
||||
|
||||
public static Streamer getAverage(Streamer sd1,
|
||||
|
@ -376,6 +376,9 @@ public class StreamerDialog extends PamDialog {
|
||||
|
||||
defaultStreamer.setStreamerName(streamerName.getText());
|
||||
int im = interpolationPanel.getSelection();
|
||||
|
||||
System.out.println("GetParams: INTERPOLATION SELECTION: " + currentArray.getOriginInterpolation());
|
||||
|
||||
if (im < 0) {
|
||||
return showWarning("Invalid interpolation selection");
|
||||
}
|
||||
|
@ -1,15 +1,22 @@
|
||||
package Array.importHydrophoneData;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import Array.ArrayManager;
|
||||
import Array.Hydrophone;
|
||||
import Array.HydrophoneDataBlock;
|
||||
import Array.HydrophoneDataUnit;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamUtils.TxtFileUtils;
|
||||
import PamView.importData.DataImport;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.PamDataUnit;
|
||||
import us.hebi.matlab.mat.format.Mat5;
|
||||
import us.hebi.matlab.mat.format.Mat5File;
|
||||
import us.hebi.matlab.mat.types.Array;
|
||||
import us.hebi.matlab.mat.types.Matrix;
|
||||
import us.hebi.matlab.mat.types.Struct;
|
||||
|
||||
/**
|
||||
* Class for importing hydrophone data from external file and saving to database.
|
||||
@ -27,13 +34,15 @@ import PamguardMVC.PamDataUnit;
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*/
|
||||
public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
public class HydrophoneImport extends DataImport<Hydrophone>{
|
||||
|
||||
String[] extensionStrings={".csv"};
|
||||
String[] extensionStrings={".csv", ".mat"};
|
||||
private ArrayList<ArrayList<Double>> hydrophonePositions;
|
||||
private int errorCode;
|
||||
private HydrophoneDataBlock hydrophoneDataBlock;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Streamer id to use if imported data has no streamer id info
|
||||
*/
|
||||
@ -80,7 +89,7 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
public final static int ERROR_LOADING_MATLAB_STRUCT=6;
|
||||
|
||||
/**
|
||||
* The number of hydrophones is not the same as the number of hydrophones in the curretn array manager.
|
||||
* The number of hydrophones is not the same as the number of hydrophones in the current array manager.
|
||||
*/
|
||||
public final static int ERROR_NUMBER_OF_HYDROPHONES_ARRAY=7;
|
||||
|
||||
@ -118,10 +127,12 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
|
||||
if (filePath.endsWith(".mat")){
|
||||
|
||||
hydrophonePositions=importPositionsFromMatlab(filePath);
|
||||
ArrayList<Hydrophone> hydrophonePositions = importPositionsFromMatlab(filePath);
|
||||
|
||||
if (hydrophonePositions==null) errorCode=ERROR_LOADING_MATLAB_STRUCT;
|
||||
|
||||
return hydrophonePositions;
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -129,17 +140,23 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a 2D List of hydrophones into a 1D list of hydrophones.
|
||||
* @param importData. Each row of the input array must have the following format. time, x0, y0,z0, x0Error, y0Error, z0Error,x1, y1,z1, x1Error, y1Error, z1Error,,..... and so on depending on the number of hydrophones.
|
||||
* @return a list of hydrophones with the following format for each row. [0]=timeMilliss [1]=x [2]=y [3]=z [4]=xErr [5]=yErr [6]=zErr [7]=streamerId [8]=hydrophoneId;
|
||||
* Converts a 2D List of hydrophones into a 1D list of hydrophone objecys.
|
||||
*
|
||||
* @param importData. Each row of the input array must have the following
|
||||
* format. time, x0, y0,z0, x0Error, y0Error, z0Error,x1,
|
||||
* y1,z1, x1Error, y1Error, z1Error,,..... and so on
|
||||
* depending on the number of hydrophones.
|
||||
* @return a list of hydrophone objects.
|
||||
*/
|
||||
public ArrayList<ArrayList<Double>> convertToHydrophoneList(ArrayList<ArrayList<Double>> importData){
|
||||
public ArrayList<Hydrophone> convertToHydrophoneList(ArrayList<ArrayList<Double>> importData){
|
||||
|
||||
ArrayList<ArrayList<Double>> hydrophonesAll=new ArrayList<ArrayList<Double>>();
|
||||
ArrayList<Hydrophone> hydrophonesAll=new ArrayList<Hydrophone>();
|
||||
ArrayList<Double> tempArray;
|
||||
Hydrophone hydrophone;
|
||||
double[] cOordinates;
|
||||
double [] cOordinateErrors;
|
||||
double sensitivity;
|
||||
double gain;
|
||||
for (int i=0; i<importData.size(); i++){
|
||||
for (int j=0; j<((importData.get(i).size()-1)/6); j++){
|
||||
|
||||
@ -156,20 +173,34 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
cOordinateErrors[1]=importData.get(i).get(j*6+5);
|
||||
cOordinateErrors[2]=importData.get(i).get(j*6+6);
|
||||
|
||||
tempArray.add(importData.get(i).get(0));
|
||||
tempArray.add(cOordinates[0]);
|
||||
tempArray.add(cOordinates[1]);
|
||||
tempArray.add(cOordinates[2]);
|
||||
tempArray.add(cOordinateErrors[0]);
|
||||
tempArray.add(cOordinateErrors[1]);
|
||||
tempArray.add(cOordinateErrors[2]);
|
||||
sensitivity=ArrayManager.DEFAULT_HYDROPHONE_SENSITIVITY;
|
||||
gain=ArrayManager.DEFAULT_PREAMP_GAIN;
|
||||
|
||||
hydrophone=new Hydrophone(j,
|
||||
cOordinates[0], cOordinates[1],cOordinates[2],
|
||||
cOordinateErrors[0], cOordinateErrors[1],cOordinateErrors[2],
|
||||
"Unknown",
|
||||
sensitivity,
|
||||
new double[]{0, 20000},//meh
|
||||
gain);
|
||||
|
||||
long timeMillis= (long) PamUtils.PamCalendar.excelSerialtoMillis(importData.get(i).get(0));
|
||||
hydrophone.setTimeMillis(timeMillis);
|
||||
|
||||
// tempArray.add(importData.get(i).get(0));
|
||||
// tempArray.add(cOordinates[0]);
|
||||
// tempArray.add(cOordinates[1]);
|
||||
// tempArray.add(cOordinates[2]);
|
||||
// tempArray.add(cOordinateErrors[0]);
|
||||
// tempArray.add(cOordinateErrors[1]);
|
||||
// tempArray.add(cOordinateErrors[2]);
|
||||
//set Streamer ID.
|
||||
tempArray.add((double) defaultStreamerID);
|
||||
// tempArray.add((double) defaultStreamerID);
|
||||
//set hydrophoneID
|
||||
// System.out.println("Hydrophone iD"+j);
|
||||
|
||||
tempArray.add((double) j);
|
||||
hydrophonesAll.add(tempArray);
|
||||
// tempArray.add((double) j);
|
||||
hydrophonesAll.add(hydrophone);
|
||||
// System.out.println("TempArray: "+tempArray);
|
||||
|
||||
}
|
||||
@ -179,10 +210,64 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
|
||||
|
||||
|
||||
|
||||
private ArrayList<ArrayList<Double>> importPositionsFromMatlab(
|
||||
/**
|
||||
* Import the hydrophone positions from a MATLAB mat file.
|
||||
* @param filePath - the file path.
|
||||
* @return an array of hydrophones.
|
||||
*/
|
||||
private static ArrayList<Hydrophone> importPositionsFromMatlab(
|
||||
String filePath) {
|
||||
// TODO- needs to be implemented.
|
||||
|
||||
try {
|
||||
|
||||
ArrayList<Hydrophone> hydrophones = new ArrayList<Hydrophone>();
|
||||
Mat5File mat5 = Mat5.readFromFile(filePath);
|
||||
Struct structArray = mat5.getArray("array_dimensions");
|
||||
|
||||
double sensitivity=ArrayManager.DEFAULT_HYDROPHONE_SENSITIVITY;
|
||||
double gain=ArrayManager.DEFAULT_PREAMP_GAIN;
|
||||
|
||||
Matrix posStruct;
|
||||
Matrix errStruct;
|
||||
Matrix datetime;
|
||||
// System.out.println("Number of structures: " + structArray.getNumElements());
|
||||
|
||||
Hydrophone hydrophone;
|
||||
for (int i=0; i<structArray.getNumElements(); i++) {
|
||||
|
||||
//hydrophones in channel order.
|
||||
posStruct= structArray.getMatrix("hydrophones", i);
|
||||
|
||||
//errors in channel order
|
||||
errStruct= structArray.getMatrix("hydrophone_errors", i);
|
||||
|
||||
//channels
|
||||
datetime = structArray.getMatrix("datetime", i);
|
||||
|
||||
if (posStruct.getNumElements()<=0) {
|
||||
continue;
|
||||
}
|
||||
for (int j=0; j<posStruct.getNumRows(); j++) {
|
||||
hydrophone =new Hydrophone(j,
|
||||
posStruct.getDouble(j, 0), posStruct.getDouble(j, 1),posStruct.getDouble(j, 2),
|
||||
errStruct.getDouble(j, 0), errStruct.getDouble(j, 1),errStruct.getDouble(j, 2),
|
||||
"Unknown",
|
||||
sensitivity,
|
||||
new double[]{0, 20000},//meh
|
||||
gain);
|
||||
hydrophone.setTimeMillis(PamUtils.PamCalendar.dateNumtoMillis(datetime.getDouble(0)));
|
||||
|
||||
hydrophones.add(hydrophone);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return hydrophones;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -192,7 +277,7 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDataFormatOK(ArrayList<Double> dataLine) {
|
||||
public boolean isDataFormatOK(Hydrophone hydrophone) {
|
||||
// TODO might need to put some extra bits and bobs here eventually.
|
||||
return true;
|
||||
}
|
||||
@ -201,21 +286,21 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
* For hydrophone data imported [0]=timeMilliss [1]=x [2]=y [3]=z [4]=xErr [5]=yErr [6]=zErr [7]=streamerId [8]=hydrophoneId [9]=sensitivity [10]=gain
|
||||
*/
|
||||
@Override
|
||||
public PamDataUnit createDataUnit(ArrayList<Double> dataLine) {
|
||||
public PamDataUnit createDataUnit(Hydrophone hydrophone) {
|
||||
|
||||
double sensitivity=ArrayManager.DEFAULT_HYDROPHONE_SENSITIVITY;
|
||||
double gain=ArrayManager.DEFAULT_PREAMP_GAIN;
|
||||
if (dataLine.size()==10) {
|
||||
gain=dataLine.get(10);
|
||||
sensitivity=dataLine.get(9);
|
||||
}
|
||||
double[] bandwidth={0, 20000};
|
||||
|
||||
Hydrophone hydrophone=new Hydrophone(dataLine.get(8).intValue(), dataLine.get(1), dataLine.get(2), dataLine.get(3), dataLine.get(4),dataLine.get(5), dataLine.get(6), "Unknown", sensitivity,
|
||||
bandwidth, gain);
|
||||
//need to convert from excel serial to millis.
|
||||
long timeMillis= (long) PamUtils.PamCalendar.excelSerialtoMillis(dataLine.get(0));
|
||||
hydrophone.setTimeMillis(timeMillis);
|
||||
// double sensitivity=ArrayManager.DEFAULT_HYDROPHONE_SENSITIVITY;
|
||||
// double gain=ArrayManager.DEFAULT_PREAMP_GAIN;
|
||||
// if (dataLine.size()==10) {
|
||||
// gain=dataLine.get(10);
|
||||
// sensitivity=dataLine.get(9);
|
||||
// }
|
||||
// double[] bandwidth={0, 20000};
|
||||
//
|
||||
// Hydrophone hydrophone=new Hydrophone(dataLine.get(8).intValue(), dataLine.get(1), dataLine.get(2), dataLine.get(3), dataLine.get(4),dataLine.get(5), dataLine.get(6), "Unknown", sensitivity,
|
||||
// bandwidth, gain);
|
||||
// //need to convert from excel serial to millis.
|
||||
// long timeMillis= (long) PamUtils.PamCalendar.excelSerialtoMillis(dataLine.get(0));
|
||||
// hydrophone.setTimeMillis(timeMillis);
|
||||
HydrophoneDataUnit hydrophoneDataUnit=new HydrophoneDataUnit(hydrophone);
|
||||
return hydrophoneDataUnit;
|
||||
|
||||
@ -231,4 +316,13 @@ public class HydrophoneImport extends DataImport<ArrayList<Double>>{
|
||||
return "Hydrophone Units";
|
||||
}
|
||||
|
||||
public static void main(String [] args) {
|
||||
String file = "/Users/au671271/Desktop/test_array_data.mat";
|
||||
ArrayList<Hydrophone> data = importPositionsFromMatlab(file);
|
||||
|
||||
System.out.println("Impotred data size: " + data.size());
|
||||
System.out.println(data.get(0));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
586
src/Array/layoutFX/Array3DPane.java
Normal file
586
src/Array/layoutFX/Array3DPane.java
Normal file
@ -0,0 +1,586 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.fxyz3d.geometry.Point3D;
|
||||
import org.fxyz3d.shapes.composites.PolyLine3D;
|
||||
|
||||
import Array.Hydrophone;
|
||||
import Array.PamArray;
|
||||
import Array.Streamer;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.AmbientLight;
|
||||
import javafx.scene.DepthTest;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.SceneAntialiasing;
|
||||
import javafx.scene.SubScene;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.scene.input.PickResult;
|
||||
import javafx.scene.input.ScrollEvent;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.PhongMaterial;
|
||||
import javafx.scene.shape.Box;
|
||||
import javafx.scene.shape.Shape3D;
|
||||
import javafx.scene.shape.Sphere;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
/**
|
||||
* Create a 3D visualisation of the array.
|
||||
* <p>
|
||||
PAMGUARD co-rdinate system is
|
||||
* <p>
|
||||
* x points right
|
||||
* <p>
|
||||
* y points north or into the screen
|
||||
* <p>
|
||||
* z is height and points up
|
||||
* <p><p>
|
||||
* This is different from the JavAFX 3D system in which
|
||||
* <p>
|
||||
* x points right
|
||||
* <p>
|
||||
* y points down
|
||||
* <p>
|
||||
* z points into the screen
|
||||
* <p>
|
||||
* Thus the source code for this class is a little bit more complex. By convention the co-ordinate system is only changed for display purposes and remains
|
||||
* in PAMGUARD format throughout the rest of code.
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class Array3DPane extends PamBorderPane {
|
||||
|
||||
public static final Color DEFAULT_HYDRO_COL = Color.RED;
|
||||
|
||||
// private static final Color DEFAULT_SENSOR_COL = Color.LIMEGREEN;
|
||||
|
||||
private double scaleFactor=20;
|
||||
|
||||
private double axisSize=10*scaleFactor;
|
||||
|
||||
//keep track of mouse positions
|
||||
double mousePosX;
|
||||
double mousePosY;
|
||||
double mouseOldX;
|
||||
double mouseOldY;
|
||||
double mouseDeltaX;
|
||||
double mouseDeltaY;
|
||||
|
||||
/**
|
||||
* This is the group which rotates
|
||||
*/
|
||||
Group root3D;
|
||||
|
||||
/**
|
||||
* Group which holds array shapes.
|
||||
*/
|
||||
Group arrayGroup;
|
||||
|
||||
/**
|
||||
* Group which holds axis and other non changing bits.
|
||||
*/
|
||||
Group axisGroup;
|
||||
|
||||
/**
|
||||
* The camera transforms
|
||||
*/
|
||||
private Rotate rotateY;
|
||||
private Rotate rotateX;
|
||||
private Translate translate;
|
||||
|
||||
/**
|
||||
* The size of the hydrophone for the 3D display.
|
||||
*/
|
||||
private double hydrophoneSize = 0.5;
|
||||
|
||||
/**
|
||||
* Holds a list of hydrophone spheres
|
||||
*/
|
||||
private ArrayList<HydrophoneSphere> hydrophonesSpheres = new ArrayList<HydrophoneSphere>();
|
||||
|
||||
/**
|
||||
* Allow rotation
|
||||
*/
|
||||
private boolean allowRotate = true;
|
||||
|
||||
private Text xText;
|
||||
|
||||
private Text yText;
|
||||
|
||||
private Text zText;
|
||||
|
||||
private Box yAxis;
|
||||
|
||||
private Shape3D ySphere;
|
||||
|
||||
|
||||
public Array3DPane(){
|
||||
|
||||
// Create and position camera
|
||||
PerspectiveCamera camera = new PerspectiveCamera(true);
|
||||
camera.setFarClip(20000);
|
||||
camera.setNearClip(0.1);
|
||||
// camera.setDepthTest(DepthTest.ENABLE);
|
||||
camera.getTransforms().addAll (
|
||||
rotateY=new Rotate(-45, Rotate.Y_AXIS),
|
||||
rotateX=new Rotate(-45, Rotate.X_AXIS),
|
||||
translate=new Translate(0, 0, -2000));
|
||||
|
||||
//create main 3D group
|
||||
root3D=new Group();
|
||||
axisGroup=buildAxes(axisSize); //create axis group
|
||||
arrayGroup=new Group();
|
||||
|
||||
root3D.getChildren().add(arrayGroup);
|
||||
root3D.getChildren().add(axisGroup);
|
||||
|
||||
|
||||
AmbientLight light = new AmbientLight();
|
||||
light.setColor(Color.WHITE);
|
||||
Group lightGroup = new Group();
|
||||
lightGroup.getChildren().add(light);
|
||||
root3D.getChildren().add(lightGroup);
|
||||
|
||||
//Use a SubScene to mix 3D and 2D stuff.
|
||||
//note- make sure depth buffer in sub scene is enabled.
|
||||
SubScene subScene = new SubScene(root3D, 500,400, true, SceneAntialiasing.BALANCED);
|
||||
subScene.widthProperty().bind(this.widthProperty());
|
||||
subScene.heightProperty().bind(this.heightProperty());
|
||||
subScene.setDepthTest(DepthTest.ENABLE);
|
||||
|
||||
subScene.setOnMouseClicked((MouseEvent me) -> {
|
||||
mousePosX = me.getSceneX();
|
||||
mousePosY = me.getSceneY();
|
||||
PickResult pr = me.getPickResult();
|
||||
// System.out.println("Picked something sphere: " + pr);
|
||||
|
||||
//clear selected radius
|
||||
for (HydrophoneSphere sphere : hydrophonesSpheres) {
|
||||
sphere.setRadius(hydrophoneSize*scaleFactor);
|
||||
}
|
||||
|
||||
if(pr!=null && pr.getIntersectedNode() != null && pr.getIntersectedNode() instanceof Sphere){
|
||||
|
||||
//make the selected sphere slightly larger
|
||||
HydrophoneSphere s = (HydrophoneSphere) pr.getIntersectedNode();
|
||||
s.setRadius(hydrophoneSize*scaleFactor*1.2);
|
||||
|
||||
hydrophoneSelected(s.getHydrophone());
|
||||
|
||||
// System.out.println("Picked a sphere: " + pr);
|
||||
// distance=pr.getIntersectedDistance();
|
||||
// s = (Sphere) pr.getIntersectedNode();
|
||||
// isPicking=true;
|
||||
// vecIni = unProjectDirection(mousePosX, mousePosY, scene.getWidth(),scene.getHeight());
|
||||
}
|
||||
});
|
||||
|
||||
//note the fill is actually quite important because if you don't have it mouse rotations etc
|
||||
//onyl work if you select a 3D shape
|
||||
subScene.setFill(Color.TRANSPARENT);
|
||||
subScene.setCamera(camera);
|
||||
|
||||
//handle mouse events for sub scene
|
||||
handleMouse(subScene);
|
||||
|
||||
resetView();
|
||||
|
||||
//create new group to add sub scene to
|
||||
Group group = new Group();
|
||||
group.getChildren().add(subScene);
|
||||
|
||||
//add group to window.
|
||||
this.setCenter(group);
|
||||
this.setDepthTest(DepthTest.ENABLE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever a hydrophone is selected.
|
||||
* @param hydrophone - the selected hydrophone.
|
||||
*/
|
||||
public void hydrophoneSelected(Hydrophone hydrophone) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a 3D axis with default colours set.
|
||||
* @param- size of the axis
|
||||
*/
|
||||
public Group buildAxes(double axisSize) {
|
||||
return buildAxes( axisSize,Color.RED, Color.RED,
|
||||
Color.GREEN, Color.GREEN,
|
||||
Color.BLUE, Color.BLUE,
|
||||
Color.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a 3D axis.
|
||||
* @param- size of the axis
|
||||
*/
|
||||
public Group buildAxes(double axisSize, Color xAxisDiffuse, Color xAxisSpectacular,
|
||||
Color yAxisDiffuse, Color yAxisSpectacular,
|
||||
Color zAxisDiffuse, Color zAxisSpectacular,
|
||||
Color textColour) {
|
||||
|
||||
Group axisGroup=new Group();
|
||||
|
||||
double length = 2d*axisSize;
|
||||
double width = axisSize/100d;
|
||||
double radius = 2d*axisSize/100d;
|
||||
|
||||
|
||||
final PhongMaterial redMaterial = new PhongMaterial();
|
||||
redMaterial.setDiffuseColor(xAxisDiffuse);
|
||||
redMaterial.setSpecularColor(xAxisSpectacular);
|
||||
final PhongMaterial greenMaterial = new PhongMaterial();
|
||||
greenMaterial.setDiffuseColor(yAxisDiffuse);
|
||||
greenMaterial.setSpecularColor( yAxisSpectacular);
|
||||
final PhongMaterial blueMaterial = new PhongMaterial();
|
||||
blueMaterial.setDiffuseColor(zAxisDiffuse);
|
||||
blueMaterial.setSpecularColor(zAxisSpectacular);
|
||||
|
||||
xText=new Text("x");
|
||||
xText.setStyle("-fx-font: 20px Tahoma; -fx-fill: white;");
|
||||
xText.setFill(textColour);
|
||||
xText.setStroke(textColour);
|
||||
|
||||
yText=new Text("z");
|
||||
yText.setStyle("-fx-font: 20px Tahoma; -fx-fill: white;");
|
||||
yText.setFill(textColour);
|
||||
yText.setStroke(textColour);
|
||||
|
||||
zText=new Text("y");
|
||||
zText.setStyle("-fx-font: 20px Tahoma; -fx-fill: white;");
|
||||
zText.setFill(textColour);
|
||||
zText.setStroke(textColour);
|
||||
|
||||
xText.setTranslateX(axisSize+5);
|
||||
xText.setTranslateZ(1); //dunno why but shifting a little in z is required to see colour
|
||||
|
||||
yText.setTranslateY(-(axisSize+5));
|
||||
yText.setTranslateZ(1); //dunno why but shifting a little in z is required to see colour
|
||||
|
||||
zText.setTranslateZ(axisSize+5);
|
||||
|
||||
Sphere xSphere = new Sphere(radius);
|
||||
ySphere = new Sphere(radius);
|
||||
Sphere zSphere = new Sphere(radius);
|
||||
xSphere.setMaterial(redMaterial);
|
||||
ySphere.setMaterial(greenMaterial);
|
||||
zSphere.setMaterial(blueMaterial);
|
||||
|
||||
xSphere.setTranslateX(axisSize);
|
||||
ySphere.setTranslateY(-axisSize);
|
||||
zSphere.setTranslateZ(axisSize);
|
||||
|
||||
Box xAxis = new Box(length, width, width);
|
||||
yAxis = new Box(width, length, width);
|
||||
Box zAxis = new Box(width, width, length);
|
||||
xAxis.setMaterial(redMaterial);
|
||||
yAxis.setMaterial(greenMaterial);
|
||||
zAxis.setMaterial(blueMaterial);
|
||||
|
||||
axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
|
||||
axisGroup.getChildren().addAll(xText, yText, zText);
|
||||
axisGroup.getChildren().addAll(xSphere, ySphere, zSphere);
|
||||
|
||||
|
||||
return axisGroup;
|
||||
}
|
||||
|
||||
|
||||
private void handleMouse(SubScene scene) {
|
||||
|
||||
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
|
||||
|
||||
@Override public void handle(MouseEvent me) {
|
||||
mousePosX = me.getSceneX();
|
||||
mousePosY = me.getSceneY();
|
||||
mouseOldX = me.getSceneX();
|
||||
mouseOldY = me.getSceneY();
|
||||
}
|
||||
});
|
||||
|
||||
scene.setOnScroll(new EventHandler<ScrollEvent>() {
|
||||
@Override public void handle(ScrollEvent event) {
|
||||
// System.out.println("Scroll Event: "+event.getDeltaX() + " "+event.getDeltaY());
|
||||
translate.setZ(translate.getZ()+ event.getDeltaY() *0.001*translate.getZ()); // +
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(MouseEvent me) {
|
||||
mouseOldX = mousePosX;
|
||||
mouseOldY = mousePosY;
|
||||
mousePosX = me.getSceneX();
|
||||
mousePosY = me.getSceneY();
|
||||
mouseDeltaX = (mousePosX - mouseOldX);
|
||||
mouseDeltaY = (mousePosY - mouseOldY);
|
||||
|
||||
double modifier = 1.0;
|
||||
double modifierFactor = 0.1;
|
||||
|
||||
if (me.isControlDown()) {
|
||||
modifier = 0.1;
|
||||
}
|
||||
if (me.isShiftDown()) {
|
||||
modifier = 10.0;
|
||||
}
|
||||
if (me.isPrimaryButtonDown() && allowRotate) {
|
||||
rotateY.setAngle(rotateY.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0); // +
|
||||
rotateX.setAngle(rotateX.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0); // -
|
||||
|
||||
// System.out.println("Rotation: x: " + rotateX.getAngle() + " y: " + rotateY.getAngle());
|
||||
}
|
||||
if (me.isSecondaryButtonDown()) {
|
||||
translate.setX(translate.getX() -mouseDeltaX * modifierFactor * modifier * 5);
|
||||
translate.setY(translate.getY() - mouseDeltaY * modifierFactor * modifier * 5); // +
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the hydrophone array.
|
||||
* @param array - the hydrophone array to draw.
|
||||
*/
|
||||
public void drawArray(PamArray array) {
|
||||
|
||||
// System.out.println("DRAW ARRAY: " + array);
|
||||
|
||||
//clear the array
|
||||
arrayGroup.getChildren().removeAll(arrayGroup.getChildren());
|
||||
|
||||
ArrayList<Hydrophone> hydrophones = array.getHydrophoneArray();
|
||||
|
||||
//draw hydrophones
|
||||
HydrophoneSphere sphere;
|
||||
Streamer streamer;
|
||||
hydrophonesSpheres.clear();
|
||||
for (int i=0; i<hydrophones.size(); i++){
|
||||
|
||||
//get the streamer for the hydrophone
|
||||
streamer = array.getStreamer(hydrophones.get(i).getStreamerId());
|
||||
|
||||
double x = (hydrophones.get(i).getX() + streamer.getCoordinate(0));
|
||||
double y = (hydrophones.get(i).getY() + streamer.getCoordinate(1));
|
||||
double z = -(hydrophones.get(i).getZ() + streamer.getCoordinate(2));
|
||||
|
||||
sphere=new HydrophoneSphere(hydrophoneSize*scaleFactor);
|
||||
sphere.setTranslateX(x*scaleFactor);
|
||||
sphere.setTranslateY(z*scaleFactor);
|
||||
sphere.setTranslateZ(y*scaleFactor);
|
||||
|
||||
Color col = Color.RED;
|
||||
|
||||
final PhongMaterial aMaterial = new PhongMaterial();
|
||||
aMaterial.setDiffuseColor(col);
|
||||
aMaterial.setSpecularColor(col.brighter());
|
||||
sphere.setMaterial(aMaterial);
|
||||
sphere.setHydrophone(hydrophones.get(i));
|
||||
|
||||
// System.out.println("Add hydrophone: " + x + " " + y + " " +z);
|
||||
|
||||
hydrophonesSpheres.add(sphere);
|
||||
arrayGroup.getChildren().add(sphere);
|
||||
|
||||
ArrayList<Point3D> streamerPoints=new ArrayList<Point3D>();
|
||||
//now plot a line from the streamer to the hydrophone
|
||||
Point3D newPoint;
|
||||
|
||||
newPoint=new Point3D(x*scaleFactor, z*scaleFactor, y*scaleFactor);
|
||||
streamerPoints.add(newPoint);
|
||||
|
||||
newPoint =new Point3D(streamer.getCoordinate(0)*scaleFactor, -streamer.getCoordinate(2)*scaleFactor, streamer.getCoordinate(1)*scaleFactor);
|
||||
streamerPoints.add(newPoint);
|
||||
|
||||
//System.out.println("Streamer points: " + streamerPoints.size());
|
||||
|
||||
PolyLine3D polyLine3D=new PolyLine3D(streamerPoints, 4f, Color.DODGERBLUE);
|
||||
arrayGroup.getChildren().add(polyLine3D);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class HydrophoneSphere extends Sphere {
|
||||
|
||||
Hydrophone hydrophone;
|
||||
|
||||
public Hydrophone getHydrophone() {
|
||||
return hydrophone;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setHydrophone(Hydrophone hydrophone) {
|
||||
this.hydrophone = hydrophone;
|
||||
}
|
||||
|
||||
public HydrophoneSphere() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HydrophoneSphere(double radius) {
|
||||
super(radius);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pane to show hydrophones in 2D or 3D.
|
||||
* @param set3D - true to set to 3D
|
||||
*/
|
||||
public void set3D(boolean set3D) {
|
||||
|
||||
double textRotation =0;
|
||||
|
||||
if (set3D) {
|
||||
allowRotate=true;
|
||||
xText.setRotate(0);
|
||||
rotateY.setAngle(-45);
|
||||
rotateX.setAngle(-45);
|
||||
}
|
||||
else {
|
||||
allowRotate=false;
|
||||
rotateY.setAngle(0);
|
||||
rotateX.setAngle(270);
|
||||
textRotation=-90;
|
||||
}
|
||||
|
||||
//confusing because the yaxis is the z axis in JavaFX...
|
||||
yText.setVisible(set3D);
|
||||
yAxis.setVisible(set3D);
|
||||
ySphere.setVisible(set3D);
|
||||
|
||||
|
||||
xText.setRotate(textRotation);
|
||||
xText.setRotationAxis(new javafx.geometry.Point3D(1,0,0));
|
||||
|
||||
yText.setRotationAxis(new javafx.geometry.Point3D(1,0,0));
|
||||
yText.setRotate(textRotation);
|
||||
|
||||
zText.setRotationAxis(new javafx.geometry.Point3D(1,0,0));
|
||||
zText.setRotate(textRotation);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset to the defulat view.
|
||||
*/
|
||||
public void resetView() {
|
||||
|
||||
translate.setX(0);
|
||||
translate.setY(0);
|
||||
translate.setZ( -2000);
|
||||
|
||||
if (allowRotate) {
|
||||
rotateY.setAngle(-45);
|
||||
rotateX.setAngle(-45);
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Draw the entire array
|
||||
// * @param pos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.
|
||||
// */
|
||||
// public void drawArrays(ArrayList<ArrayList<ArrayPos>> pos){
|
||||
//
|
||||
// arrayGroup.getChildren().removeAll(arrayGroup.getChildren());
|
||||
//
|
||||
// if (pos==null){
|
||||
// System.err.println("Array3DPane: Hydrophone positions are null");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// for (int i=0; i< pos.size(); i++){
|
||||
// for (int j=0; j<pos.get(i).size(); j++){
|
||||
// drawArray(pos.get(i).get(j));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //System.out.println("Draw 3D hydrophone array");
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Draw an array.
|
||||
// * @param arrayPos - hydrophone and streamer positions in the same co-ordinate frame as the reference frame.
|
||||
// */
|
||||
// private void drawArray(ArrayPos arrayPos){
|
||||
//
|
||||
// final PhongMaterial redMaterial = new PhongMaterial();
|
||||
// redMaterial.setDiffuseColor(DEFAULT_HYDRO_COL);
|
||||
// redMaterial.setSpecularColor(DEFAULT_HYDRO_COL.brighter());
|
||||
//
|
||||
// final PhongMaterial greenMaterial = new PhongMaterial();
|
||||
// greenMaterial.setDiffuseColor(DEFAULT_SENSOR_COL);
|
||||
// greenMaterial.setSpecularColor(DEFAULT_SENSOR_COL.brighter());
|
||||
//
|
||||
// //draw hydrophones
|
||||
// Sphere sphere;
|
||||
// for (int i=0; i<arrayPos.getTransformHydrophonePos().size(); i++){
|
||||
// sphere=new Sphere(settings.hydrophoneSize*scaleFactor);
|
||||
// sphere.setTranslateX(arrayPos.getTransformHydrophonePos().get(i)[0]*scaleFactor);
|
||||
// sphere.setTranslateY(-arrayPos.getTransformHydrophonePos().get(i)[2]*scaleFactor);
|
||||
// sphere.setTranslateZ(arrayPos.getTransformHydrophonePos().get(i)[1]*scaleFactor);
|
||||
//
|
||||
// Color hydroCol = settings.hydrophoneColours[arrayPos.getHArray().getHydrophones().get(i).channel.get()];
|
||||
//
|
||||
// if (hydroCol == null) {
|
||||
// sphere.setMaterial(redMaterial);
|
||||
// }
|
||||
// else {
|
||||
// final PhongMaterial aMaterial = new PhongMaterial();
|
||||
// aMaterial.setDiffuseColor(hydroCol);
|
||||
// aMaterial.setSpecularColor(hydroCol.brighter());
|
||||
// sphere.setMaterial(aMaterial);
|
||||
//
|
||||
// }
|
||||
// arrayGroup.getChildren().add(sphere);
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// //draw streamer
|
||||
// PolyLine3D polyLine3D;
|
||||
// ArrayList<Point3D> streamerPoints;
|
||||
//
|
||||
// for (int i=0; i<arrayPos.getTransformStreamerPositions().size(); i++){
|
||||
// if (arrayPos.getTransformStreamerPositions().get(i)==null) return;
|
||||
// streamerPoints=new ArrayList<Point3D>();
|
||||
// for (int j=0; j<arrayPos.getTransformStreamerPositions().get(i).size(); j++){
|
||||
//
|
||||
// //TODO- use cylinder for line
|
||||
// // Cylinder cylinder=createConnection(arrayPos.getTransformStreamerPositions().get(i).get(j).multiply(scaleFactor), arrayPos.getTransformStreamerPositions().get(i).get(j+1).multiply(scaleFactor),0.2*scaleFactor);
|
||||
// // arrayGroup.getChildren().add(cylinder);
|
||||
//
|
||||
// //need to convert to fxyz 3D point - stupid but no work around.
|
||||
// Point3D newPoint=new Point3D((float) (arrayPos.getTransformStreamerPositions().get(i).get(j).getX()*scaleFactor),
|
||||
// (float) (-arrayPos.getTransformStreamerPositions().get(i).get(j).getZ()*scaleFactor), (float) (arrayPos.getTransformStreamerPositions().get(i).get(j).getY()*scaleFactor));
|
||||
// streamerPoints.add(newPoint);
|
||||
// }
|
||||
// polyLine3D=new PolyLine3D(streamerPoints, 4, Color.BLUE);
|
||||
// arrayGroup.getChildren().add(polyLine3D);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
15
src/Array/layoutFX/ArrayChangeListener.java
Normal file
15
src/Array/layoutFX/ArrayChangeListener.java
Normal file
@ -0,0 +1,15 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
public interface ArrayChangeListener {
|
||||
|
||||
int STREAMER_CHANGE = 0;
|
||||
int HYDROPHONE_CHANGE = 1;
|
||||
|
||||
/**
|
||||
* Called whenever a hydrophone or streamer changes.
|
||||
* @param type - the type of change e.g. ArrayChangeListener.HYDROPHONE_CHANGE
|
||||
* @param changedObject - the changed object - hydrophone or streamer property.
|
||||
*/
|
||||
public void arrayChanged(int type, Object changedObject);
|
||||
|
||||
}
|
@ -7,6 +7,7 @@ import pamViewFX.PamControlledGUIFX;
|
||||
|
||||
/**
|
||||
* JavaFX UI bits of the Array Manager.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
@ -30,12 +31,17 @@ public class ArrayGUIFX extends PamControlledGUIFX {
|
||||
if (arraySettingsPane==null) {
|
||||
arraySettingsPane= new ArraySettingsPane();
|
||||
}
|
||||
System.out.println("The current array is "+ arrayManager.getCurrentArray());
|
||||
arraySettingsPane.setParams(arrayManager.getCurrentArray());
|
||||
return arraySettingsPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateParams() {
|
||||
System.out.println("The current array is "+ arrayManager.getCurrentArray());
|
||||
|
||||
PamArray newParams=arraySettingsPane.getParams(arrayManager.getCurrentArray());
|
||||
|
||||
if (newParams!=null) arrayManager.setCurrentArray(newParams);
|
||||
//setup the controlled unit.
|
||||
arrayManager.setupControlledUnit();
|
||||
|
@ -1,39 +1,385 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.controlsfx.control.SegmentedButton;
|
||||
|
||||
import Array.ArrayManager;
|
||||
import Array.Hydrophone;
|
||||
import Array.PamArray;
|
||||
import PamController.PamController;
|
||||
import PamController.SettingsPane;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.ToggleButton;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.FileChooser.ExtensionFilter;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxGlyphs.PamGlyphDude;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamButton;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
|
||||
/**
|
||||
* The main settings pane for settings up a hydrophone array.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
* @param <FlipPane>
|
||||
*
|
||||
*/
|
||||
public class ArraySettingsPane extends SettingsPane<PamArray >{
|
||||
|
||||
/**
|
||||
* Minimum size of the 3D pane.
|
||||
*/
|
||||
private static final double MIN_3D_WIDTH = 450;
|
||||
|
||||
/**
|
||||
* Minimum height of the 3D pane.
|
||||
*/
|
||||
private static final double MIN_3D_HEIGHT = 600;
|
||||
|
||||
/**
|
||||
* Pane for adding or removing streamers.
|
||||
*/
|
||||
private StreamersPane streamerPane;
|
||||
|
||||
private PamBorderPane mainPane;
|
||||
|
||||
/**
|
||||
* Pane for adding or removing hydrophones.
|
||||
*/
|
||||
private HydrophonesPane hydrophonePane;
|
||||
|
||||
// private Pane holder;
|
||||
|
||||
private Label hydrophoneLabel;
|
||||
|
||||
/**
|
||||
* Pane which shows a 3D representation of the hydrophone array.
|
||||
*/
|
||||
private Array3DPane array3DPane;
|
||||
|
||||
private PropogationPane propogationPane;
|
||||
|
||||
private Label recivierDiagramLabel;
|
||||
|
||||
/**
|
||||
* Pane with controls to change speed of sound.
|
||||
*/
|
||||
private SettingsPane<PamArray> environmentalPane;
|
||||
|
||||
private FileChooser fileChooser;
|
||||
|
||||
//a copy of the current array
|
||||
private PamArray currentArray;
|
||||
|
||||
public ArraySettingsPane() {
|
||||
super(null);
|
||||
// TODO Auto-generated constructor stub
|
||||
|
||||
mainPane=new PamBorderPane();
|
||||
|
||||
mainPane.setCenter(createArrayPane());
|
||||
// mainPane.setStyle("-fx-background-color: red;");
|
||||
mainPane.setMaxWidth(Double.MAX_VALUE);
|
||||
mainPane.setMinWidth(1100);
|
||||
mainPane.setStyle("-fx-padding: 0,0,0,0");
|
||||
|
||||
|
||||
recivierDiagramLabel = new Label("Hydrophone Diagram");
|
||||
PamGuiManagerFX.titleFont1style(recivierDiagramLabel);
|
||||
recivierDiagramLabel.setPadding(new Insets(5,5,5,5));
|
||||
|
||||
Label environmentLabel = new Label("Environment");
|
||||
PamGuiManagerFX.titleFont1style(environmentLabel);
|
||||
environmentLabel.setPadding(new Insets(0,0,5,0)); //little more space under this label
|
||||
|
||||
environmentalPane = createEnvironmentPane();
|
||||
|
||||
PamVBox rightPane = new PamVBox();
|
||||
rightPane.setSpacing(5);
|
||||
|
||||
Pane hydrophone3DPane = create3DPane();
|
||||
rightPane.getChildren().addAll(recivierDiagramLabel, hydrophone3DPane, environmentLabel, new PamBorderPane(environmentalPane.getContentNode()));
|
||||
VBox.setVgrow(hydrophone3DPane, Priority.ALWAYS);
|
||||
|
||||
mainPane.setRight(rightPane);
|
||||
|
||||
// streamerPane.getStreamerTable().getItems().addListener((ListChangeListener<? super StreamerProperty>) c->{
|
||||
// //the streamer table has changed and so the streamer needs changed
|
||||
// System.out.println("Streamer Changed!!!");
|
||||
// });
|
||||
|
||||
streamerPane.addStreamerListener((x,y)->{
|
||||
PamArray array = getParams(new PamArray("temp_array: ", null)) ;
|
||||
System.out.println("Streamer changed!");
|
||||
array3DPane.drawArray(array);
|
||||
});
|
||||
|
||||
hydrophonePane.addStreamerListener((x,y)->{
|
||||
PamArray array = getParams(new PamArray("temp_array: ", null)) ;
|
||||
System.out.println("Hydrophone changed!" + array.getHydrophoneCount());
|
||||
array3DPane.drawArray(array);
|
||||
});
|
||||
|
||||
// mainPane.setMinWidth(800);
|
||||
|
||||
// mainPane.setCenter(createArrayPane());
|
||||
//
|
||||
// mainPane.getAdvPane().setCenter(new Label("Advanced Settings"));
|
||||
|
||||
|
||||
// //mainPane.getFront().setStyle("-fx-background-color: grey;");
|
||||
// mainPane.setStyle("-fx-background-color: red;");
|
||||
//
|
||||
// FlipPane aflipPane = new FlipPane();
|
||||
// aflipPane.setStyle("-fx-background-color: red;");
|
||||
//
|
||||
// PamHBox stackPane = new PamHBox();
|
||||
// stackPane.setStyle("-fx-background-color: red;");
|
||||
//
|
||||
// Button button = new Button();
|
||||
// button.setOnAction((action)->{
|
||||
// System.out.println(" 1 " + stackPane.getPadding());
|
||||
// System.out.println(" 2 " +PamBorderPane.getMargin(stackPane));
|
||||
// System.out.println(" 3 " + holder.getPadding());
|
||||
// });
|
||||
//
|
||||
// stackPane.getChildren().add(button);
|
||||
//
|
||||
//
|
||||
// mainPane.setPadding(new Insets(0,0,0,0));
|
||||
|
||||
|
||||
// holder = new StackPane();
|
||||
// holder.getChildren().add(mainPane);
|
||||
// holder.setStyle("-fx-padding: 0,0,0,0");
|
||||
|
||||
}
|
||||
|
||||
private Pane create3DPane() {
|
||||
|
||||
StackPane stackPane = new StackPane();
|
||||
this.array3DPane = new HydrophoneArray3DPane();
|
||||
|
||||
//important because the 3D pane has not default size
|
||||
stackPane.setMinWidth(MIN_3D_WIDTH);
|
||||
stackPane.setMinHeight(MIN_3D_HEIGHT);
|
||||
|
||||
// stackPane.prefHeightProperty().bind(mainPane.heightProperty().subtract(100));
|
||||
|
||||
stackPane.getChildren().add(array3DPane);
|
||||
|
||||
|
||||
//add buttons
|
||||
ToggleButton b1 = new ToggleButton("2D");
|
||||
ToggleButton b2 = new ToggleButton("3D");
|
||||
|
||||
b1.setOnAction((action)->{
|
||||
array3DPane.set3D(false);
|
||||
});
|
||||
|
||||
b2.setOnAction((action)->{
|
||||
array3DPane.set3D(true);
|
||||
});
|
||||
|
||||
|
||||
SegmentedButton segmentedButton = new SegmentedButton();
|
||||
segmentedButton.getButtons().addAll(b1, b2);
|
||||
segmentedButton.setPadding(new Insets(5,5,5,5));
|
||||
segmentedButton.setMinWidth(100);
|
||||
|
||||
StackPane.setAlignment(segmentedButton, Pos.TOP_RIGHT);
|
||||
stackPane.getChildren().add(segmentedButton);
|
||||
|
||||
|
||||
final ContextMenu contextMenu = new ContextMenu();
|
||||
final MenuItem item1 = new MenuItem("Reset");
|
||||
item1.setOnAction((action)->{
|
||||
array3DPane.resetView();
|
||||
});
|
||||
contextMenu.getItems().add(item1);
|
||||
segmentedButton.setContextMenu(contextMenu);
|
||||
|
||||
// stackPane.setOnContextMenuRequested(e ->
|
||||
// contextMenu.show(stackPane, e.getScreenX(), e.getScreenY()));
|
||||
|
||||
|
||||
b2.setSelected(true);
|
||||
|
||||
return stackPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the environment pane.
|
||||
* @return the environment pane.
|
||||
*/
|
||||
private SettingsPane<PamArray> createEnvironmentPane() {
|
||||
this.propogationPane = new PropogationPane();
|
||||
return propogationPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the main pane.
|
||||
* @return the main array pane.
|
||||
*/
|
||||
private Pane createArrayPane() {
|
||||
|
||||
Label arrayLabel = new Label("Array");
|
||||
arrayLabel.setPadding(new Insets(5,5,5,5));
|
||||
PamGuiManagerFX.titleFont1style(arrayLabel);
|
||||
|
||||
//holds the array label and also some button for import and export.
|
||||
PamHBox arrayImportExportBox = new PamHBox();
|
||||
arrayImportExportBox.setSpacing(5);
|
||||
arrayImportExportBox.setAlignment(Pos.CENTER_LEFT);
|
||||
arrayImportExportBox.setPadding(new Insets(5,0,0,0));
|
||||
|
||||
fileChooser = new FileChooser();
|
||||
fileChooser.setTitle("Open Resource File");
|
||||
fileChooser.getExtensionFilters().addAll(
|
||||
new ExtensionFilter("PAMGuard Array Files", "*.paf"));
|
||||
|
||||
PamButton importButton = new PamButton("Import...");
|
||||
importButton.setOnAction((action)->{
|
||||
importArray();
|
||||
});
|
||||
importButton.setGraphic(PamGlyphDude.createPamIcon("mdi2f-file-import", PamGuiManagerFX.iconSize));
|
||||
importButton.setTooltip(new Tooltip("Import array settings from a .pgaf file"));
|
||||
|
||||
PamButton exportButton = new PamButton("Export...");
|
||||
exportButton.setOnAction((action)->{
|
||||
exportArray();
|
||||
});
|
||||
exportButton.setGraphic(PamGlyphDude.createPamIcon("mdi2f-file-export", PamGuiManagerFX.iconSize));
|
||||
exportButton.setTooltip(new Tooltip("Export array settings to a .pgaf file"));
|
||||
|
||||
//balnk region to make it look nicer
|
||||
Region blank = new Region();
|
||||
blank.setPrefWidth(70);
|
||||
|
||||
arrayImportExportBox.getChildren().addAll(importButton, exportButton, blank);
|
||||
|
||||
PamBorderPane titleHolder = new PamBorderPane();
|
||||
titleHolder.setLeft(arrayLabel);
|
||||
titleHolder.setRight(arrayImportExportBox);
|
||||
|
||||
//the streamer pane for changing streamer settings.
|
||||
streamerPane = new StreamersPane();
|
||||
streamerPane.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
hydrophoneLabel = new Label("Hydrophones");
|
||||
PamGuiManagerFX.titleFont1style(hydrophoneLabel);
|
||||
hydrophoneLabel.setPadding(new Insets(5,5,5,5));
|
||||
|
||||
hydrophonePane = new HydrophonesPane();
|
||||
hydrophonePane.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
// PamButton advancedButton = new PamButton();
|
||||
// advancedButton.setOnAction((action)->{
|
||||
// mainPane.flipToBack();
|
||||
// });
|
||||
// advancedButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-cog"));
|
||||
|
||||
// PamHBox advancedPane = new PamHBox();
|
||||
// advancedPane.setSpacing(5);
|
||||
// advancedPane.setAlignment(Pos.CENTER_RIGHT);
|
||||
// advancedPane.getChildren().addAll(new Label("Advanced"), advancedButton);
|
||||
|
||||
PamVBox vBox = new PamVBox();
|
||||
vBox.setSpacing(5);
|
||||
vBox.getChildren().addAll(titleHolder, streamerPane, hydrophoneLabel,
|
||||
hydrophonePane);
|
||||
|
||||
return vBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a file to export array settings to.
|
||||
*/
|
||||
private void exportArray() {
|
||||
File file = fileChooser.showSaveDialog(getFXWindow());
|
||||
if (file==null) return;
|
||||
PamArray pamArray = getParams(new PamArray("saved_array: ", null));
|
||||
boolean isSaved = ArrayManager.saveArrayToFile(pamArray);
|
||||
if (isSaved==false) {
|
||||
PamDialogFX.showError("Unable to save the array file to \n" + file.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select a file to import array settings
|
||||
*/
|
||||
private void importArray() {
|
||||
File file = fileChooser.showOpenDialog(getFXWindow());
|
||||
if (file==null) return;
|
||||
PamArray pamArray = ArrayManager.loadArrayFromFile(file.getPath());
|
||||
this.setParams(pamArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set correct text for the receiver in the current medium (e.g. air or water);
|
||||
*/
|
||||
private void setReceieverLabels() {
|
||||
hydrophonePane.setRecieverLabels();
|
||||
streamerPane.setRecieverLabels();
|
||||
|
||||
hydrophoneLabel.setText(PamController.getInstance().getGlobalMediumManager().getRecieverString(true) + "s");
|
||||
recivierDiagramLabel.setText(PamController.getInstance().getGlobalMediumManager().getRecieverString(true) + " diagram");
|
||||
// if (singleInstance!=null) {
|
||||
// singleInstance.setTitle("Pamguard "+ PamController.getInstance().getGlobalMediumManager().getRecieverString(false) +" array");
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PamArray getParams(PamArray currParams) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
||||
if (currParams==null) currParams = this.currentArray;
|
||||
|
||||
currParams = streamerPane.getParams(currParams);
|
||||
currParams = hydrophonePane.getParams(currParams);
|
||||
currParams.setHydrophoneInterpolation(hydrophonePane.getHydrophoneInterp());
|
||||
currParams = environmentalPane.getParams(currParams);
|
||||
// System.out.println("Array settings pane: No. streamers: " + currParams.getStreamerCount());
|
||||
return currParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(PamArray input) {
|
||||
// TODO Auto-generated method stub
|
||||
this.currentArray = input.clone();
|
||||
// System.out.println("Hydrophone array is: "+ input);
|
||||
setReceieverLabels();
|
||||
hydrophonePane.setParams(input);
|
||||
streamerPane.setParams(input);
|
||||
environmentalPane.setParams(input);
|
||||
|
||||
//draw the array
|
||||
array3DPane.drawArray(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
// TODO Auto-generated method stub
|
||||
return "Array Parameters";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
// TODO Auto-generated method stub
|
||||
return new Label("TODO: The Array Manager needs an FX GUI");
|
||||
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,4 +388,13 @@ public class ArraySettingsPane extends SettingsPane<PamArray >{
|
||||
|
||||
}
|
||||
|
||||
private class HydrophoneArray3DPane extends Array3DPane {
|
||||
|
||||
@Override
|
||||
public void hydrophoneSelected(Hydrophone hydrophone) {
|
||||
hydrophonePane.selectHydrophone(hydrophone);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
58
src/Array/layoutFX/DefaultHydrophone.java
Normal file
58
src/Array/layoutFX/DefaultHydrophone.java
Normal file
@ -0,0 +1,58 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
/**
|
||||
* Default hydrophone parameters.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public enum DefaultHydrophone {
|
||||
|
||||
SoundTrap600HF("SoundTrap 600 HF", -176., 0), SoundTrap300HF("SoundTrap 300 HF", -176., 0), HydroMoth_1_0_0("HydroMoth 1.0.0", -180., 0);
|
||||
|
||||
/**
|
||||
* The name of the hydrophones.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
|
||||
/**
|
||||
* The sensitivity of the hydrophone in dB re 1V/uPa.
|
||||
*/
|
||||
private double sens;
|
||||
|
||||
/**
|
||||
* The gain in dB.
|
||||
*/
|
||||
private double gain;
|
||||
|
||||
/**
|
||||
* The name of the hydrophone.
|
||||
* @param name - the name of the hydrophone.
|
||||
* @param sens - the sensitivity of the hydrophone.
|
||||
* @param gain - the gain of the hydrophone.
|
||||
*/
|
||||
DefaultHydrophone(String name, double sens, double gain) {
|
||||
this.name = name;
|
||||
this.sens = sens;
|
||||
this.gain = gain;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The sensitivity of the hydrophone in dB re 1V/uPa.
|
||||
*/
|
||||
public double getSens() {
|
||||
return sens;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The gain in dB.
|
||||
*/
|
||||
public double getGain() {
|
||||
return gain;
|
||||
}
|
||||
|
||||
|
||||
}
|
116
src/Array/layoutFX/HydrophoneProperty.java
Normal file
116
src/Array/layoutFX/HydrophoneProperty.java
Normal file
@ -0,0 +1,116 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import Array.Hydrophone;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
|
||||
/**
|
||||
* Property class for a hydrophone object.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class HydrophoneProperty {
|
||||
|
||||
SimpleDoubleProperty x = new SimpleDoubleProperty();
|
||||
|
||||
SimpleDoubleProperty y = new SimpleDoubleProperty();
|
||||
|
||||
SimpleDoubleProperty z = new SimpleDoubleProperty();
|
||||
|
||||
SimpleDoubleProperty xErr = new SimpleDoubleProperty();
|
||||
|
||||
SimpleDoubleProperty yErr = new SimpleDoubleProperty();
|
||||
|
||||
SimpleDoubleProperty zErr = new SimpleDoubleProperty();
|
||||
|
||||
SimpleIntegerProperty id = new SimpleIntegerProperty();
|
||||
|
||||
private Hydrophone hydrophone;
|
||||
|
||||
public HydrophoneProperty(Hydrophone hydrophone) {
|
||||
setHydrophone(hydrophone);
|
||||
}
|
||||
|
||||
public void setHydrophone(Hydrophone hydrophone) {
|
||||
this.hydrophone = hydrophone;
|
||||
|
||||
|
||||
x .set(hydrophone.getX());
|
||||
y .set(hydrophone.getY());
|
||||
z .set(hydrophone.getZ());
|
||||
|
||||
xErr .set(hydrophone.getdX());
|
||||
yErr .set(hydrophone.getdY());
|
||||
zErr .set(hydrophone.getdZ());
|
||||
|
||||
id.set(hydrophone.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* The x-coordinate property.
|
||||
* @return the x coordintae property.
|
||||
*/
|
||||
public SimpleDoubleProperty getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* The y-coordinate property.
|
||||
* @return the y coordintae property.
|
||||
*/
|
||||
public SimpleDoubleProperty getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* The z-coordinate property.
|
||||
* @return the z coordintae property.
|
||||
*/
|
||||
public SimpleDoubleProperty getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public SimpleIntegerProperty getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Hydrophone getHydrophone() {
|
||||
//incase table data changes.
|
||||
this.hydrophone.setID(this.id.get());
|
||||
this.hydrophone.setX(x.get());
|
||||
this.hydrophone.setY(y.get());
|
||||
this.hydrophone.setZ(z.get());
|
||||
this.hydrophone.setdX(xErr.get());
|
||||
this.hydrophone.setdY(yErr.get());
|
||||
this.hydrophone.setdZ(xErr.get());
|
||||
|
||||
return hydrophone;
|
||||
}
|
||||
|
||||
/**
|
||||
* The x-coordinate property.
|
||||
* @return the x coordintae property.
|
||||
*/
|
||||
public SimpleDoubleProperty getXErr() {
|
||||
return xErr;
|
||||
}
|
||||
|
||||
/**
|
||||
* The y-coordinate property.
|
||||
* @return the y coordintae property.
|
||||
*/
|
||||
public SimpleDoubleProperty getYErr() {
|
||||
return yErr;
|
||||
}
|
||||
|
||||
/**
|
||||
* The z-coordinate property.
|
||||
* @return the z coordintae property.
|
||||
*/
|
||||
public SimpleDoubleProperty getZErr() {
|
||||
return zErr;
|
||||
}
|
||||
|
||||
}
|
589
src/Array/layoutFX/HydrophoneSettingsPane.java
Normal file
589
src/Array/layoutFX/HydrophoneSettingsPane.java
Normal file
@ -0,0 +1,589 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import Array.Hydrophone;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import Array.PamArray;
|
||||
import Array.Streamer;
|
||||
import PamController.PamController;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Labeled;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Region;
|
||||
import net.synedra.validatorfx.Validator;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxSettingsPanes.DynamicSettingsPane;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamSpinner;
|
||||
import pamViewFX.validator.PamValidator;
|
||||
|
||||
/**
|
||||
* The settings pane for a single hydrophones.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class HydrophoneSettingsPane extends DynamicSettingsPane<Hydrophone> {
|
||||
|
||||
private static final double COLUMN_0_WIDTH = 120;
|
||||
|
||||
|
||||
private final static double MAX_TEXTFIELD_WIDTH = 80;
|
||||
|
||||
/**
|
||||
*
|
||||
* Check inputs in real time
|
||||
*/
|
||||
PamValidator validator = new PamValidator();
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Hydrophone Settings";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paneInitialized() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
private TextField iD;
|
||||
|
||||
private TextField yPos;
|
||||
private TextField xPos;
|
||||
private TextField zPos;
|
||||
|
||||
private TextField yPosErr;
|
||||
private TextField xPosErr;
|
||||
private TextField zPosErr;
|
||||
|
||||
private PamSpinner<Double> hSens;
|
||||
private PamSpinner<Double> preampGain;
|
||||
|
||||
private ComboBox<String> streamers;
|
||||
private ChoiceBox<DefaultHydrophone> defaultArrays;
|
||||
private TextField nameField;
|
||||
|
||||
private PamArray currentArray;
|
||||
|
||||
///Labels which might change name if in air or water (i.e. hydrophone or microphone).
|
||||
|
||||
private Labeled depthLabel;
|
||||
|
||||
private Labeled depthLabel2;
|
||||
|
||||
private Label recieverIDLabel;
|
||||
|
||||
private Label recieverTypeLabel;
|
||||
|
||||
private Label recieverSensLabel;
|
||||
|
||||
private Label dBSensLabel;
|
||||
|
||||
private boolean ressetHydrophoneType = false;
|
||||
|
||||
/**
|
||||
* The main holder pane.
|
||||
*/
|
||||
private PamBorderPane mainPane;
|
||||
|
||||
private InterpChoicePane interpPane;
|
||||
|
||||
private ComboBox<String> defaultHydro;
|
||||
|
||||
//create the dialog
|
||||
public HydrophoneSettingsPane() {
|
||||
super(null);
|
||||
|
||||
PamVBox holderPane = new PamVBox();
|
||||
holderPane.setSpacing(5);
|
||||
|
||||
|
||||
recieverIDLabel = new Label("General");
|
||||
PamGuiManagerFX.titleFont2style(recieverIDLabel);
|
||||
|
||||
Label coOrdLabel = new Label("Coordinates");
|
||||
PamGuiManagerFX.titleFont2style(coOrdLabel);
|
||||
|
||||
Label interpLabel = new Label("Interpolation");
|
||||
PamGuiManagerFX.titleFont2style(interpLabel);
|
||||
|
||||
interpPane = new InterpChoicePane();
|
||||
|
||||
PamHBox interpHolder = new PamHBox();
|
||||
interpHolder.setSpacing(5);
|
||||
interpHolder.setAlignment(Pos.CENTER_LEFT);
|
||||
interpHolder.getChildren().addAll(new Label("Method"), interpPane);
|
||||
|
||||
holderPane.getChildren().addAll(recieverIDLabel, createGeneralPane(), coOrdLabel, createPositionPane(), interpLabel, interpHolder);
|
||||
|
||||
mainPane = new PamBorderPane();
|
||||
mainPane.setCenter(holderPane);
|
||||
}
|
||||
|
||||
//
|
||||
// public Boolean getParams(){
|
||||
// array.nameProperty().setValue(nameField.getText());
|
||||
// array.hArrayTypeProperty().setValue(arrayType.getValue());
|
||||
// try {
|
||||
// array.xPosProperty().setValue(Double.valueOf(xPos.getText()));
|
||||
// array.yPosProperty().setValue(Double.valueOf(yPos.getText()));
|
||||
// array.zPosProperty().setValue(Double.valueOf(zPos.getText()));
|
||||
// }
|
||||
// catch (Exception e){
|
||||
// System.err.println("Invalid field in Array Dialog");
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public void setParams(Hydrophone hydrophone){
|
||||
//
|
||||
// iD.setText(String.format("%d", hydrophone.getID()));
|
||||
// streamers.getItems().clear();
|
||||
//
|
||||
// //set thre text values for the recieevrs.
|
||||
//// setRecieverLabelText();
|
||||
// if (currentArray != null) {
|
||||
// Streamer s;
|
||||
// for (int i = 0; i < currentArray.getNumStreamers(); i++) {
|
||||
// s = currentArray.getStreamer(i);
|
||||
// streamers.getItems().add(String.format("Streamer %d, x=%3.1f", i, s.getX()));
|
||||
// }
|
||||
// }
|
||||
// if (hydrophone.getStreamerId() < currentArray.getNumStreamers()) {
|
||||
// streamers.getSelectionModel().select(hydrophone.getStreamerId());
|
||||
// }
|
||||
// hSens.setText(String.format("%.1f", hydrophone.getSensitivity()-PamController.getInstance().getGlobalMediumManager().getdBSensOffset()));
|
||||
// preampGain.setText(String.format("%.1f", hydrophone.getPreampGain()));
|
||||
// // bandwidth0.setText(String.format("%.1f", hydrophone.getBandwidth()[0]));
|
||||
// // bandwidth1.setText(String.format("%.1f", hydrophone.getBandwidth()[1]));
|
||||
//
|
||||
//
|
||||
//// this.array=array;
|
||||
//// nameField.setText(hydrophone.getType());
|
||||
// parentArrayComboBox.setValue(array.get);
|
||||
//
|
||||
// //attachmentComboBox.setItems(ArrayModelControl.getInstance().getArrays());
|
||||
// parentArrayComboBox.setValue(array.parentHArrayProperty().getValue());
|
||||
//
|
||||
// xPos.setText(Double.toString(hydrophone.);
|
||||
// yPos.setText(Double.toString(array.yPosProperty().get()));
|
||||
// zPos.setText(Double.toString(array.zPosProperty().get()));
|
||||
//
|
||||
// createArrayPane(array);
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Set the receiver labels depending on whether air or water is being used.
|
||||
*/
|
||||
private void setGeneralInfoLabelText() {
|
||||
String recieverString = PamController.getInstance().getGlobalMediumManager().getRecieverString();
|
||||
String dbSens = PamController.getInstance().getGlobalMediumManager().getdBSensString();
|
||||
|
||||
recieverIDLabel.setText(recieverString+ " ID Info");
|
||||
recieverTypeLabel.setText(recieverString + " type ");
|
||||
recieverSensLabel.setText(recieverString + " sens ");
|
||||
dBSensLabel.setText(dbSens);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the receiver labels depending on whether air or water is being used.
|
||||
*/
|
||||
private void setCoordsText() {
|
||||
String recieverDepthString = PamController.getInstance().getGlobalMediumManager().getZString();
|
||||
|
||||
depthLabel.setText(recieverDepthString + " ");
|
||||
|
||||
switch (PamController.getInstance().getGlobalMediumManager().getCurrentMedium()) {
|
||||
case Air:
|
||||
depthLabel2.setText(" m (height above streamer)");
|
||||
break;
|
||||
case Water:
|
||||
depthLabel2.setText(" m (depth below streamer)");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create the pane to allow users to change the position of hydrophones
|
||||
*/
|
||||
private Pane createGeneralPane() {
|
||||
|
||||
PamGridPane mainControls=new PamGridPane();
|
||||
mainControls.setHgap(5);
|
||||
mainControls.setVgap(5);
|
||||
|
||||
|
||||
int gridy = 0;
|
||||
Label parentArrayLabel = new Label("Parent Array");
|
||||
parentArrayLabel.setAlignment(Pos.CENTER_LEFT);
|
||||
mainControls.add(parentArrayLabel, 0, gridy);
|
||||
streamers = new ComboBox<String>();
|
||||
mainControls.add(streamers, 1, gridy);
|
||||
|
||||
gridy++;
|
||||
mainControls.add(recieverTypeLabel = new Label(""), 0, gridy);
|
||||
recieverTypeLabel.setAlignment(Pos.CENTER_LEFT);
|
||||
defaultHydro = new ComboBox<String>();
|
||||
|
||||
for (int i=0; i<DefaultHydrophone.values().length; i++) {
|
||||
defaultHydro.getItems().add(DefaultHydrophone.values()[i].toString());
|
||||
}
|
||||
defaultHydro.getItems().add(0, "User defined");
|
||||
defaultHydro.getSelectionModel().select(0);
|
||||
|
||||
defaultHydro.setOnAction((action)->{
|
||||
//don't want to trigger this if we are programtically setting it back
|
||||
if (defaultHydro.getSelectionModel().getSelectedIndex() <= 0 || ressetHydrophoneType) {
|
||||
//do nothing.
|
||||
return;
|
||||
}
|
||||
ressetHydrophoneType=true;
|
||||
hSens.getValueFactory().setValue(Double.valueOf(DefaultHydrophone.values()[defaultHydro.getSelectionModel().getSelectedIndex()-1].getSens()));
|
||||
preampGain.getValueFactory().setValue(Double.valueOf(DefaultHydrophone.values()[defaultHydro.getSelectionModel().getSelectedIndex()-1].getGain()));
|
||||
ressetHydrophoneType=false;
|
||||
});
|
||||
|
||||
mainControls.add(defaultHydro, 1, gridy);
|
||||
|
||||
gridy++;
|
||||
mainControls.add(recieverSensLabel = new Label(""), 0, gridy);
|
||||
recieverSensLabel.setAlignment(Pos.CENTER_LEFT);
|
||||
hSens = new PamSpinner<Double>(-Double.MAX_VALUE, Double.MAX_VALUE, -200., 1.);
|
||||
hSens.setEditable(true);
|
||||
|
||||
hSens.valueProperty().addListener((obs, oldval, newVal)->{
|
||||
if (ressetHydrophoneType) return;
|
||||
ressetHydrophoneType = true; //make sure we don't trigger anything when resetting the combo box
|
||||
defaultHydro.getSelectionModel().select(0);
|
||||
ressetHydrophoneType= false;
|
||||
});
|
||||
|
||||
mainControls.add(hSens, 1, gridy);
|
||||
mainControls.add(dBSensLabel = new Label(""), 2, gridy);
|
||||
|
||||
|
||||
gridy++;
|
||||
Label preAmpLabel = new Label("Preamplifier gain");
|
||||
mainControls.add(preAmpLabel, 0, gridy);
|
||||
preAmpLabel.setAlignment(Pos.CENTER_LEFT);
|
||||
preampGain =new PamSpinner<Double>(-Double.MAX_VALUE, Double.MAX_VALUE, 0., 1.);
|
||||
preampGain.valueProperty().addListener((obs, oldval, newVal)->{
|
||||
if (ressetHydrophoneType) return;
|
||||
ressetHydrophoneType = true;//make sure we don't trigger anything when resetting the combo box
|
||||
defaultHydro.getSelectionModel().select(0);
|
||||
ressetHydrophoneType= false;
|
||||
});
|
||||
preampGain.setEditable(true);
|
||||
|
||||
|
||||
mainControls.add(preampGain, 1, gridy);
|
||||
mainControls.add(new Label("dB"), 2, gridy);
|
||||
|
||||
ColumnConstraints col1 = new ColumnConstraints();
|
||||
col1.setMinWidth(COLUMN_0_WIDTH);
|
||||
col1.setMaxWidth(COLUMN_0_WIDTH);
|
||||
mainControls.getColumnConstraints().addAll(col1);
|
||||
|
||||
setGeneralInfoLabelText();
|
||||
|
||||
|
||||
return mainControls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the pane to allow users to change the position of hydrophones
|
||||
*/
|
||||
private Pane createPositionPane(){
|
||||
|
||||
double sectionPadding=15;
|
||||
|
||||
|
||||
PamVBox mainControls=new PamVBox();
|
||||
mainControls.setSpacing(5);
|
||||
|
||||
Insets h;
|
||||
|
||||
Label nameLabel=new Label("Array Name");
|
||||
nameLabel.setPadding(new Insets(5,0,0,0));
|
||||
nameField=new TextField();
|
||||
|
||||
//parent array.
|
||||
Label parentArrayLabel=new Label("Parent Streamer");
|
||||
parentArrayLabel.setPadding(new Insets(sectionPadding,0,0,0));
|
||||
|
||||
PamGridPane positionPane = new PamGridPane();
|
||||
positionPane.setHgap(5);
|
||||
positionPane.setVgap(5);
|
||||
|
||||
ColumnConstraints rc = new ColumnConstraints(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, MAX_TEXTFIELD_WIDTH);
|
||||
//this sets all text fields to the correct width - but of naff hack but what grid pane needs to work.
|
||||
for (int i=1; i<5; i++) {
|
||||
positionPane.getColumnConstraints().add(rc);
|
||||
}
|
||||
|
||||
double maxWidth =10;
|
||||
|
||||
xPos=new TextField();
|
||||
xPos.textProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
notifySettingsListeners();
|
||||
});
|
||||
xPos.setMaxWidth(maxWidth);
|
||||
addTextValidator(xPos, "x position", validator);
|
||||
|
||||
yPos=new TextField();
|
||||
yPos.setMaxWidth(maxWidth);
|
||||
addTextValidator(yPos, "y position", validator);
|
||||
yPos.textProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
notifySettingsListeners();
|
||||
});
|
||||
|
||||
zPos=new TextField();
|
||||
zPos.setMaxWidth(maxWidth);
|
||||
zPos.textProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
notifySettingsListeners();
|
||||
});
|
||||
|
||||
addTextValidator(zPos, "z position", validator);
|
||||
depthLabel = new Label("Depth");
|
||||
depthLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
xPosErr=new TextField();
|
||||
xPosErr.setMaxWidth(50);
|
||||
addTextValidator(xPosErr, "x error",validator);
|
||||
yPosErr=new TextField();
|
||||
yPosErr.setMaxWidth(50);
|
||||
addTextValidator(yPosErr, "y error",validator);
|
||||
zPosErr=new TextField();
|
||||
zPosErr.setMaxWidth(50);
|
||||
depthLabel2 = new Label(""); //changes with air or water mode.
|
||||
depthLabel2.setAlignment(Pos.CENTER);
|
||||
addTextValidator(zPosErr, "z error", validator);
|
||||
|
||||
int col=0;
|
||||
int row =0;
|
||||
|
||||
Label xLabel = new Label("x");
|
||||
xLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
Label yLabel = new Label("y");
|
||||
yLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
col=1;
|
||||
positionPane.add(xLabel, col++, row);
|
||||
positionPane.add(yLabel, col++, row);
|
||||
positionPane.add(depthLabel, col++, row);
|
||||
|
||||
col=0;
|
||||
row++;
|
||||
|
||||
Label positionLabel = new Label("Position");
|
||||
positionPane.add(positionLabel, col++, row);
|
||||
positionPane.add(xPos, col++, row);
|
||||
positionPane.add(yPos, col++, row);
|
||||
positionPane.add(zPos, col++, row);
|
||||
positionPane.add(new Label("(m)"), col++, row);
|
||||
|
||||
col=0;
|
||||
row++;
|
||||
|
||||
Label errLabel = new Label("Error");
|
||||
positionPane.add(errLabel, col++, row);
|
||||
positionPane.add(xPosErr, col++, row);
|
||||
positionPane.add(yPosErr, col++, row);
|
||||
positionPane.add(zPosErr, col++, row);
|
||||
positionPane.add(new Label("(m)"), col++, row);
|
||||
|
||||
// positionPane.add(new Label("\u00B1"), col, 2);
|
||||
// positionPane.add(xPosErr, col, 3);
|
||||
// positionPane.add(new Label("m (right of streamer)"), col, 5);
|
||||
|
||||
col++;
|
||||
|
||||
// Label yLabel = new Label("y");
|
||||
// yLabel.setAlignment(Pos.CENTER);
|
||||
// positionPane.add(yLabel, col, 0);
|
||||
// positionPane.add(yPos, col, 1);
|
||||
// positionPane.add(new Label("\u00B1"), col, 2);
|
||||
// positionPane.add(yPosErr, col, 3);
|
||||
// positionPane.add(new Label("m (ahead of streamer)"), col, 4);
|
||||
// col++;
|
||||
//
|
||||
//
|
||||
// positionPane.add(depthLabel, col, 0);
|
||||
// positionPane.add(zPos, col, 1);
|
||||
// positionPane.add(new Label("\u00B1"), col, 2);
|
||||
// positionPane.add(zPosErr, col, 3);
|
||||
// positionPane.add(depthLabel2, col, 4);
|
||||
|
||||
// ColumnConstraints col1 = new ColumnConstraints();
|
||||
// col1.setHgrow(Priority.ALWAYS);
|
||||
// positionPane.getColumnConstraints().add(col1);
|
||||
|
||||
// Label positionLabel = new Label("Coordinates");
|
||||
// PamGuiManagerFX.titleFont2style(positionLabel);
|
||||
|
||||
mainControls.getChildren().addAll(positionPane);
|
||||
|
||||
ColumnConstraints col1 = new ColumnConstraints();
|
||||
col1.setMinWidth(COLUMN_0_WIDTH);
|
||||
col1.setMaxWidth(COLUMN_0_WIDTH);
|
||||
positionPane.getColumnConstraints().addAll(col1);
|
||||
|
||||
|
||||
setCoordsText();
|
||||
|
||||
return mainControls;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a text filed and adds a validator to check that the input is OK.
|
||||
* @return
|
||||
*/
|
||||
protected static void addTextValidator(TextField userTextField, String description, Validator validator) {
|
||||
//userTextField.setPrefColumnCount(8);
|
||||
|
||||
validator.createCheck()
|
||||
.dependsOn(description, userTextField.textProperty())
|
||||
.withMethod(c -> {
|
||||
String posVal = c.get(description);
|
||||
|
||||
/**
|
||||
* Ok, this is weird. So if the c.error is called then somehow it messes up
|
||||
* the sizing of the pane i.e. it does not resize..
|
||||
*/
|
||||
|
||||
try {
|
||||
if (posVal.isEmpty() || Double.valueOf(posVal)==null) {
|
||||
c.error("The input for " + description + " is invalid");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
c.error("The input for " + description + " is invalid");
|
||||
}
|
||||
})
|
||||
.decorates(userTextField).immediate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setParams(Hydrophone hydrophone) {
|
||||
|
||||
//parent array stuff.
|
||||
|
||||
//iD.setText(String.format("%d", hydrophone.getID()));
|
||||
|
||||
streamers.getItems().clear();
|
||||
|
||||
//set thre text values for the recieevrs.
|
||||
setGeneralInfoLabelText();
|
||||
if (currentArray != null) {
|
||||
Streamer s;
|
||||
for (int i = 0; i < currentArray.getNumStreamers(); i++) {
|
||||
s = currentArray.getStreamer(i);
|
||||
streamers.getItems().add(String.format("Streamer %d, x=%3.1f", i, s.getX()));
|
||||
}
|
||||
}
|
||||
if (hydrophone.getStreamerId() < currentArray.getNumStreamers()) {
|
||||
streamers.getSelectionModel().select(hydrophone.getStreamerId());
|
||||
}
|
||||
|
||||
//hydrophone stuff
|
||||
hSens.getValueFactory().setValue(hydrophone.getSensitivity()-PamController.getInstance().getGlobalMediumManager().getdBSensOffset());
|
||||
preampGain.getValueFactory().setValue(hydrophone.getPreampGain());
|
||||
|
||||
double zCoeff = PamController.getInstance().getGlobalMediumManager().getZCoeff();
|
||||
setCoordsText();
|
||||
|
||||
interpPane.setSelection(currentArray.getHydrophoneInterpolation());
|
||||
|
||||
xPos.setText(Double.toString(hydrophone.getX()));
|
||||
yPos.setText(Double.toString(hydrophone.getY()));
|
||||
zPos.setText(Double.toString(zCoeff*hydrophone.getZ()));
|
||||
xPosErr.setText(Double.toString(hydrophone.getdX()));
|
||||
yPosErr.setText(Double.toString(hydrophone.getdY()));
|
||||
zPosErr.setText(Double.toString(hydrophone.getdZ()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Hydrophone getParams(Hydrophone hydrophone) {
|
||||
double zCoeff = PamController.getInstance().getGlobalMediumManager().getZCoeff();
|
||||
|
||||
try {
|
||||
//hydrophone.setID(Integer.valueOf(iD.getText()));
|
||||
//hydrophone.setType(type.getText());
|
||||
hydrophone.setStreamerId(streamers.getSelectionModel().getSelectedIndex());
|
||||
hydrophone.setSensitivity(hSens.getValue()+PamController.getInstance().getGlobalMediumManager().getdBSensOffset());
|
||||
hydrophone.setPreampGain(preampGain.getValue());
|
||||
// double[] bw = new double[2];
|
||||
// bw[0] = Double.valueOf(bandwidth0.getText());
|
||||
// bw[1] = Double.valueOf(bandwidth1.getText());
|
||||
// hydrophone.setBandwidth(bw);
|
||||
|
||||
hydrophone.setX(Double.valueOf(xPos.getText()));
|
||||
hydrophone.setY(Double.valueOf(yPos.getText()));
|
||||
hydrophone.setZ(zCoeff*Double.valueOf(zPos.getText()));
|
||||
hydrophone.setdX(Double.valueOf(xPosErr.getText()));
|
||||
hydrophone.setdY(Double.valueOf(yPosErr.getText()));
|
||||
hydrophone.setdZ(Double.valueOf(zPosErr.getText()));
|
||||
|
||||
int hi = interpPane.getSelection();
|
||||
if (hi >= 0) {
|
||||
this.currentArray.setHydrophoneInterpolation(interpPane.getSelectedInterpType());
|
||||
}
|
||||
}
|
||||
catch (Exception Ex) {
|
||||
System.err.println("There is a problem with one of the parameters in the hydrophone panel");
|
||||
return null;
|
||||
}
|
||||
return hydrophone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current array associated with the hydrophone.
|
||||
* @param currentArray - the current array.
|
||||
*/
|
||||
public void setCurrentArray(PamArray currentArray) {
|
||||
this.currentArray= currentArray;
|
||||
|
||||
}
|
||||
|
||||
public void setRecieverLabels() {
|
||||
setGeneralInfoLabelText();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
412
src/Array/layoutFX/HydrophonesPane.java
Normal file
412
src/Array/layoutFX/HydrophonesPane.java
Normal file
@ -0,0 +1,412 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import Array.Hydrophone;
|
||||
import Array.PamArray;
|
||||
import PamController.PamController;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Dialog;
|
||||
import javafx.scene.control.TableCell;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.util.Callback;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.cell.TextFieldTableCell;
|
||||
import javafx.util.converter.IntegerStringConverter;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamColorsFX;
|
||||
import pamViewFX.fxNodes.flipPane.PamFlipPane;
|
||||
import pamViewFX.fxNodes.table.TableSettingsPane;
|
||||
|
||||
/**
|
||||
* Table which allows users to add and edit hydrophones.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class HydrophonesPane extends PamBorderPane {
|
||||
|
||||
|
||||
static final double defaultx = 0.;
|
||||
static final double defaulty = 0.;
|
||||
static final double defaultz = 0.;
|
||||
static final double defaultxErr = 0.;
|
||||
static final double defaultyErr = 0.;
|
||||
static final double defaultzErr = 0.;
|
||||
static final String defaulttype = "Unknown";
|
||||
static final double defaultsensitivity = -201;
|
||||
|
||||
/**
|
||||
* Reference to the current array
|
||||
*/
|
||||
protected PamArray currentArray;
|
||||
|
||||
/**
|
||||
* The current hydrophone data.
|
||||
*/
|
||||
private HydrophoneProperty currentHydrophoneData;
|
||||
|
||||
|
||||
/**
|
||||
* A list of all the current hydrophones.
|
||||
*/
|
||||
ObservableList<HydrophoneProperty> hydrophoneList = FXCollections.observableArrayList();
|
||||
|
||||
|
||||
/**
|
||||
* The hydrophone array table.
|
||||
*/
|
||||
private HydrophoneTable tableArrayPane;
|
||||
|
||||
private PamFlipPane pamFlipePane;
|
||||
|
||||
/**
|
||||
* Settings pane for a single hydrophone.
|
||||
*/
|
||||
private HydrophoneSettingsPane hydrophonePane = new HydrophoneSettingsPane();
|
||||
|
||||
/**
|
||||
* A list of listeners which are called whenever a hydrophone is added removed or changed.
|
||||
*/
|
||||
public ArrayList<ArrayChangeListener> hydrophoneChangeListeners = new ArrayList<ArrayChangeListener>();
|
||||
|
||||
public HydrophonesPane() {
|
||||
|
||||
tableArrayPane = new HydrophoneTable(hydrophoneList);
|
||||
|
||||
tableArrayPane.setPadding(new Insets(5,5,5,5));
|
||||
|
||||
pamFlipePane = new PamFlipPane();
|
||||
pamFlipePane.getAdvLabel().setText(PamController.getInstance().getGlobalMediumManager().getRecieverString());
|
||||
// pamFlipePane.minWidthProperty().bind(this.widthProperty());
|
||||
// pamFlipePane.setStyle("-fx-background-color: green;");
|
||||
|
||||
|
||||
((Pane) hydrophonePane.getContentNode()).setPadding(new Insets(5,5,5,15));
|
||||
|
||||
pamFlipePane.setAdvPaneContent(hydrophonePane.getContentNode());
|
||||
pamFlipePane.setFrontContent(tableArrayPane);
|
||||
|
||||
pamFlipePane.getFront().setPadding(new Insets(5,5,5,10));
|
||||
|
||||
pamFlipePane.backButtonProperty().addListener((obsval, oldVal, newVal)->{
|
||||
|
||||
// System.out.println("Hello back button pressed: " + newVal.intValue());
|
||||
//the flip pane
|
||||
if (newVal.intValue()==PamFlipPane.OK_BACK_BUTTON) {
|
||||
|
||||
Hydrophone hydro = hydrophonePane.getParams(currentHydrophoneData.getHydrophone());
|
||||
|
||||
if (hydro==null) {
|
||||
//the warning dialog is shown in the streamer settings pane
|
||||
return;
|
||||
}
|
||||
|
||||
// System.out.println("Hydro: " + currentHydrophoneData.getX().get()+ " " + currentHydrophoneData.getY().get() + " " + currentHydrophoneData.getZ().get() + " ID: " +hydro.getID());
|
||||
// System.out.println("Hydro err: " + currentHydrophoneData.getXErr().get()+ " " + currentHydrophoneData.getYErr().get() + " " + currentHydrophoneData.getZErr().get());
|
||||
|
||||
currentHydrophoneData.setHydrophone(hydro);
|
||||
|
||||
notifyHydrophoneListeners(currentHydrophoneData);
|
||||
|
||||
//need to refresh table to show symbol.
|
||||
tableArrayPane.getTableView().refresh();
|
||||
//
|
||||
// System.out.println("Table size: " + tableArrayPane.getTableView().getItems().size());
|
||||
// for (int i=0; i<tableArrayPane.getTableView().getItems().size(); i++) {
|
||||
// System.out.println("Item : " + tableArrayPane.getTableView().getItems().get(i) + " " + currentHydrophoneData);
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
this.setCenter(pamFlipePane);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the hydrophone listeners of a change
|
||||
* @param streamer - the changed streamer
|
||||
*/
|
||||
public void notifyHydrophoneListeners(HydrophoneProperty hydrophone) {
|
||||
for (ArrayChangeListener listener: hydrophoneChangeListeners) {
|
||||
listener.arrayChanged(ArrayChangeListener.HYDROPHONE_CHANGE, hydrophone);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
class HydrophoneTable extends TableSettingsPane<HydrophoneProperty> {
|
||||
|
||||
|
||||
/**
|
||||
* The z table
|
||||
*/
|
||||
private TableColumn<HydrophoneProperty, Number> z;
|
||||
|
||||
public HydrophoneTable(ObservableList<HydrophoneProperty> hydrophoneData) {
|
||||
super(hydrophoneData);
|
||||
|
||||
z = new TableColumn<HydrophoneProperty,Number>("depth");
|
||||
z.setCellValueFactory(cellData -> cellData.getValue().getZ().multiply(PamController.getInstance().getGlobalMediumManager().getZCoeff()));
|
||||
z.setEditable(true);
|
||||
|
||||
//need to set up all the rows.
|
||||
TableColumn<HydrophoneProperty,Integer> hydroID = new TableColumn<HydrophoneProperty,Integer>("ID");
|
||||
hydroID.setCellValueFactory(cellData -> cellData.getValue().getID().asObject());
|
||||
hydroID.setEditable(false);
|
||||
|
||||
// Default cell factory provides text field for editing and converts text in text field to int.
|
||||
Callback<TableColumn<HydrophoneProperty, Integer>, TableCell<HydrophoneProperty, Integer>> defaultCellFactory =
|
||||
TextFieldTableCell.forTableColumn(new IntegerStringConverter());
|
||||
|
||||
// Cell factory implementation that uses default cell factory above, and augments the implementation
|
||||
// by updating the value of the looked-up color cell-selection-color for the cell when the item changes:
|
||||
Callback<TableColumn<HydrophoneProperty, Integer>, TableCell<HydrophoneProperty, Integer>> cellFactory = col -> {
|
||||
TableCell<HydrophoneProperty, Integer> cell = defaultCellFactory.call(col);
|
||||
cell.itemProperty().addListener((obs, oldValue, newValue) -> {
|
||||
// System.out.println("Hello set colour: " + newValue);
|
||||
if (newValue == null) {
|
||||
cell.setStyle("cell-selection-color: -fx-selection-bar ;");
|
||||
} else {
|
||||
Color color = createColor(newValue.intValue());
|
||||
String formattedColor = formatColor(color);
|
||||
// cell.setStyle("cell-selection-color: "+ formattedColor + " ;");
|
||||
cell.setStyle("-fx-background: "+ formattedColor + " ;");
|
||||
cell.setStyle("-fx-background-color: "+ formattedColor + " ;");
|
||||
// System.out.println("Hello set style: " + formattedColor);
|
||||
}
|
||||
});
|
||||
return cell;
|
||||
};
|
||||
|
||||
hydroID.setCellFactory(cellFactory);
|
||||
|
||||
|
||||
TableColumn<HydrophoneProperty,Number> x = new TableColumn<HydrophoneProperty,Number>("x");
|
||||
x.setCellValueFactory(cellData -> cellData.getValue().getX());
|
||||
x.setEditable(true);
|
||||
|
||||
TableColumn<HydrophoneProperty,Number> y = new TableColumn<HydrophoneProperty,Number>("y");
|
||||
y.setCellValueFactory(cellData -> cellData.getValue().getY());
|
||||
y.setEditable(true);
|
||||
|
||||
|
||||
TableColumn posColumn=new TableColumn("Position (m)");
|
||||
posColumn.getColumns().addAll(x, y, z);
|
||||
|
||||
TableColumn<HydrophoneProperty,Number> xErr = new TableColumn<HydrophoneProperty,Number>("x");
|
||||
xErr.setCellValueFactory(cellData -> cellData.getValue().getXErr());
|
||||
xErr.setEditable(true);
|
||||
|
||||
TableColumn<HydrophoneProperty,Number> yErr = new TableColumn<HydrophoneProperty,Number>("y");
|
||||
yErr.setCellValueFactory(cellData -> cellData.getValue().getYErr());
|
||||
yErr.setEditable(true);
|
||||
|
||||
TableColumn<HydrophoneProperty,Number> zErr = new TableColumn<HydrophoneProperty,Number>("z");
|
||||
zErr.setCellValueFactory(cellData -> cellData.getValue().getZErr());
|
||||
zErr.setEditable(true);
|
||||
|
||||
TableColumn errorColumn=new TableColumn("Errors (m)");
|
||||
errorColumn.getColumns().addAll(xErr, yErr, zErr);
|
||||
|
||||
getTableView().getColumns().addAll(hydroID, posColumn, errorColumn);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Create color based on int value. Just use value as hue, full saturation and brightness:
|
||||
private Color createColor(int i) {
|
||||
//get channel colour and add a bit of transparancy to make less abnoxious
|
||||
return PamColorsFX.getInstance().getChannelColor(i).deriveColor(1, 1, 1, 0.5);
|
||||
|
||||
// return Color.hsb(x, 1.0, 1.0);
|
||||
}
|
||||
|
||||
// Format color as string for CSS (#rrggbb format, values in hex).
|
||||
private String formatColor(Color c) {
|
||||
int r = (int) (255 * c.getRed());
|
||||
int g = (int) (255 * c.getGreen());
|
||||
int b = (int) (255 * c.getBlue());
|
||||
return String.format("#%02x%02x%02x", r, g, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dialogClosed(HydrophoneProperty data) {
|
||||
System.out.println("Get hydrophone paramters");
|
||||
Hydrophone hydro = hydrophonePane.getParams(data.getHydrophone());
|
||||
data.setHydrophone(hydro);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog<HydrophoneProperty> createSettingsDialog(HydrophoneProperty data) {
|
||||
//we do not use dialogs here- sliding pane instead.
|
||||
// setClassifierPane(data);
|
||||
pamFlipePane.flipToBack();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editData(HydrophoneProperty data){
|
||||
// setClassifierPane(data);
|
||||
|
||||
pamFlipePane.getAdvLabel().setText("Hydrophone " + data.getID().get() + " Settings");
|
||||
|
||||
hydrophonePane.setCurrentArray(currentArray);
|
||||
hydrophonePane.setParams(data.getHydrophone());
|
||||
|
||||
currentHydrophoneData = data;
|
||||
|
||||
pamFlipePane.flipToBack();
|
||||
}
|
||||
|
||||
|
||||
private PamArray getCurrentArray() {
|
||||
return currentArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the button which closes the hiding pane.
|
||||
* @return button which closes the hiding pane.
|
||||
*/
|
||||
public Button getFlipPaneCloseButton() {
|
||||
return pamFlipePane.getBackButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNewData(){
|
||||
HydrophoneProperty hydrophone = createDefaultHydrophoneProperty(hydrophoneList.size());
|
||||
//create a new classifier.
|
||||
hydrophoneList.add(hydrophone);
|
||||
notifyHydrophoneListeners(hydrophone);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void deleteData(HydrophoneProperty data){
|
||||
super.deleteData(data);
|
||||
//the ID number for hydrophone sis actually important for where they are in the list. Bit a legacy issue but no
|
||||
//point in messes everything up to fix. So, when a hydrophone is deleted must update all the ID numbers.
|
||||
|
||||
updateIDNumbers();
|
||||
|
||||
notifyHydrophoneListeners(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the ID numbers.
|
||||
*/
|
||||
private void updateIDNumbers() {
|
||||
for (int i=0; i<getData().size(); i++){
|
||||
getData().get(i).id.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
private HydrophoneProperty createDefaultHydrophoneProperty(int id) {
|
||||
Hydrophone hydrophone = new Hydrophone(id, defaultx, defaulty,defaultz, defaultxErr, defaultyErr, defaultzErr, defaulttype, defaultsensitivity,
|
||||
null, 0. );
|
||||
return new HydrophoneProperty(hydrophone);
|
||||
}
|
||||
|
||||
|
||||
public TableColumn<HydrophoneProperty, Number> getZColumn() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current streamers.
|
||||
* @return the current streamers.
|
||||
*/
|
||||
public ObservableList<HydrophoneProperty> getHydrophones() {
|
||||
return getData();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void setParams(PamArray currentArray) {
|
||||
this.currentArray=currentArray;
|
||||
|
||||
tableArrayPane.getHydrophones().clear();
|
||||
|
||||
for (int i=0; i<currentArray.getHydrophoneCount(); i++) {
|
||||
tableArrayPane.getHydrophones().add(new HydrophoneProperty(currentArray.getHiddenHydrophone(i)));
|
||||
}
|
||||
|
||||
//update ID numbers just incase.
|
||||
tableArrayPane.updateIDNumbers();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public synchronized PamArray getParams(PamArray currParams) {
|
||||
|
||||
currParams.clearArray();
|
||||
|
||||
Hydrophone hydrophone;
|
||||
for (int i=0; i<tableArrayPane.getHydrophones().size(); i++) {
|
||||
hydrophone = tableArrayPane.getHydrophones().get(i).getHydrophone();
|
||||
hydrophone.setID(i);
|
||||
currParams.addHydrophone(hydrophone);
|
||||
}
|
||||
|
||||
return currParams;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current hydrophone list.
|
||||
* @return the current hydrophone list.
|
||||
*/
|
||||
public ObservableList<HydrophoneProperty> getHydrophoneList() {
|
||||
return hydrophoneList;
|
||||
}
|
||||
|
||||
public void setHydrophoneList(ObservableList<HydrophoneProperty> hydrophoneList) {
|
||||
this.hydrophoneList = hydrophoneList;
|
||||
}
|
||||
|
||||
public void setRecieverLabels() {
|
||||
tableArrayPane.getZColumn().setText(PamController.getInstance().getGlobalMediumManager().getZString());
|
||||
hydrophonePane.setRecieverLabels();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener which is called whenever a hydrophone is added, removed or changed.
|
||||
* @param e - the listener to add
|
||||
*/
|
||||
public void addStreamerListener(ArrayChangeListener e) {
|
||||
hydrophoneChangeListeners.add(e);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the current hydrophone in table.
|
||||
*/
|
||||
public void selectHydrophone(Hydrophone hydrophone) {
|
||||
//select the current hydrophone in the table
|
||||
tableArrayPane.getTableView().getSelectionModel().select(hydrophone.getID());
|
||||
}
|
||||
|
||||
public void setCurrentArray(PamArray currentArray) {
|
||||
this.currentArray=currentArray;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hydrophone interpolation. Note that this is stored in the
|
||||
* currentArray because the interpolator must be the same for all hydrophones.
|
||||
*
|
||||
* @return the inteprolation selection.
|
||||
*/
|
||||
public int getHydrophoneInterp() {
|
||||
return currentArray.getHydrophoneInterpolation();
|
||||
}
|
||||
|
||||
}
|
104
src/Array/layoutFX/InterpChoicePane.java
Normal file
104
src/Array/layoutFX/InterpChoicePane.java
Normal file
@ -0,0 +1,104 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Choice box which allows selection of interpolation options.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class InterpChoicePane extends InterpSettingsPane {
|
||||
|
||||
/**
|
||||
* Interp choice box.
|
||||
*/
|
||||
private ChoiceBox<Integer> interpChoiceBox;
|
||||
|
||||
public InterpChoicePane() {
|
||||
|
||||
interpChoiceBox = new ChoiceBox<Integer>();
|
||||
interpChoiceBox.getItems().addAll(interpChoice);
|
||||
interpChoiceBox.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
interpChoiceBox.setConverter(new StringConverter<>() {
|
||||
@Override
|
||||
public String toString(Integer item) {
|
||||
if (item ==null) return "null";
|
||||
return getInterpString(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer fromString(String unused) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
});
|
||||
|
||||
this.setCenter(interpChoiceBox);
|
||||
|
||||
}
|
||||
|
||||
public void setSelection(int option) {
|
||||
|
||||
System.out.println("Select interp option: " + option);
|
||||
|
||||
interpChoiceBox.getSelectionModel().select(Integer.valueOf(option));
|
||||
|
||||
// useLatest.setSelected(option == PamArray.ORIGIN_USE_LATEST);
|
||||
// useInterpolate.setSelected(option == PamArray.ORIGIN_INTERPOLATE);
|
||||
// usePrevious.setSelected(option == PamArray.ORIGIN_USE_PRECEEDING);
|
||||
}
|
||||
|
||||
public int getSelection() {
|
||||
int sel = getSelectedInterpType();
|
||||
if (((1<<sel) & allowedValues) == 0) {
|
||||
PamDialogFX.showWarning("The selected interpolation is not available with the selected reference position");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enableControls() {
|
||||
//get the current selection
|
||||
Integer item = interpChoiceBox.getSelectionModel().getSelectedItem();
|
||||
|
||||
//clear items
|
||||
interpChoiceBox.getItems().clear();
|
||||
|
||||
//set allowed values
|
||||
for (int i=0; i<interpChoice.length ; i++) {
|
||||
|
||||
if ((allowedValues & (1<<interpChoice[i])) != 0){
|
||||
interpChoiceBox.getItems().add(interpChoice[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//reselect the previously selected item if possible.
|
||||
if (interpChoiceBox.getItems().contains(item)) {
|
||||
interpChoiceBox.getSelectionModel().select(item);
|
||||
}
|
||||
else {
|
||||
interpChoiceBox.getSelectionModel().select(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSelectedInterpType() {
|
||||
Integer choice = interpChoiceBox.getSelectionModel().getSelectedItem();
|
||||
if (choice == null) {
|
||||
return -1;
|
||||
}
|
||||
else return choice;
|
||||
}
|
||||
|
||||
|
||||
}
|
160
src/Array/layoutFX/InterpSettingsPane.java
Normal file
160
src/Array/layoutFX/InterpSettingsPane.java
Normal file
@ -0,0 +1,160 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import Array.PamArray;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Radio buttons which allow selection of interpolation options.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class InterpSettingsPane extends PamBorderPane {
|
||||
|
||||
/**
|
||||
* Interp choice.
|
||||
*/
|
||||
public static Integer[] interpChoice = new Integer[] {PamArray.ORIGIN_USE_LATEST,
|
||||
PamArray.ORIGIN_INTERPOLATE, PamArray.ORIGIN_USE_PRECEEDING};
|
||||
|
||||
private RadioButton[] radioButton;
|
||||
|
||||
protected int allowedValues = 0xFF; // bitmap of banned values !
|
||||
|
||||
public InterpSettingsPane() {
|
||||
this.setCenter(createInterpPane());
|
||||
}
|
||||
|
||||
|
||||
protected Pane createInterpPane() {
|
||||
PamGridPane gridPane = new PamGridPane();
|
||||
|
||||
gridPane.setVgap(5);
|
||||
|
||||
int gridy=0;
|
||||
|
||||
radioButton = new RadioButton[interpChoice.length];
|
||||
ToggleGroup group = new ToggleGroup();
|
||||
|
||||
for (int i=0; i<radioButton.length ; i++) {
|
||||
gridPane.add(radioButton[i] = new RadioButton( getInterpString(interpChoice[i])), 0, gridy);
|
||||
radioButton[i].setTooltip(new Tooltip( getInterpTip(interpChoice[i])));
|
||||
gridy++;
|
||||
radioButton[i].setToggleGroup(group);
|
||||
|
||||
}
|
||||
|
||||
return gridPane;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a description of the interpolation type for an interp-type flag.
|
||||
* @param interpType - the interpolation type flag.
|
||||
* @return a description of that interpolation methid.
|
||||
*/
|
||||
public String getInterpString(int interpType) {
|
||||
String description = null;
|
||||
switch ( interpType) {
|
||||
case PamArray.ORIGIN_USE_LATEST:
|
||||
description = "Use only the latest value";
|
||||
break;
|
||||
case PamArray.ORIGIN_INTERPOLATE:
|
||||
description = "Interpolate between values";
|
||||
|
||||
break;
|
||||
case PamArray.ORIGIN_USE_PRECEEDING:
|
||||
description = "Use the location for the time preceeding each data unit";
|
||||
break;
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a description of the interpolation type for an interp-type flag.
|
||||
* @param interpType - the interpolation type flag.
|
||||
* @return a description of that interpolation methid.
|
||||
*/
|
||||
public String getInterpTip(int interpType) {
|
||||
String description = null;
|
||||
switch ( interpType) {
|
||||
case PamArray.ORIGIN_USE_LATEST:
|
||||
description = "Select this option if you have a simple static array in a single location for the entire data set";
|
||||
break;
|
||||
case PamArray.ORIGIN_INTERPOLATE:
|
||||
description = "Select this option if you are storing multiple locations for slowely moving (i.e. not quite fixed) devices";
|
||||
|
||||
break;
|
||||
case PamArray.ORIGIN_USE_PRECEEDING:
|
||||
description = "Select this option if you have devices which are periodically moved from one spot to another";
|
||||
break;
|
||||
}
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
public void setSelection(int option) {
|
||||
for (int i=0; i<interpChoice.length; i++) {
|
||||
radioButton[i].setSelected(option == interpChoice[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSelection() {
|
||||
int sel = getSelectedInterpType();
|
||||
if (((1<<sel) & allowedValues) == 0) {
|
||||
PamDialogFX.showWarning("The selected interpolation is not available with the selected reference position");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the allowedValues
|
||||
*/
|
||||
protected int getAllowedValues() {
|
||||
return allowedValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowedValues the allowedValues to set
|
||||
*/
|
||||
protected void setAllowedValues(int allowedValues) {
|
||||
this.allowedValues = allowedValues;
|
||||
enableControls();
|
||||
}
|
||||
|
||||
protected void enableControls() {
|
||||
for (int i=0; i<interpChoice.length; i++) {
|
||||
radioButton[i].setDisable((allowedValues & (1<<interpChoice[i])) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getSelectedInterpType() {
|
||||
for (int i=0; i<interpChoice.length; i++) {
|
||||
if (radioButton[i].isSelected()) {
|
||||
return interpChoice[i];
|
||||
}
|
||||
radioButton[i].setDisable((allowedValues & (1<<interpChoice[i])) == 0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
119
src/Array/layoutFX/PropogationPane.java
Normal file
119
src/Array/layoutFX/PropogationPane.java
Normal file
@ -0,0 +1,119 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import Array.PamArray;
|
||||
import PamController.SettingsPane;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.Pane;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.validator.PamValidator;
|
||||
|
||||
/**
|
||||
* Pane for settings some basic environmental variables.
|
||||
*/
|
||||
public class PropogationPane extends SettingsPane<PamArray> {
|
||||
|
||||
Pane mainPane;
|
||||
|
||||
private TextField speedOfSound;
|
||||
|
||||
private TextField speedOfSoundError;
|
||||
|
||||
private PamValidator validator;
|
||||
|
||||
|
||||
public PropogationPane() {
|
||||
super(null);
|
||||
validator= new PamValidator();
|
||||
mainPane = createEnvironmentPane();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the pane for setting propogation conditions.
|
||||
* @return the pane with controls to change environmental variables.
|
||||
*/
|
||||
private Pane createEnvironmentPane() {
|
||||
speedOfSound = new TextField();
|
||||
speedOfSound.setPrefColumnCount(6);
|
||||
|
||||
validator.createCheck()
|
||||
.dependsOn("speed_of_sound", speedOfSound.textProperty())
|
||||
.withMethod(c -> {
|
||||
try {
|
||||
String posVal = c.get("speed_of_sound");
|
||||
if (posVal.isEmpty() || Double.valueOf(posVal)==null) {
|
||||
c.error("The input for speed of sound is invalid");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
c.error("The input for speed of sound is invalid");
|
||||
}
|
||||
})
|
||||
.decorates(speedOfSound).immediate();
|
||||
|
||||
|
||||
speedOfSoundError = new TextField();
|
||||
speedOfSoundError.setPrefColumnCount(4);
|
||||
|
||||
validator.createCheck()
|
||||
.dependsOn("speed_of_sound_error", speedOfSoundError.textProperty())
|
||||
.withMethod(c -> {
|
||||
try {
|
||||
String posVal = c.get("speed_of_sound_error");
|
||||
if (posVal.isEmpty() || Double.valueOf(posVal)==null) {
|
||||
c.error("The input for speed of sound error is invalid");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
c.error("The input for speed of sound is invalid");
|
||||
}
|
||||
})
|
||||
.decorates(speedOfSoundError).immediate();
|
||||
|
||||
PamHBox hBox = new PamHBox();
|
||||
hBox.setSpacing(5);
|
||||
hBox.setAlignment(Pos.CENTER);
|
||||
|
||||
|
||||
hBox.getChildren().addAll(new Label("Speed of sound"), speedOfSound, new Label("\u00B1"), speedOfSoundError, new Label("m/s"));
|
||||
|
||||
return hBox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PamArray getParams(PamArray currParams) {
|
||||
if (validator.containsErrors()) return null;
|
||||
|
||||
currParams.setSpeedOfSound(Double.valueOf(speedOfSound.getText()));
|
||||
currParams.setSpeedOfSoundError(Double.valueOf(speedOfSoundError.getText()));
|
||||
return currParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(PamArray input) {
|
||||
//set the current params.
|
||||
speedOfSound.setText(String.valueOf(input.getSpeedOfSound()));
|
||||
speedOfSoundError.setText(String.valueOf(input.getSpeedOfSoundError()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Propogation pane";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paneInitialized() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
162
src/Array/layoutFX/SensorSourcePane.java
Normal file
162
src/Array/layoutFX/SensorSourcePane.java
Normal file
@ -0,0 +1,162 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import Array.sensors.ArrayParameterType;
|
||||
import Array.sensors.ArraySensorDataBlock;
|
||||
import Array.sensors.ArraySensorDataUnit;
|
||||
import Array.sensors.ArraySensorFieldType;
|
||||
import PamController.PamController;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Tooltip;
|
||||
|
||||
public class SensorSourcePane {
|
||||
|
||||
private ArraySensorFieldType sensorType;
|
||||
|
||||
private ComboBox<String> sensorDropDown;
|
||||
|
||||
private ArrayList<PamDataBlock> currentBlocks;
|
||||
|
||||
private boolean defaultOption;
|
||||
|
||||
private boolean fixedOption;
|
||||
|
||||
private int nSpecials;
|
||||
|
||||
private ArrayParameterType[] specialTypes = new ArrayParameterType[2];
|
||||
|
||||
public SensorSourcePane(ArraySensorFieldType sensorType, boolean fixedOption, boolean defaultOption) {
|
||||
this.sensorType = sensorType;
|
||||
this.fixedOption = fixedOption;
|
||||
this.defaultOption = defaultOption;
|
||||
sensorDropDown = new ComboBox<>();
|
||||
fillDropDown();
|
||||
sensorDropDown.setTooltip(new Tooltip("Sensor updates for " + sensorType.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of sensor.
|
||||
* @return the type of sensor.
|
||||
*/
|
||||
public ArraySensorFieldType getSensorType() {
|
||||
return sensorType;
|
||||
}
|
||||
|
||||
public void setOnAction(EventHandler<ActionEvent> e) {
|
||||
sensorDropDown.setOnAction(e);
|
||||
}
|
||||
|
||||
public void fillDropDown() {
|
||||
currentBlocks = getDataBlocks();
|
||||
sensorDropDown.getItems().clear();
|
||||
nSpecials = 0;
|
||||
if (fixedOption) {
|
||||
sensorDropDown.getItems().add("Fixed Value");
|
||||
specialTypes[nSpecials++] = ArrayParameterType.FIXED;
|
||||
}
|
||||
if (defaultOption) {
|
||||
sensorDropDown.getItems().add("Default value");
|
||||
specialTypes[nSpecials++] = ArrayParameterType.DEFAULT;
|
||||
}
|
||||
for (PamDataBlock aBlock : currentBlocks) {
|
||||
sensorDropDown.getItems().add(aBlock.getDataName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of parameter being used, fixed, default or sensor
|
||||
* @param paramType
|
||||
*/
|
||||
public void setParameterType(ArrayParameterType paramType) {
|
||||
for (int i = 0; i < nSpecials; i++) {
|
||||
if (paramType == specialTypes[i]) {
|
||||
sensorDropDown.getSelectionModel().select(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of parameter being used, fixed, default or sensor
|
||||
* @return
|
||||
*/
|
||||
public ArrayParameterType getParameterType() {
|
||||
int ind = sensorDropDown.getSelectionModel().getSelectedIndex();
|
||||
if (ind < 0) {
|
||||
return null;
|
||||
}
|
||||
if (ind < nSpecials) {
|
||||
return specialTypes[ind];
|
||||
}
|
||||
return ArrayParameterType.SENSOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the selected datablock for sensor data. Before calling this, you should call
|
||||
* fillDropDown to make sure list of blocks is up to date.
|
||||
* @param aDataBlock datablock to select
|
||||
* @return true if that block was selected OK, i.e. it was in the list.
|
||||
*/
|
||||
public boolean setDataBlock(PamDataBlock aDataBlock) {
|
||||
if (currentBlocks == null) {
|
||||
return false;
|
||||
}
|
||||
int ind = currentBlocks.indexOf(aDataBlock);
|
||||
if (ind < 0) {
|
||||
return false;
|
||||
}
|
||||
sensorDropDown.getSelectionModel().select(ind+nSpecials); // offset by 1 to allow for null option.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Currently selected datablock for this sensor (can be null)
|
||||
*/
|
||||
public PamDataBlock getDataBlock() {
|
||||
int ind = sensorDropDown.getSelectionModel().getSelectedIndex();
|
||||
if (ind <= 0 || currentBlocks == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return currentBlocks.get(ind-nSpecials);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sensor pane.
|
||||
* @return the sensor pane
|
||||
*/
|
||||
public Node getPane() {
|
||||
return sensorDropDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of datablocks that might be able to provide info on this
|
||||
* sensor field type
|
||||
* @return
|
||||
*/
|
||||
private ArrayList<PamDataBlock> getDataBlocks() {
|
||||
ArrayList<PamDataBlock> allDataBlocks = PamController.getInstance().getDataBlocks(ArraySensorDataUnit.class, true);
|
||||
ArrayList<PamDataBlock> sensBlocks = new ArrayList<>();
|
||||
if (allDataBlocks == null) {
|
||||
return sensBlocks;
|
||||
}
|
||||
// go through take out the ones that support this sensor.
|
||||
for (PamDataBlock aBlock : allDataBlocks) {
|
||||
if (aBlock instanceof ArraySensorDataBlock == false) {
|
||||
continue;
|
||||
}
|
||||
ArraySensorDataBlock sensBlock = (ArraySensorDataBlock) aBlock;
|
||||
if (sensBlock.hasSensorField(sensorType)) {
|
||||
sensBlocks.add(aBlock);
|
||||
}
|
||||
}
|
||||
return sensBlocks;
|
||||
}
|
||||
}
|
121
src/Array/layoutFX/StreamerProperty.java
Normal file
121
src/Array/layoutFX/StreamerProperty.java
Normal file
@ -0,0 +1,121 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import Array.Streamer;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
||||
|
||||
/**
|
||||
* Property class for a Streamer. Create property bindings for certain Streamer values which allows
|
||||
* for much easier integration into UI components in JavaFX.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class StreamerProperty {
|
||||
|
||||
/**
|
||||
* The simple name property.
|
||||
*/
|
||||
private SimpleStringProperty name = new SimpleStringProperty();
|
||||
|
||||
private SimpleStringProperty reference = new SimpleStringProperty();
|
||||
|
||||
private SimpleStringProperty origin = new SimpleStringProperty();
|
||||
|
||||
/**
|
||||
* Get the x, y and z.
|
||||
*/
|
||||
private SimpleDoubleProperty x = new SimpleDoubleProperty();
|
||||
|
||||
private SimpleDoubleProperty y = new SimpleDoubleProperty();
|
||||
|
||||
private SimpleDoubleProperty z = new SimpleDoubleProperty();
|
||||
|
||||
|
||||
private Streamer streamer;
|
||||
|
||||
private SimpleIntegerProperty streamerIDProperty = new SimpleIntegerProperty();
|
||||
|
||||
public StreamerProperty(Streamer streamer) {
|
||||
setStreamer( streamer);
|
||||
}
|
||||
|
||||
public void setStreamer(Streamer streamer) {
|
||||
this.streamer = streamer;
|
||||
name.setValue(streamer.getStreamerName());
|
||||
x.setValue(streamer.getX());
|
||||
y.setValue(streamer.getY());
|
||||
z.setValue(streamer.getZ());
|
||||
streamerIDProperty.setValue(streamer.getStreamerIndex());
|
||||
reference.setValue(streamer.getHydrophoneLocator() != null ? streamer.getHydrophoneLocator().getName() : "null");
|
||||
origin.setValue(streamer.getHydrophoneOrigin() != null ? streamer.getHydrophoneOrigin().getName() : "null");
|
||||
|
||||
}
|
||||
|
||||
public SimpleStringProperty getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(SimpleStringProperty name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SimpleDoubleProperty getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(SimpleDoubleProperty x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public SimpleDoubleProperty getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void setY(SimpleDoubleProperty y) {
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public SimpleDoubleProperty getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(SimpleDoubleProperty z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
public Streamer getStreamer() {
|
||||
return streamer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index property of the streamer.
|
||||
* @return the streamer index.
|
||||
*/
|
||||
public SimpleIntegerProperty getID() {
|
||||
return streamerIDProperty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reference property.
|
||||
* @return the reference property.
|
||||
*/
|
||||
public SimpleStringProperty getHydrophineLocator() {
|
||||
return reference;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the origin string property.
|
||||
* @return the origin string property.
|
||||
*/
|
||||
public SimpleStringProperty getHydrophoneOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
752
src/Array/layoutFX/StreamerSettingsPane.java
Normal file
752
src/Array/layoutFX/StreamerSettingsPane.java
Normal file
@ -0,0 +1,752 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import org.controlsfx.control.PopOver;
|
||||
|
||||
import Array.HydrophoneLocator;
|
||||
import Array.HydrophoneLocators;
|
||||
import Array.PamArray;
|
||||
import Array.Streamer;
|
||||
import Array.sensors.ArrayParameterType;
|
||||
import Array.sensors.ArraySensorFieldType;
|
||||
import Array.streamerOrigin.HydrophoneOriginMethod;
|
||||
import Array.streamerOrigin.HydrophoneOriginMethods;
|
||||
import Array.streamerOrigin.HydrophoneOriginSystem;
|
||||
import Array.streamerOrigin.OriginDialogComponent;
|
||||
import Array.streamerOrigin.OriginSettings;
|
||||
import PamController.PamController;
|
||||
import PamController.SettingsPane;
|
||||
import PamUtils.LatLong;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxGlyphs.PamGlyphDude;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamButton;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.validator.PamValidator;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import net.synedra.validatorfx.Validator;
|
||||
|
||||
|
||||
/**
|
||||
* A JavaFX settings pane for a streamer.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class StreamerSettingsPane extends SettingsPane<Streamer> {
|
||||
|
||||
private final static double MAX_TEXTFIELD_WIDTH = 80;
|
||||
|
||||
|
||||
public PamBorderPane mainPane;
|
||||
|
||||
/**
|
||||
* Combo Box which shows which origin methods are available.
|
||||
*/
|
||||
private ComboBox<HydrophoneOriginSystem> originMethod;
|
||||
|
||||
/**
|
||||
* The origin pane;
|
||||
*/
|
||||
private PamBorderPane originPane;
|
||||
|
||||
/**
|
||||
* The default streamer
|
||||
*/
|
||||
public Streamer defaultStreamer;
|
||||
|
||||
|
||||
/**
|
||||
* The current array
|
||||
*/
|
||||
private PamArray currentArray;
|
||||
|
||||
/**
|
||||
* The current origin methods
|
||||
*/
|
||||
private HydrophoneOriginMethod currentOriginMethod;
|
||||
|
||||
/*
|
||||
* The current origin method pane.
|
||||
*/
|
||||
private Pane currentOriginComponent;
|
||||
|
||||
/**
|
||||
* Interpolation panel
|
||||
*/
|
||||
private InterpChoicePane interpPane;
|
||||
|
||||
|
||||
private TextField xPos;
|
||||
|
||||
|
||||
private Validator validator = new PamValidator();
|
||||
|
||||
|
||||
private TextField yPos;
|
||||
|
||||
|
||||
private TextField zPos;
|
||||
|
||||
|
||||
private TextField zPosErr;
|
||||
|
||||
|
||||
private TextField xPosErr;
|
||||
|
||||
|
||||
private Label depthLabel;
|
||||
|
||||
|
||||
private TextField yPosErr;
|
||||
|
||||
|
||||
private Label depthLabel2;
|
||||
|
||||
|
||||
private TextField heading;
|
||||
|
||||
|
||||
private TextField roll;
|
||||
|
||||
|
||||
private TextField pitch;
|
||||
|
||||
|
||||
private ComboBox localiserMethod;
|
||||
|
||||
|
||||
private SensorSourcePane[] sensorComponents;
|
||||
|
||||
|
||||
private Label depthSensorLabel;
|
||||
|
||||
|
||||
/**
|
||||
* Button for extra origin parameters.
|
||||
*/
|
||||
private PamButton originButton;
|
||||
|
||||
|
||||
|
||||
public StreamerSettingsPane() {
|
||||
super(null);
|
||||
|
||||
mainPane = new PamBorderPane();
|
||||
mainPane.setCenter(getStreamerPane());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the streamer pane
|
||||
* @return get the pane.
|
||||
*/
|
||||
private Pane getStreamerPane(){
|
||||
|
||||
String reciever = PamController.getInstance().getGlobalMediumManager().getRecieverString();
|
||||
|
||||
Label label = new Label("Geo-reference Position");
|
||||
PamGuiManagerFX.titleFont2style(label);
|
||||
|
||||
//holds advanced setings for new origin methods.
|
||||
originPane = new PamBorderPane();
|
||||
PopOver popOver = new PopOver();
|
||||
popOver.setContentNode(originPane);
|
||||
|
||||
originMethod = new ComboBox<HydrophoneOriginSystem>();
|
||||
originButton = new PamButton();
|
||||
originButton.setGraphic(PamGlyphDude.createPamIcon("mdi2c-crosshairs-gps"));
|
||||
originButton.setOnAction((a)->{
|
||||
popOver.show(originButton);
|
||||
});
|
||||
originMethod.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
PamHBox originHolder = new PamHBox();
|
||||
originHolder.setSpacing(5);
|
||||
originHolder.setAlignment(Pos.CENTER_LEFT);
|
||||
originHolder.getChildren().addAll(originMethod,originButton);
|
||||
originHolder.setMaxWidth(Double.MAX_VALUE);
|
||||
HBox.setHgrow(originMethod, Priority.ALWAYS);
|
||||
|
||||
int n = HydrophoneOriginMethods.getInstance().getCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
originMethod.getItems().add(HydrophoneOriginMethods.getInstance().getMethod(i));
|
||||
}
|
||||
|
||||
Label hydroMovementLabel = new Label(reciever +" Movement Model");
|
||||
|
||||
//listener for when a new origin method is called.
|
||||
originMethod.setOnAction((action)->{
|
||||
newOriginMethod();
|
||||
});
|
||||
|
||||
interpPane = new InterpChoicePane();
|
||||
Label inteprlabel = new Label("Interpolation");
|
||||
PamGuiManagerFX.titleFont2style(inteprlabel);
|
||||
|
||||
PamHBox interpBox = new PamHBox();
|
||||
interpBox.setSpacing(5);
|
||||
Label interpMethodLabel = new Label("Method");
|
||||
|
||||
Region spacer = new Region();
|
||||
spacer.prefWidthProperty().bind(originButton.widthProperty());
|
||||
interpBox.getChildren().addAll(interpMethodLabel, interpPane, spacer);
|
||||
interpBox.setAlignment(Pos.CENTER_LEFT);
|
||||
interpBox.setMaxWidth(Double.MAX_VALUE);
|
||||
interpPane.setMaxWidth(Double.MAX_VALUE);
|
||||
HBox.setHgrow(interpPane, Priority.ALWAYS);
|
||||
|
||||
//add all stuff to the holder
|
||||
PamVBox holder = new PamVBox();
|
||||
holder.getChildren().addAll(label, originHolder, hydroMovementLabel, createLocatorPane(), inteprlabel, interpBox);
|
||||
holder.setSpacing(5);
|
||||
|
||||
|
||||
return holder;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the locator pane.
|
||||
* @return the pane containing controls.
|
||||
*/
|
||||
public Pane createLocatorPane() {
|
||||
|
||||
localiserMethod = new ComboBox<>();
|
||||
int n = HydrophoneLocators.getInstance().getCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
localiserMethod.getItems().add(HydrophoneLocators.getInstance().getSystem(i));
|
||||
}
|
||||
localiserMethod.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
PamHBox loclaiserMethodHolder = new PamHBox();
|
||||
loclaiserMethodHolder.setSpacing(5);
|
||||
loclaiserMethodHolder.setAlignment(Pos.CENTER_LEFT);
|
||||
Label spacer = new Label();
|
||||
spacer.prefWidthProperty().bind(originButton.widthProperty());
|
||||
loclaiserMethodHolder.getChildren().addAll(localiserMethod, spacer);
|
||||
loclaiserMethodHolder.setMaxWidth(Double.MAX_VALUE);
|
||||
HBox.setHgrow(localiserMethod, Priority.ALWAYS);
|
||||
|
||||
//hydrophone position and
|
||||
PamGridPane positionPane = new PamGridPane();
|
||||
positionPane.setHgap(5);
|
||||
positionPane.setVgap(5);
|
||||
|
||||
ColumnConstraints rc = new ColumnConstraints(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE, MAX_TEXTFIELD_WIDTH);
|
||||
|
||||
//Orientation pane.
|
||||
//create data sources for sensors.
|
||||
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
|
||||
sensorComponents = new SensorSourcePane[sensorFields.length];
|
||||
//EnableOrientation eo = new EnableOrientation();
|
||||
for (int i = 0; i < sensorFields.length; i++) {
|
||||
sensorComponents[i] = new SensorSourcePane(sensorFields[i], true, sensorFields[i] != ArraySensorFieldType.HEIGHT);
|
||||
sensorComponents[i].setOnAction((e)->{
|
||||
enableOrientationPane();
|
||||
});
|
||||
}
|
||||
PamButton button = new PamButton("Sensors");
|
||||
button.setGraphic(PamGlyphDude.createPamIcon("mdi2c-compass-outline", PamGuiManagerFX.iconSize));
|
||||
|
||||
PopOver popOver = new PopOver(createSensorPane());
|
||||
popOver.setDetachable(true);
|
||||
|
||||
button.setOnAction((a)->{
|
||||
popOver.show(button);
|
||||
});
|
||||
|
||||
|
||||
//this sets all text fields to the correct width - but of naff hack but what grid pane needs to work.
|
||||
for (int i=1; i<5; i++) {
|
||||
positionPane.getColumnConstraints().add(rc);
|
||||
}
|
||||
|
||||
xPos=new TextField();
|
||||
xPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(xPos, "x position", validator);
|
||||
yPos=new TextField();
|
||||
yPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(yPos, "y position", validator);
|
||||
zPos=new TextField();
|
||||
zPos.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(zPos, "z position", validator);
|
||||
|
||||
|
||||
depthLabel = new Label("Depth");
|
||||
depthLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
depthSensorLabel = new Label("Depth Sensor");
|
||||
depthSensorLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
|
||||
xPosErr=new TextField();
|
||||
xPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(xPosErr, "x error", validator);
|
||||
yPosErr=new TextField();
|
||||
yPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(yPosErr, "y error", validator);
|
||||
zPosErr=new TextField();
|
||||
zPosErr.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
depthLabel2 = new Label(""); //changes with air or water mode.
|
||||
depthLabel2.setAlignment(Pos.CENTER);
|
||||
HydrophoneSettingsPane.addTextValidator(zPosErr, "z error", validator);
|
||||
|
||||
int col=0;
|
||||
int row=0;
|
||||
|
||||
|
||||
Label xLabel = new Label("x");
|
||||
xLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
Label yLabel = new Label("y");
|
||||
yLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
//Orientations
|
||||
|
||||
String degsLab = LatLong.deg + " ";
|
||||
|
||||
|
||||
col=1;
|
||||
positionPane.add(xLabel, col++, row);
|
||||
positionPane.add(yLabel, col++, row);
|
||||
positionPane.add(depthLabel, col++, row);
|
||||
col++;
|
||||
positionPane.add(depthSensorLabel, col++, row);
|
||||
|
||||
col=0;
|
||||
row++;
|
||||
|
||||
Label positionLabel = new Label("Position");
|
||||
positionPane.add(positionLabel, col++, row);
|
||||
positionPane.add(xPos, col++, row);
|
||||
positionPane.add(yPos, col++, row);
|
||||
positionPane.add(zPos, col++, row);
|
||||
positionPane.add(new Label("(m)"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.HEIGHT.ordinal()].getPane(), col++, row);
|
||||
|
||||
col=0;
|
||||
row++;
|
||||
|
||||
Label errLabel = new Label("Error");
|
||||
positionPane.add(errLabel, col++, row);
|
||||
positionPane.add(xPosErr, col++, row);
|
||||
positionPane.add(yPosErr, col++, row);
|
||||
positionPane.add(zPosErr, col++, row);
|
||||
positionPane.add(new Label("(m)"), col++, row);
|
||||
|
||||
//Orientation
|
||||
col=1;
|
||||
row++;
|
||||
|
||||
Label headingLabel = new Label("Heading");
|
||||
headingLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
Label pitchLabel = new Label("Pitch");
|
||||
pitchLabel.setAlignment(Pos.CENTER);
|
||||
|
||||
Label rolllabel = new Label("Roll");
|
||||
rolllabel.setAlignment(Pos.CENTER);
|
||||
|
||||
|
||||
positionPane.add(headingLabel, col++, row);
|
||||
positionPane.add(pitchLabel, col++, row);
|
||||
positionPane.add(rolllabel, col++, row);
|
||||
|
||||
row++;
|
||||
|
||||
heading = new TextField();
|
||||
heading.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(heading, "heading", validator);
|
||||
|
||||
pitch = new TextField();
|
||||
pitch.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(pitch, "pitch", validator);
|
||||
|
||||
roll = new TextField();
|
||||
roll.setMaxWidth(MAX_TEXTFIELD_WIDTH);
|
||||
HydrophoneSettingsPane.addTextValidator(roll, "roll", validator);
|
||||
|
||||
col=0;
|
||||
|
||||
Label orientation = new Label("Orientation");
|
||||
positionPane.add(orientation, col++, row);
|
||||
positionPane.add(heading, col++, row);
|
||||
positionPane.add(pitch, col++, row);
|
||||
positionPane.add(roll, col++, row);
|
||||
positionPane.add(new Label(degsLab), col++, row);
|
||||
|
||||
|
||||
positionPane.add(button, col++, row);
|
||||
|
||||
PamVBox holder= new PamVBox();
|
||||
holder.setSpacing(5);
|
||||
holder.getChildren().addAll(loclaiserMethodHolder, positionPane);
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables controls in the orientation pane.
|
||||
*/
|
||||
private void enableOrientationPane() {
|
||||
for (int i=0; i<sensorComponents.length; i++) {
|
||||
if (sensorComponents[i]==null || sensorComponents[i].getParameterType()==null) continue;
|
||||
boolean enable = sensorComponents[i].getParameterType().equals(ArrayParameterType.FIXED);
|
||||
switch (sensorComponents[i].getSensorType()) {
|
||||
case HEADING:
|
||||
heading.setDisable(!enable);
|
||||
break;
|
||||
case HEIGHT:
|
||||
break;
|
||||
case PITCH:
|
||||
pitch.setDisable(!enable);
|
||||
break;
|
||||
case ROLL:
|
||||
roll.setDisable(!enable);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a pane to set where sensor data comes from
|
||||
* @return the sensor pane.
|
||||
*/
|
||||
private Pane createSensorPane() {
|
||||
PamBorderPane pane = new PamBorderPane();
|
||||
|
||||
//hydrophone position and
|
||||
PamGridPane positionPane = new PamGridPane();
|
||||
positionPane.setHgap(5);
|
||||
positionPane.setVgap(5);
|
||||
|
||||
int col=0;
|
||||
int row=0;
|
||||
|
||||
positionPane.add(new Label("Heading"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.HEADING.ordinal()].getPane(), col++, row);
|
||||
|
||||
row++;
|
||||
col=0;
|
||||
positionPane.add(new Label("Pitch"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.PITCH.ordinal()].getPane(), col++, row);
|
||||
|
||||
row++;
|
||||
col=0;
|
||||
positionPane.add(new Label("Roll"), col++, row);
|
||||
positionPane.add(sensorComponents[ArraySensorFieldType.ROLL.ordinal()].getPane(), col++, row);
|
||||
|
||||
Label orientLabel = new Label("Orientation Data");
|
||||
PamGuiManagerFX.titleFont2style(orientLabel);
|
||||
|
||||
pane.setTop(orientLabel);
|
||||
pane.setCenter(positionPane);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new origin method.
|
||||
*/
|
||||
public void newOriginMethod() {
|
||||
|
||||
int methInd = originMethod.getSelectionModel().getSelectedIndex();
|
||||
if (methInd < 0) {
|
||||
return;
|
||||
}
|
||||
HydrophoneOriginSystem currentSystem = HydrophoneOriginMethods.getInstance().getMethod(this.originMethod.getSelectionModel().getSelectedIndex());
|
||||
currentOriginMethod = currentSystem.createMethod(currentArray, defaultStreamer);
|
||||
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.
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent();
|
||||
|
||||
if (mthDialogComponent == null) {
|
||||
originPane.getChildren().clear();
|
||||
currentOriginComponent = null;
|
||||
this.originButton.setDisable(true);
|
||||
}
|
||||
else {
|
||||
this.originButton.setDisable(false);
|
||||
Pane newComponent = mthDialogComponent.getSettingsPane();
|
||||
if (currentOriginComponent != newComponent) {
|
||||
originPane.setCenter(newComponent);
|
||||
currentOriginComponent = newComponent;
|
||||
mthDialogComponent.setParams();
|
||||
}
|
||||
}
|
||||
|
||||
enableControls();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void enableControls() {
|
||||
if (currentOriginMethod != null) {
|
||||
System.out.println("Enable: selected interp: " + interpPane.getSelectedInterpType());
|
||||
|
||||
interpPane.setAllowedValues(currentOriginMethod.getAllowedInterpolationMethods());
|
||||
System.out.println("Enable controls: " + interpPane.getSelectedInterpType());
|
||||
if (interpPane.getSelectedInterpType()<0) {
|
||||
interpPane.setSelection(0);
|
||||
}
|
||||
}
|
||||
enableOrientationPane();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Streamer getParams(Streamer currParams) {
|
||||
// System.out.println("GETPARAMS: " + currParams);
|
||||
double zCoeff = PamController.getInstance().getGlobalMediumManager().getZCoeff();
|
||||
|
||||
try {
|
||||
defaultStreamer.setX(Double.valueOf(xPos.getText()));
|
||||
defaultStreamer.setY(Double.valueOf(yPos.getText()));
|
||||
defaultStreamer.setZ(zCoeff*Double.valueOf(zPos.getText()));
|
||||
defaultStreamer.setDx(Double.valueOf(xPosErr.getText()));
|
||||
defaultStreamer.setDy(Double.valueOf(yPosErr.getText()));
|
||||
defaultStreamer.setDz(Double.valueOf(zPosErr.getText()));
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
System.err.println("Streamer getParams: There is a problem with one of the position parameters in the streamer panel");
|
||||
return null;
|
||||
}
|
||||
|
||||
defaultStreamer.setStreamerName(currParams.getStreamerName());
|
||||
int im = interpPane.getSelectedInterpType();
|
||||
System.out.println("Streamer gwetParams: Origin interpolator: " + interpPane.getSelectedInterpType());
|
||||
|
||||
if (im < 0) {
|
||||
System.err.println("Streamer getParams: There is an index problem with the interpolation selection streamer panel: index = " + im);
|
||||
}
|
||||
currentArray.setOriginInterpolation(im);
|
||||
// try {
|
||||
// streamer.setBuoyId1(Integer.valueOf(buoyId.getText()));
|
||||
// }
|
||||
// catch (NumberFormatException e) {
|
||||
// streamer.setBuoyId1(null);
|
||||
// }
|
||||
HydrophoneLocator locator = HydrophoneLocators.getInstance().
|
||||
getSystem(localiserMethod.getSelectionModel().getSelectedIndex()).getLocator(currentArray, defaultStreamer);
|
||||
if (originPane != null) {
|
||||
// MasterLocator masterLocator = currentArray.getMasterLocator();
|
||||
// int streamerIndex = currentArray.indexOfStreamer(streamer);
|
||||
// if (streamerIndex < 0) {
|
||||
// streamerIndex = currentArray.getNumStreamers();
|
||||
// }
|
||||
// masterLocator.setHydrophoneLocator(streamerIndex, locator);
|
||||
if (currentOriginMethod == null) {
|
||||
System.err.println("Streamer getParams: No hydrophoneorigin method selected in streamer panel");
|
||||
}
|
||||
}
|
||||
|
||||
OriginDialogComponent mthDialogComponent = currentOriginMethod.getDialogComponent();
|
||||
if (mthDialogComponent != null) {
|
||||
if (mthDialogComponent.getParams() == false) {
|
||||
System.err.println("Streamer: The origin settings pane returned false suggesting paramters are not correct.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// defaultStreamer.setEnableOrientation(enableOrientation.isSelected());
|
||||
// if (enableOrientation.isSelected()) {
|
||||
defaultStreamer.setHeading(getDoubleValue(heading));
|
||||
defaultStreamer.setPitch(getDoubleValue(pitch));
|
||||
defaultStreamer.setRoll(getDoubleValue(roll));
|
||||
// }
|
||||
|
||||
if (!heading.isDisable() && defaultStreamer.getHeading() == null) {
|
||||
System.err.println("Streamer getParams: You must enter a fixed value for the streamer heading");
|
||||
}
|
||||
if (!pitch.isDisable() && defaultStreamer.getPitch() == null) {
|
||||
System.err.println("Streamer getParams: You must enter a fixed value for the streamer pitch");
|
||||
}
|
||||
if (!roll.isDisable() && defaultStreamer.getRoll() == null) {
|
||||
System.err.println("Streamer getParams: You must enter a fixed value for the streamer roll");
|
||||
}
|
||||
|
||||
/**
|
||||
* We may have large lists of the streamers which we meant to use the
|
||||
* orientation data from or not. The enable orientation check box will enable or
|
||||
* disable orientation for ALL streamers which are loaded into memory.
|
||||
*/
|
||||
// System.out.println("CURRENTORIGINMETHOD: " + currentOriginMethod);
|
||||
// System.out.println("LOCATORMETHOD: " + locator);
|
||||
|
||||
defaultStreamer.setHydrophoneOrigin(currentOriginMethod);
|
||||
defaultStreamer.setHydrophoneLocator(locator);
|
||||
defaultStreamer.setOriginSettings(currentOriginMethod.getOriginSettings());
|
||||
defaultStreamer.setLocatorSettings(locator.getLocatorSettings());
|
||||
|
||||
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
|
||||
for (int i = 0; i < sensorFields.length; i++) {
|
||||
ArrayParameterType fieldType = sensorComponents[i].getParameterType();
|
||||
defaultStreamer.setOrientationTypes(sensorFields[i], fieldType);
|
||||
if (fieldType == ArrayParameterType.SENSOR) {
|
||||
PamDataBlock dataBlock = sensorComponents[i].getDataBlock();
|
||||
defaultStreamer.setSensorDataBlocks(sensorFields[i], dataBlock == null ? null : dataBlock.getLongDataName());
|
||||
}
|
||||
}
|
||||
|
||||
return defaultStreamer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(Streamer input) {
|
||||
if (input==null) {
|
||||
System.out.print("Streamer setParams: The input streamer is null");
|
||||
}
|
||||
this.defaultStreamer=input;
|
||||
// origin methods
|
||||
// MasterLocator masterLocator = currentArray.getMasterLocator();
|
||||
// int streamerIndex = currentArray.indexOfStreamer(streamer);
|
||||
HydrophoneLocator hLocator = defaultStreamer.getHydrophoneLocator();
|
||||
if (hLocator != null) {
|
||||
int locatorIndex = HydrophoneLocators.getInstance().indexOfClass(hLocator.getClass());
|
||||
localiserMethod.getSelectionModel().select(locatorIndex);
|
||||
|
||||
HydrophoneOriginMethod originMethod = defaultStreamer.getHydrophoneOrigin();
|
||||
if (originMethod != null) {
|
||||
int originIndex = HydrophoneOriginMethods.getInstance().indexOfClass(originMethod.getClass());
|
||||
this.originMethod.getSelectionModel().select(originIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
localiserMethod.getSelectionModel().select(0);
|
||||
}
|
||||
|
||||
//streamerName.setText(defaultStreamer.getStreamerName());
|
||||
xPos.setText(String.valueOf(defaultStreamer.getX()));
|
||||
yPos.setText(String.valueOf(defaultStreamer.getY()));
|
||||
zPos.setText(String.valueOf(PamController.getInstance().getGlobalMediumManager().getZCoeff()*defaultStreamer.getZ()));
|
||||
xPosErr.setText(String.valueOf(defaultStreamer.getDx()));
|
||||
yPosErr.setText(String.valueOf(defaultStreamer.getDy()));
|
||||
zPosErr.setText(String.valueOf(defaultStreamer.getDz()));
|
||||
// if (streamer.getBuoyId1() != null) {
|
||||
// buoyId.setText(streamer.getBuoyId1().toString());
|
||||
// }
|
||||
// else {
|
||||
// buoyId.setText("");
|
||||
// }
|
||||
|
||||
HydrophoneOriginMethod mth = defaultStreamer.getHydrophoneOrigin();
|
||||
if (mth==null) {
|
||||
originMethod.getSelectionModel().select(0);
|
||||
newOriginMethod();
|
||||
mth = currentOriginMethod;
|
||||
//defaultStreamer.setHydrophoneOrigin(HydrophoneOriginMethods.getInstance().getMethod(0).createMethod(currentArray, defaultStreamer));
|
||||
}
|
||||
|
||||
|
||||
OriginDialogComponent mthDialogComponent = mth.getDialogComponent();
|
||||
if (mthDialogComponent != null) {
|
||||
System.out.println("Streamer setParams: Set origin component: ");
|
||||
mthDialogComponent.setParams();
|
||||
}
|
||||
|
||||
// System.out.println("Streamer setParams: Set orientation: " + defaultStreamer.getHeading() + " " + defaultStreamer.getPitch() + " " + defaultStreamer.getRoll());
|
||||
|
||||
heading .setText(orientation2Text(defaultStreamer.getHeading()));
|
||||
pitch .setText(orientation2Text(defaultStreamer.getPitch()));
|
||||
roll .setText(orientation2Text(defaultStreamer.getRoll()));
|
||||
|
||||
System.out.println("Streamer setParams: Origin interpolator: " + currentArray.getOriginInterpolation() + " " + currentOriginMethod.getAllowedInterpolationMethods());
|
||||
|
||||
|
||||
if (currentArray.getOriginInterpolation()<0 || currentArray.getOriginInterpolation()>=currentOriginMethod.getAllowedInterpolationMethods()) {
|
||||
System.err.println("Streamer setParams: Origin interpolator value of " + currentArray.getOriginInterpolation() + " not allowed for origin method - setting to first allowed method:");
|
||||
interpPane.setSelection(0);
|
||||
}
|
||||
else {
|
||||
interpPane.setSelection(currentArray.getOriginInterpolation());
|
||||
}
|
||||
|
||||
System.out.println("Streamer setParams: selected interp: " + interpPane.getSelectedInterpType());
|
||||
|
||||
|
||||
ArraySensorFieldType[] sensorFields = ArraySensorFieldType.values();
|
||||
for (int i = 0; i < sensorFields.length; i++) {
|
||||
ArrayParameterType fieldType = defaultStreamer.getOrientationTypes(sensorFields[i]);
|
||||
String fieldDataBlock = defaultStreamer.getSensorDataBlocks(sensorFields[i]);
|
||||
sensorComponents[i].setParameterType(fieldType);
|
||||
if (fieldType == ArrayParameterType.SENSOR && fieldDataBlock != null) {
|
||||
sensorComponents[i].setDataBlock(PamController.getInstance().getDataBlockByLongName(fieldDataBlock));
|
||||
}
|
||||
}
|
||||
|
||||
setRecieverLabels() ;
|
||||
enableControls();
|
||||
|
||||
}
|
||||
|
||||
private String orientation2Text(Double ang) {
|
||||
if (ang == null) return String.valueOf(0.0);
|
||||
else return String.format("%3.1f", ang);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Streamer Pane";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
return mainPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paneInitialized() {
|
||||
|
||||
}
|
||||
|
||||
public void setRecieverLabels() {
|
||||
String recieverDepthString = PamController.getInstance().getGlobalMediumManager().getZString();
|
||||
|
||||
depthLabel.setText(recieverDepthString );
|
||||
depthSensorLabel.setText(recieverDepthString + " Sensor");
|
||||
|
||||
}
|
||||
|
||||
private Double getDoubleValue(TextField textField) {
|
||||
String txt = textField.getText();
|
||||
if (txt == null || txt.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
Double val;
|
||||
try {
|
||||
val = Double.valueOf(txt);
|
||||
return val;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
System.err.println("Invalid orientation information: " + txt);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentArray(PamArray currentArray2) {
|
||||
this.currentArray=currentArray2;
|
||||
|
||||
}
|
||||
}
|
315
src/Array/layoutFX/StreamersPane.java
Normal file
315
src/Array/layoutFX/StreamersPane.java
Normal file
@ -0,0 +1,315 @@
|
||||
package Array.layoutFX;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import Array.PamArray;
|
||||
import Array.Streamer;
|
||||
import PamController.PamController;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.control.Dialog;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.flipPane.PamFlipPane;
|
||||
import pamViewFX.fxNodes.table.TableSettingsPane;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.geometry.Insets;
|
||||
|
||||
/**
|
||||
* A pane for setting up hydrophones. Note that this is entirely separate from PAMGuard so can be used in
|
||||
* other projects.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class StreamersPane extends PamBorderPane {
|
||||
|
||||
BasicArrayTable tableArrayPane;
|
||||
|
||||
ObservableList<StreamerProperty> streamerData = FXCollections.observableArrayList();
|
||||
|
||||
/**
|
||||
* The current hydrophone array
|
||||
*/
|
||||
private PamArray currentArray;
|
||||
|
||||
/**
|
||||
* The pam flip pane.
|
||||
*/
|
||||
private PamFlipPane pamFlipePane;
|
||||
|
||||
/**
|
||||
* The current streamer data.
|
||||
*/
|
||||
private StreamerProperty currentStreamerData;
|
||||
|
||||
/**
|
||||
* Settings pane for a single hydrophone.
|
||||
*/
|
||||
private StreamerSettingsPane streamerPane = new StreamerSettingsPane();
|
||||
|
||||
/**
|
||||
* A list of listeners which are called whenever a streamer is added removed or changed.
|
||||
*/
|
||||
public ArrayList<ArrayChangeListener> streamerChangeListeners = new ArrayList<ArrayChangeListener>();
|
||||
|
||||
|
||||
public StreamersPane() {
|
||||
|
||||
tableArrayPane = new BasicArrayTable(streamerData);
|
||||
|
||||
tableArrayPane.setPadding(new Insets(5,5,5,5));
|
||||
this.setCenter(tableArrayPane);
|
||||
|
||||
pamFlipePane = new PamFlipPane();
|
||||
pamFlipePane.getAdvLabel().setText("Streamer");
|
||||
pamFlipePane.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
((Pane) streamerPane.getContentNode()).setPadding(new Insets(5,5,5,15));
|
||||
|
||||
pamFlipePane.setAdvPaneContent(streamerPane.getContentNode());
|
||||
pamFlipePane.setFrontContent(tableArrayPane);
|
||||
|
||||
pamFlipePane.getFront().setPadding(new Insets(5,5,5,10));
|
||||
pamFlipePane.setAdvLabelEditable(true);
|
||||
pamFlipePane.getPostAdvLabel().setText("Settings");
|
||||
|
||||
|
||||
pamFlipePane.backButtonProperty().addListener((obsval, oldVal, newVal)->{
|
||||
|
||||
// System.out.println("Hello back button pressed: " + newVal.intValue());
|
||||
|
||||
//the flip pane
|
||||
if (newVal.intValue()==PamFlipPane.OK_BACK_BUTTON) {
|
||||
|
||||
Streamer streamer = streamerPane.getParams(currentStreamerData.getStreamer());
|
||||
|
||||
if (streamer==null) {
|
||||
//the warning dialog is shown in the streamer settings pane
|
||||
return;
|
||||
}
|
||||
|
||||
streamer.setStreamerName(pamFlipePane.getAdvLabel().getText());
|
||||
|
||||
currentStreamerData.setStreamer(streamer);
|
||||
|
||||
notifyStreamerListeners(currentStreamerData);
|
||||
// System.out.println("Update streamer: " + tableArrayPane.getStreamers().indexOf(currentStreamerData) + " no. streamers: " + currentArray.getNumStreamers());
|
||||
|
||||
//need to refresh table to show symbol.
|
||||
tableArrayPane.getTableView().refresh();
|
||||
|
||||
if (streamer != null) {
|
||||
streamer.setupLocator(currentArray);
|
||||
streamer.makeStreamerDataUnit();
|
||||
//update the streamer in the current array
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.setCenter(pamFlipePane);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the streamer listeners of a change
|
||||
* @param streamer - the changed streamer
|
||||
*/
|
||||
public void notifyStreamerListeners(StreamerProperty streamer) {
|
||||
for (ArrayChangeListener listener: streamerChangeListeners) {
|
||||
listener.arrayChanged(ArrayChangeListener.STREAMER_CHANGE, streamer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class which extends TableSettingsPane and creates a sliding pane instead of a dialog when an item is added.
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
class BasicArrayTable extends TableSettingsPane<StreamerProperty> {
|
||||
|
||||
private TableColumn<StreamerProperty, Number> z;
|
||||
|
||||
|
||||
public BasicArrayTable(ObservableList<StreamerProperty> data) {
|
||||
super(data);
|
||||
//need to set up all the rows.
|
||||
TableColumn<StreamerProperty,Number> streamerID = new TableColumn<StreamerProperty,Number>("ID");
|
||||
streamerID.setCellValueFactory(cellData -> cellData.getValue().getID());
|
||||
streamerID.setEditable(false);
|
||||
|
||||
TableColumn<StreamerProperty,String> name = new TableColumn<StreamerProperty,String>("Name");
|
||||
name.setCellValueFactory(cellData -> cellData.getValue().getName());
|
||||
name.setEditable(true);
|
||||
|
||||
|
||||
TableColumn<StreamerProperty,Number> x = new TableColumn<StreamerProperty,Number>("x");
|
||||
x.setCellValueFactory(cellData -> cellData.getValue().getX());
|
||||
x.setEditable(false);
|
||||
|
||||
TableColumn<StreamerProperty,Number> y = new TableColumn<StreamerProperty,Number>("y");
|
||||
y.setCellValueFactory(cellData -> cellData.getValue().getY());
|
||||
y.setEditable(false);
|
||||
|
||||
z = new TableColumn<StreamerProperty,Number>("depth");
|
||||
z.setCellValueFactory(cellData -> cellData.getValue().getZ().multiply(PamController.getInstance().getGlobalMediumManager().getZCoeff()));
|
||||
z.setEditable(false);
|
||||
|
||||
TableColumn posColumn=new TableColumn("Position (m)");
|
||||
posColumn.getColumns().addAll(x, y, z);
|
||||
|
||||
TableColumn<StreamerProperty,String> reference = new TableColumn<StreamerProperty,String>("Reference");
|
||||
reference.setCellValueFactory(cellData -> cellData.getValue().getHydrophoneOrigin());
|
||||
reference.setEditable(true);
|
||||
|
||||
TableColumn<StreamerProperty,String> locator = new TableColumn<StreamerProperty,String>("Locator");
|
||||
locator.setCellValueFactory(cellData -> cellData.getValue().getHydrophineLocator());
|
||||
locator.setEditable(true);
|
||||
|
||||
TableColumn geoColumn=new TableColumn("Geo-reference");
|
||||
geoColumn.getColumns().addAll(reference, locator);
|
||||
|
||||
|
||||
getTableView().getColumns().addAll(streamerID, name, posColumn, geoColumn);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current streamers.
|
||||
* @return the current streamers.
|
||||
*/
|
||||
public ObservableList<StreamerProperty> getStreamers() {
|
||||
return getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dialogClosed(StreamerProperty data) {
|
||||
Streamer hydro = streamerPane.getParams(data.getStreamer());
|
||||
data.setStreamer(hydro);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog<StreamerProperty> createSettingsDialog(StreamerProperty data) {
|
||||
//we do not use dialogs here- sliding pane instead.
|
||||
// setClassifierPane(data);
|
||||
// showFlipPane(true);
|
||||
pamFlipePane.flipToBack();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editData(StreamerProperty data){
|
||||
//edit streamer data.
|
||||
if (data.getName() == null){
|
||||
pamFlipePane.getAdvLabel().setText("Streamer " + data.getID().get());
|
||||
}
|
||||
|
||||
streamerPane.setCurrentArray(currentArray);
|
||||
streamerPane.setParams(data.getStreamer());
|
||||
|
||||
currentStreamerData = data;
|
||||
|
||||
pamFlipePane.flipToBack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createNewData(){
|
||||
StreamerProperty newStreamer = createDefaultStreamerProperty();
|
||||
//create a new classifier.
|
||||
streamerData.add(newStreamer);
|
||||
//add to the current array.
|
||||
currentArray.addStreamer(newStreamer.getStreamer());
|
||||
System.out.println("Create new streamer: " + currentArray.getNumStreamers());
|
||||
|
||||
notifyStreamerListeners(newStreamer);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteData(StreamerProperty data){
|
||||
super.deleteData(data);
|
||||
notifyStreamerListeners(null);
|
||||
}
|
||||
|
||||
private StreamerProperty createDefaultStreamerProperty() {
|
||||
Streamer streamer = new Streamer(1, 0.,0.,0.,0.,0.,0.);
|
||||
return new StreamerProperty(streamer);
|
||||
}
|
||||
|
||||
public TableColumn<StreamerProperty, Number> getZColumn() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the parameters for the streamer pane.
|
||||
* @param currentArray - the current array.
|
||||
*/
|
||||
public void setParams(PamArray currentArray) {
|
||||
|
||||
this.currentArray=currentArray.clone();
|
||||
|
||||
System.out.println("Set params streamer: " + currentArray.getNumStreamers());
|
||||
|
||||
tableArrayPane.getStreamers().clear();
|
||||
|
||||
for (int i=0; i<currentArray.getStreamerCount(); i++) {
|
||||
tableArrayPane.getStreamers().add(new StreamerProperty(currentArray.getStreamer(i)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parameters from the streamer pane.
|
||||
* @param currParams - the current parameters.
|
||||
* @return the PamArray with updated streamers.
|
||||
*/
|
||||
public PamArray getParams(PamArray currParams) {
|
||||
|
||||
//add all new streamers - bit weird because the PamArray requires that at least one streamer exists.
|
||||
|
||||
for (int i=0; i<tableArrayPane.getStreamers().size(); i++) {
|
||||
|
||||
if (i<currentArray.getStreamerCount()) {
|
||||
currParams.updateStreamer(i,tableArrayPane.getStreamers().get(i).getStreamer());
|
||||
}
|
||||
else {
|
||||
currParams.addStreamer(tableArrayPane.getStreamers().get(i).getStreamer());
|
||||
}
|
||||
}
|
||||
|
||||
while (currParams.getStreamerCount()>tableArrayPane.getStreamers().size()) {
|
||||
currParams.removeStreamer(currParams.getStreamerCount()-1);
|
||||
}
|
||||
|
||||
// currentArray.updateStreamer(tableArrayPane.getStreamers().indexOf(currentStreamerData), streamer);
|
||||
|
||||
return currParams;
|
||||
}
|
||||
|
||||
public void setRecieverLabels() {
|
||||
tableArrayPane.getZColumn().setText(PamController.getInstance().getGlobalMediumManager().getZString());
|
||||
streamerPane.setRecieverLabels();
|
||||
}
|
||||
|
||||
public TableView<StreamerProperty> getStreamerTable() {
|
||||
return tableArrayPane.getTableView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener which is called whenever a streamer is added, removed or changed.
|
||||
* @param e - the listener to add
|
||||
*/
|
||||
public void addStreamerListener(ArrayChangeListener e) {
|
||||
this.streamerChangeListeners.add(e);
|
||||
}
|
||||
|
||||
public void setCurrentArray(PamArray currentArray) {
|
||||
this.currentArray=currentArray;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,7 +1,15 @@
|
||||
package Array.streamerOrigin;
|
||||
|
||||
import PamView.dialog.DialogComponent;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public abstract class OriginDialogComponent implements DialogComponent{
|
||||
|
||||
/**
|
||||
* Get a JavaFX pane for the origin method.
|
||||
* @return the JavaFX pane.
|
||||
*/
|
||||
public abstract Pane getSettingsPane();
|
||||
|
||||
|
||||
}
|
||||
|
97
src/Array/streamerOrigin/StaticHydrophonePane.java
Normal file
97
src/Array/streamerOrigin/StaticHydrophonePane.java
Normal file
@ -0,0 +1,97 @@
|
||||
package Array.streamerOrigin;
|
||||
|
||||
import GPS.GpsData;
|
||||
import GPS.GpsDataUnit;
|
||||
import PamUtils.LatLong;
|
||||
import javafx.scene.control.Label;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.utilityPanes.LatLongPane;
|
||||
|
||||
/**
|
||||
* JavaFX settings pane for a static hydrophones.
|
||||
*/
|
||||
public class StaticHydrophonePane extends PamBorderPane {
|
||||
|
||||
/**
|
||||
* Reference to static origin mwthod.
|
||||
*/
|
||||
private StaticOriginMethod staticOriginMethod;
|
||||
|
||||
LatLongPane latLongPane;
|
||||
|
||||
public StaticHydrophonePane(StaticOriginMethod staticOriginMethod) {
|
||||
|
||||
this.staticOriginMethod=staticOriginMethod;
|
||||
|
||||
latLongPane = new LatLongPane("Static streamer position");
|
||||
this.setCenter(latLongPane.getContentNode());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void setParams() {
|
||||
GpsDataUnit dataUnit = getStaticOriginSettings().getStaticPosition();
|
||||
if (dataUnit == null) {
|
||||
setLatLong(null);
|
||||
}
|
||||
else {
|
||||
GpsData gpsData = dataUnit.getGpsData();
|
||||
setLatLong(gpsData);
|
||||
}
|
||||
|
||||
// if (gpsData == null) {
|
||||
// return;
|
||||
// }
|
||||
// else {
|
||||
// setLatLong(gpsData);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
private StaticOriginSettings getStaticOriginSettings() {
|
||||
return ((StaticOriginSettings) staticOriginMethod.getOriginSettings());
|
||||
}
|
||||
|
||||
|
||||
public boolean getParams() {
|
||||
|
||||
LatLong latLong = latLongPane.getParams(null);
|
||||
|
||||
if (latLong==null) {
|
||||
System.err.println("StaticHydrophonePane: latitude and longitude is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getStaticOriginSettings()==null) {
|
||||
System.err.println("StaticHydrophonePane: static origin is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
//set
|
||||
getStaticOriginSettings().setStaticPosition(staticOriginMethod.getStreamer(), new GpsData(latLong));
|
||||
//
|
||||
// boolean ok = getStaticOriginSettings()!= null && getStaticOriginSettings() .getStaticPosition() != null;
|
||||
//
|
||||
// System.out.println("StaticHydrophonePane: Get params from static origin 1 : " + getStaticOriginSettings());
|
||||
//
|
||||
// System.out.println("StaticHydrophonePane: Get params from static origin 2: " + getStaticOriginSettings() .getStaticPosition());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just set the lat long without resetting the heading.
|
||||
* @param latLong
|
||||
*/
|
||||
private void setLatLong(LatLong latLong) {
|
||||
if (latLong==null) {
|
||||
//create a default latitude and longitude - Rockall (why not).
|
||||
LatLong latLongdefault = new LatLong();
|
||||
latLongdefault.setLatitude(57.595833333333);
|
||||
latLongdefault.setLongitude(-13.686944444444);
|
||||
latLongPane.setParams(latLongdefault);
|
||||
}
|
||||
else latLongPane.setParams(latLong);
|
||||
}
|
||||
|
||||
}
|
@ -29,10 +29,11 @@ import PamUtils.LatLongDialog;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamView.dialog.PamDialog;
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
import javafx.scene.layout.Pane;
|
||||
|
||||
public class StaticOriginMethod extends HydrophoneOriginMethod {
|
||||
|
||||
private StaticHydrophoneDialogComponent staticHydrophoneDialogComponent;
|
||||
private StaticHydrophoneComponent staticHydrophoneDialogComponent;
|
||||
|
||||
private StaticOriginSettings staticOriginSettings = new StaticOriginSettings();
|
||||
|
||||
@ -48,12 +49,107 @@ public class StaticOriginMethod extends HydrophoneOriginMethod {
|
||||
@Override
|
||||
public OriginDialogComponent getDialogComponent() {
|
||||
if (staticHydrophoneDialogComponent == null) {
|
||||
staticHydrophoneDialogComponent = new StaticHydrophoneDialogComponent();
|
||||
staticHydrophoneDialogComponent = new StaticHydrophoneComponent();
|
||||
}
|
||||
return staticHydrophoneDialogComponent;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OriginSettings getOriginSettings() {
|
||||
return staticOriginSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOriginSettings(OriginSettings originSettings) {
|
||||
staticOriginSettings = (StaticOriginSettings) originSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepare() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamerDataUnit getLastStreamerData() {
|
||||
StreamerDataBlock streamerDataBlock = ArrayManager.getArrayManager().getStreamerDatabBlock();
|
||||
StreamerDataUnit sdu = streamerDataBlock.getLastUnit(1<<streamer.getStreamerIndex());
|
||||
if (sdu == null) {
|
||||
sdu = new StreamerDataUnit(PamCalendar.getTimeInMillis(), streamer);
|
||||
//System.out.println("StaticOriginMethod: Streamer rotation: " +sdu.getGpsData().getQuaternion().toHeading());
|
||||
}
|
||||
return sdu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OriginIterator getGpsDataIterator(int wherefrom) {
|
||||
return new StreamerDataIterator(wherefrom, streamer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSynchronizationObject() {
|
||||
return NavDataSynchronisation.getSynchobject();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GUI components for the static hydrophone locator. This returns a JavaFX or Swing component depending on the current GUI.
|
||||
*/
|
||||
private class StaticHydrophoneComponent extends OriginDialogComponent {
|
||||
|
||||
/**
|
||||
* Swing component.
|
||||
*/
|
||||
private StaticHydrophoneDialogComponent staticHydrophoneDialog;
|
||||
|
||||
/**
|
||||
* JavaFX pane for static hydrophones.
|
||||
*/
|
||||
private StaticHydrophonePane staticHydrophonePane;
|
||||
|
||||
|
||||
@Override
|
||||
public JComponent getComponent(Window owner) {
|
||||
if (staticHydrophoneDialog==null) {
|
||||
staticHydrophoneDialog = new StaticHydrophoneDialogComponent();
|
||||
}
|
||||
return staticHydrophoneDialog.getComponent(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams() {
|
||||
if (staticHydrophoneDialog!=null) {
|
||||
staticHydrophoneDialog.setParams();
|
||||
}
|
||||
if (staticHydrophonePane!=null) {
|
||||
staticHydrophonePane.setParams();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getParams() {
|
||||
if (staticHydrophoneDialog!=null) {
|
||||
return staticHydrophoneDialog.getParams();
|
||||
}
|
||||
if (staticHydrophonePane!=null) {
|
||||
return staticHydrophonePane.getParams();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getSettingsPane() {
|
||||
if (staticHydrophonePane==null) {
|
||||
staticHydrophonePane = new StaticHydrophonePane(StaticOriginMethod.this);
|
||||
}
|
||||
return staticHydrophonePane;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Swing components for the static hydrophone locator.
|
||||
*/
|
||||
private class StaticHydrophoneDialogComponent extends OriginDialogComponent {
|
||||
|
||||
private JPanel outerPanel;
|
||||
@ -268,41 +364,12 @@ public class StaticOriginMethod extends HydrophoneOriginMethod {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pane getSettingsPane() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OriginSettings getOriginSettings() {
|
||||
return staticOriginSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOriginSettings(OriginSettings originSettings) {
|
||||
staticOriginSettings = (StaticOriginSettings) originSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepare() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamerDataUnit getLastStreamerData() {
|
||||
StreamerDataBlock streamerDataBlock = ArrayManager.getArrayManager().getStreamerDatabBlock();
|
||||
StreamerDataUnit sdu = streamerDataBlock.getLastUnit(1<<streamer.getStreamerIndex());
|
||||
if (sdu == null) {
|
||||
sdu = new StreamerDataUnit(PamCalendar.getTimeInMillis(), streamer);
|
||||
//System.out.println("StaticOriginMethod: Streamer rotation: " +sdu.getGpsData().getQuaternion().toHeading());
|
||||
}
|
||||
return sdu;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OriginIterator getGpsDataIterator(int wherefrom) {
|
||||
return new StreamerDataIterator(wherefrom, streamer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getSynchronizationObject() {
|
||||
return NavDataSynchronisation.getSynchobject();
|
||||
}
|
||||
}
|
||||
|
@ -267,6 +267,9 @@ public class GPSControl extends PamControlledUnit implements PamSettings, Positi
|
||||
GpsDataUnit pointBefore = null, pointAfter = null;
|
||||
synchronized (getGpsDataBlock().getSynchLock()) {
|
||||
ListIterator<GpsDataUnit> iter = getGpsDataBlock().getListIterator(timeMilliseconds, 0, PamDataBlock.MATCH_BEFORE, PamDataBlock.POSITION_BEFORE);
|
||||
if (iter == null) {
|
||||
return null;
|
||||
}
|
||||
if (iter.hasNext()) {
|
||||
pointBefore = iter.next();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public interface LocaliserModel<T extends PamDataUnit> {
|
||||
public String getToolTipText();
|
||||
|
||||
/**
|
||||
* The type of localisation information the localizer can accept. e.g. bearings, time delays etc. The types are
|
||||
* The type of localisation information the localiser can accept. e.g. bearings, time delays etc. The types are
|
||||
* defined in the AbstractLocalisation class.
|
||||
* @return integer bitmap of the type of localisation information the localiser can use.
|
||||
*/
|
||||
@ -35,13 +35,13 @@ public interface LocaliserModel<T extends PamDataUnit> {
|
||||
|
||||
/**
|
||||
* Get the settings pane for the localiser. Allows users to change localiser settings.
|
||||
* @return the settings pane for the loclaiser.
|
||||
* @return the settings pane for the localiser.
|
||||
*/
|
||||
public LocaliserPane<?> getSettingsPane();
|
||||
public LocaliserPane<?> getAlgorithmSettingsPane();
|
||||
|
||||
|
||||
/**
|
||||
* True if the model has paramaters to set. If has the loclaiser has a settings pane it will have
|
||||
* True if the model has parameters to set. If has the localiser has a settings pane it will have
|
||||
* parameters. This generally puts an extra button onto a display panel.
|
||||
*/
|
||||
public boolean hasParams();
|
||||
@ -56,7 +56,7 @@ public interface LocaliserModel<T extends PamDataUnit> {
|
||||
public AbstractLocalisation runModel(T pamDataUnit, DetectionGroupOptions detectionGroupOptions, boolean addLoc);
|
||||
|
||||
/**
|
||||
* This should be called whenever the localiser has finished processing and, if the loclaisation process is long, then updates progress.
|
||||
* This should be called whenever the localiser has finished processing and, if the localisation process is long, then updates progress.
|
||||
*/
|
||||
public void notifyModelProgress(double progress);
|
||||
|
||||
|
@ -1,5 +1,17 @@
|
||||
package Localiser;
|
||||
|
||||
public interface LocaliserPane<T> {
|
||||
import PamController.SettingsPane;
|
||||
|
||||
public abstract class LocaliserPane<T> extends SettingsPane<T> {
|
||||
|
||||
public LocaliserPane() {
|
||||
super(null);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -152,8 +152,7 @@ public class ModelControlPanel {
|
||||
@Override
|
||||
//settings panel
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
model.getSettingsPane();
|
||||
|
||||
model.getAlgorithmSettingsPane();
|
||||
//AWT implementation.
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +258,8 @@ public class Correlations {
|
||||
correlationValue = newPeak[1];
|
||||
return newPeak[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Measure the time delay between pulses on two channels. Inputs in this case are the
|
||||
* spectrum data (most of the cross correlation is done in the frequency domain)<p>
|
||||
|
@ -185,7 +185,7 @@ public class Chi2TimeDelays implements MinimisationFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time delays. Each row is a set fo delays from N synchronised hydrophones. Different rows
|
||||
* Set the time delays. Each row is a set for delays from N synchronised hydrophones. Different rows
|
||||
* can have different numbers of synchronised hydrophones.
|
||||
* @param timeDelays - a set of time delays in seconds.
|
||||
*/
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user