Squashed commit of the following:

commit 34ba7ebceb
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Aug 23 09:15:40 2024 +0100

    Merge from DG (#150)

    * Localization output

    * update localiser output

    * Start effort management system

    * Start of Effort plotting

    Strat of effort plotting on map. Framework for using Effort data in other areas (such as Tethys output).

    * Logger forms update

    Effort and Symbol selectors working with Logger forms. Also functions to add, edit and delete form rows in Viewer mode.

    * Update LoggerFormGraphics.java

    add in correct symbol managemet to forms graphics.

    * Effort lines on map

    Sort of working OK in real time mode.

    * Working effort system

    Currently only for map, but seems to work OK

    * Update Tethys to latest nilus schema

    * Raven importer

    Start of a system for a raven importer. Not quite working yet.

    * Raven import

    Basic functionality working. Not nice to use though.

    * Tethys Localization work

    Abstracting out writing of localization objects and document header information so that individual localisers can give fine scale control of this stuff.

    * updated Nilus

    A few updates around track and target motion measures.

    * FX Plot for raven data

    Also sorted out symbols a bit and improved symbol selector in Generic plots.

    * Update spectrogram mark bearing display

    Remove the 90-angle bit

    * Raven extra columns

    Logging of data from additional Raven table columns

commit cb1b28423e
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Aug 19 15:55:25 2024 +0100

    updates ready for 2.2.12

commit 4829b46b36
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Aug 19 11:54:24 2024 +0100

    Merge from DG (#149)

    * Localization output

    * update localiser output

    * Start effort management system

    * Start of Effort plotting

    Strat of effort plotting on map. Framework for using Effort data in other areas (such as Tethys output).

    * Logger forms update

    Effort and Symbol selectors working with Logger forms. Also functions to add, edit and delete form rows in Viewer mode.

    * Update LoggerFormGraphics.java

    add in correct symbol managemet to forms graphics.

    * Effort lines on map

    Sort of working OK in real time mode.

    * Working effort system

    Currently only for map, but seems to work OK

    * Update Tethys to latest nilus schema

    * Raven importer

    Start of a system for a raven importer. Not quite working yet.

    * Raven import

    Basic functionality working. Not nice to use though.

    * Tethys Localization work

    Abstracting out writing of localization objects and document header information so that individual localisers can give fine scale control of this stuff.

    * updated Nilus

    A few updates around track and target motion measures.

    * FX Plot for raven data

    Also sorted out symbols a bit and improved symbol selector in Generic plots.

    * Update spectrogram mark bearing display

    Remove the 90-angle bit

commit 507ff9e28d
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Sat Aug 17 14:34:54 2024 +0100

    Merge from DG (#148)

    * Localization output

    * update localiser output

    * Start effort management system

    * Start of Effort plotting

    Strat of effort plotting on map. Framework for using Effort data in other areas (such as Tethys output).

    * Logger forms update

    Effort and Symbol selectors working with Logger forms. Also functions to add, edit and delete form rows in Viewer mode.

    * Update LoggerFormGraphics.java

    add in correct symbol managemet to forms graphics.

    * Effort lines on map

    Sort of working OK in real time mode.

    * Working effort system

    Currently only for map, but seems to work OK

    * Update Tethys to latest nilus schema

    * Raven importer

    Start of a system for a raven importer. Not quite working yet.

    * Raven import

    Basic functionality working. Not nice to use though.

    * Tethys Localization work

    Abstracting out writing of localization objects and document header information so that individual localisers can give fine scale control of this stuff.

    * updated Nilus

    A few updates around track and target motion measures.

    * FX Plot for raven data

    Also sorted out symbols a bit and improved symbol selector in Generic plots.

commit 51757499d4
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Aug 16 10:44:54 2024 +0100

    Merge from DG (#147)

    * Localization output

    * update localiser output

    * Start effort management system

    * Start of Effort plotting

    Strat of effort plotting on map. Framework for using Effort data in other areas (such as Tethys output).

    * Logger forms update

    Effort and Symbol selectors working with Logger forms. Also functions to add, edit and delete form rows in Viewer mode.

    * Update LoggerFormGraphics.java

    add in correct symbol managemet to forms graphics.

    * Effort lines on map

    Sort of working OK in real time mode.

    * Working effort system

    Currently only for map, but seems to work OK

    * Update Tethys to latest nilus schema

    * Raven importer

    Start of a system for a raven importer. Not quite working yet.

    * Raven import

    Basic functionality working. Not nice to use though.

    * Tethys Localization work

    Abstracting out writing of localization objects and document header information so that individual localisers can give fine scale control of this stuff.

    * updated Nilus

    A few updates around track and target motion measures.

commit 46bd88c197
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Aug 16 10:40:00 2024 +0100

    Merge Tethys updates from DG (#146)

    * Localization output

    * update localiser output

    * Start effort management system

    * Start of Effort plotting

    Strat of effort plotting on map. Framework for using Effort data in other areas (such as Tethys output).

    * Logger forms update

    Effort and Symbol selectors working with Logger forms. Also functions to add, edit and delete form rows in Viewer mode.

    * Update LoggerFormGraphics.java

    add in correct symbol managemet to forms graphics.

    * Effort lines on map

    Sort of working OK in real time mode.

    * Working effort system

    Currently only for map, but seems to work OK

    * Update Tethys to latest nilus schema

    * Raven importer

    Start of a system for a raven importer. Not quite working yet.

    * Raven import

    Basic functionality working. Not nice to use though.

    * Tethys Localization work

    Abstracting out writing of localization objects and document header information so that individual localisers can give fine scale control of this stuff.

    * updated Nilus

    A few updates around track and target motion measures.

commit bea4a544d0
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 8 14:27:05 2024 +0100

    Merge from DG (#145)

    * Localization output

    * update localiser output

commit adf4c87781
Merge: 62121bdb 29293725
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 8 09:29:24 2024 +0100

    Merge branch 'main' into main

commit 2929372533
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Aug 5 17:58:08 2024 +0100

    Tethys Localisation output

    Not all types, but getting there.

commit 62121bdbbd
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Sun Aug 4 11:41:08 2024 +0100

    update jserialcom to 2.11.0

commit 82adc06e3d
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Aug 2 15:26:49 2024 +0100

    Merge DG branch (#144)

    * Refactoring Tethys

    A lot of refactoring of Nilus wrappers with more useful Objects for PAMGUard to work with.

    * Improved document handling

    Abstracted wrapper around nilus documents which allows easyish calling of internal functions in Localize and Detections document without a common base class.

    * Fix doc deletion in detector output panel

commit 36455153a2
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 30 16:34:35 2024 +0100

    Fix doc deletion in detector output panel

commit bc686c0fe6
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 26 16:12:54 2024 +0100

    Improved document handling

    Abstracted wrapper around nilus documents which allows easyish calling of internal functions in Localize and Detections document without a common base class.

commit 4f87b7b661
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 16:07:33 2024 +0100

    Refactoring Tethys

    A lot of refactoring of Nilus wrappers with more useful Objects for PAMGUard to work with.

commit 3abaff0379
Merge: a3f41e22 9eee7434
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 13:50:49 2024 +0100

    Merge pull request #86 from PAMGuard/main

    Merge from main

commit 9eee7434de
Merge: 32c7c9b2 a3f41e22
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 13:50:38 2024 +0100

    Merge branch 'main' into main

commit 32c7c9b263
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 11:55:06 2024 +0100

    Merge from Jamie (#143)

    * Working on the exporter

    * Working out on exporter

    * Working on new symbol options for deep learning and sud file options in SoundAcquisition GUI

    * Add zero pad option for sud files.

    * Updates to sud zero pad options on FX GUI

    * Implementing a data selector for the deep learning module

    * Bug fix to data transforms if the wave data and sample length are different

    * Updated POm to ignore test resources and updates to DL data selector

    * Updates to DL data selector and POM

    * Work on the data selector for the deep learning module.

    * Working on the exporter

    * Working out on exporter

    * Working on new symbol options for deep learning and sud file options in SoundAcquisition GUI

    * Add zero pad option for sud files.

    * Updates to sud zero pad options on FX GUI

    * Implementing a data selector for the deep learning module

    * Updated POm to ignore test resources and updates to DL data selector

    * Bug fix to data transforms if the wave data and sample length are different

    * Updates to DL data selector and POM

    * Work on the data selector for the deep learning module.

    * Data selectors for deep learning models now working with FX

    Still have to be implemented in Swing

    * Update deep_learning_help.md

    Updated help values to have some info on data selectors and symbol managers.

    * Updates to deep learning symbol options for swing and data selector panel for swing

    Made tooltips last longer on TD display  FX

    * Update deep_learning_help.md

    * Swing symbol modifiers for DL and peak freq

    * Squashed commit of the following:

    commit bad2255710
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Thu Jul 18 09:47:47 2024 +0100

        Better symbol options

        Add clearer options button to multi option symbol manager panel.

    * Fix bugs in detection display

    * Bug fix to hiding panes

    * Squashed commit of the following:

    commit 8b5b5b2f18
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Fri Jul 19 17:14:28 2024 +0100

        Updated data selectors for BT display

        Merging old status bar and new DataSelector options so that they work more consistently on the BT display.

    commit bad2255710
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Thu Jul 18 09:47:47 2024 +0100

        Better symbol options

        Add clearer options button to multi option symbol manager panel.

    * Deep learning bug fix

    * Ignore the class path

    * Squashed commit of the following:

    commit 577670ccd0
    Merge: 6510d226 8b5b5b2f
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Mon Jul 22 09:35:01 2024 +0100

        Merge branch 'main' of https://github.com/PAMGuard/PAMGuard

    commit 6510d2260e
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Mon Jul 22 09:34:58 2024 +0100

        Remove unnecessary text output

    commit 3da8401756
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Mon Jul 22 09:29:38 2024 +0100

        updates to Daq

        New DLL, and some LED control, but hasn't fixed stalling problem.

    commit 8b5b5b2f18
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Fri Jul 19 17:14:28 2024 +0100

        Updated data selectors for BT display

        Merging old status bar and new DataSelector options so that they work more consistently on the BT display.

    commit bad2255710
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Thu Jul 18 09:47:47 2024 +0100

        Better symbol options

        Add clearer options button to multi option symbol manager panel.

    * Squashed commit of the following:

    commit 687220dad5
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Mon Jul 22 11:42:19 2024 +0100

        Change click data selector

        Change Click BT display so it can handle CompoundDataSelectors

    commit 577670ccd0
    Merge: 6510d226 8b5b5b2f
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Mon Jul 22 09:35:01 2024 +0100

        Merge branch 'main' of https://github.com/PAMGuard/PAMGuard

    commit 6510d2260e
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Mon Jul 22 09:34:58 2024 +0100

        Remove unnecessary text output

    commit 3da8401756
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Mon Jul 22 09:29:38 2024 +0100

        updates to Daq

        New DLL, and some LED control, but hasn't fixed stalling problem.

    commit 8b5b5b2f18
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Fri Jul 19 17:14:28 2024 +0100

        Updated data selectors for BT display

        Merging old status bar and new DataSelector options so that they work more consistently on the BT display.

    commit bad2255710
    Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
    Date:   Thu Jul 18 09:47:47 2024 +0100

        Better symbol options

        Add clearer options button to multi option symbol manager panel.

    ---------

    Co-authored-by: Jamie Mac <macster110@gmail.com>

commit 687220dad5
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 11:42:19 2024 +0100

    Change click data selector

    Change Click BT display so it can handle CompoundDataSelectors

commit 577670ccd0
Merge: 6510d226 8b5b5b2f
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 09:35:01 2024 +0100

    Merge branch 'main' of https://github.com/PAMGuard/PAMGuard

commit 6510d2260e
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 09:34:58 2024 +0100

    Remove unnecessary text output

commit 3da8401756
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jul 22 09:29:38 2024 +0100

    updates to Daq

    New DLL, and some LED control, but hasn't fixed stalling problem.

commit 8b5b5b2f18
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 19 17:14:28 2024 +0100

    Updated data selectors for BT display

    Merging old status bar and new DataSelector options so that they work more consistently on the BT display.

commit bad2255710
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Jul 18 09:47:47 2024 +0100

    Better symbol options

    Add clearer options button to multi option symbol manager panel.

commit a3f41e22e6
Merge: 0165982a f7be084e
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 16 10:58:25 2024 +0100

    Merge pull request #85 from PAMGuard/main

    Fix vector error

commit 0165982a22
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 12 16:57:28 2024 +0100

    Work on localisation export

    Not ready to rock yet.

commit f24dd9bb91
Merge: 07f4398a 3f23474e
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 12 16:38:11 2024 +0100

    Merge pull request #84 from PAMGuard/main

    Merge from main

commit 07f4398a1d
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jun 25 09:25:10 2024 +0100

    Update .classpath

    Fix classpath file

commit 32ab9f7ead
Merge: 3a42eabd 7accb79f
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jun 24 15:43:47 2024 +0100

    Merge pull request #83 from PAMGuard/main

    V2.02.12

commit 3a42eabd74
Merge: 18a507b5 f7b4f44e
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Jun 24 13:58:16 2024 +0100

    Merge pull request #82 from PAMGuard/main

    Merge from main
This commit is contained in:
Jamie Mac 2024-08-23 10:55:40 +01:00
parent 6410dd8cf0
commit f4844e8fcd
165 changed files with 7080 additions and 1068 deletions

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
org.eclipse.jdt.ui.exception.name=e
org.eclipse.jdt.ui.gettersetter.use.is=true
org.eclipse.jdt.ui.keywordthis=false
org.eclipse.jdt.ui.overrideannotation=true

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a:clrMap xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" bg1="lt1" tx1="dk1" bg2="lt2" tx2="dk2" accent1="accent1" accent2="accent2" accent3="accent3" accent4="accent4" accent5="accent5" accent6="accent6" hlink="hlink" folHlink="folHlink"/>

BIN
README.files/themedata.thmx Normal file

Binary file not shown.

View File

@ -388,7 +388,7 @@ 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.11_April">Latest
Version 2.02.12 June 2024</a></span></em></h1>
Version 2.02.12 August 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>
@ -461,11 +461,11 @@ Version 2.00.10 June 2017</a></span></h1>
<h1><span style='font-size:12.0pt'><a href="#_Older_Versions">Older Versions</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><a name="_Version_2.02.11_April"></a>Version
2.02.12 June 2024</h1>
<h1><a name="_Hlk174698335"></a><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><a
name="_Version_2.02.11_April"></a>Version 2.02.12 August 2024</h1>
<p class=MsoNormal>&nbsp;</p>
@ -483,12 +483,18 @@ continually reset them. </p>
project information to store with your data. See menu item Settings/Project
information.</p>
<p class=MsoNormal>Effort management system. New map options allow colouring
of track line by effort from various other modules. This is currently the
acquisition system (so the track will change colour when PAMGuard is running),
the binary store system (likely the same as the acquisition) or data from Logger
forms. This system will be extended to other modules in the near future. </p>
<h2>Tethys Database</h2>
<p class=MsoNormal>Many users will be aware that were integrating an interface
to the <a href="https://tethys.sdsu.edu/">Tethys Database</a> into PAMGuard.
Some basic features are available for testing. If interested, please contact
the PAMGuard support team. </p>
to the <a href="https://tethys.sdsu.edu/">Tethys Database</a> into PAMGuard. Some
basic features are available for testing. If interested, please contact the
PAMGuard support team. </p>
<h2>Bug Fixes</h2>
@ -532,6 +538,9 @@ exact times, rather than a couple of seconds after the hour. </p>
<p class=MsoNormal>Updated icons to improve display on high definition screens.
</p>
<p class=MsoNormal>SAIL Daq Card. Automatic restart when DAQ card stalls
(happening increasingly often with latest Windows updates)</p>
<h1>Version 2.02.10 January 2024</h1>
<h2><span lang=EN-US>New Features</span></h2>
@ -1026,11 +1035,10 @@ help</a>. </p>
<h1><a name="_Latest_Beta_Version_2.01.05"></a><span lang=EN-US>Latest Version
2.01.05 October 2020</span></h1>
<p class=MsoNormal><b>If you are upgrading from a PAMGuard core release
(1.15.xx), PAMGuard Version 2 contains major updates. You should read and
understand the notes listed for <a href="#_Latest_Beta_Version_2.00.10">Beta
Version 2.00.10</a> before proceeding with installation and use of this
version.</b></p>
<p class=MsoNormal><b>If you are upgrading from a PAMGuard core release (1.15.xx),
PAMGuard Version 2 contains major updates. You should read and understand the
notes listed for <a href="#_Latest_Beta_Version_2.00.10">Beta Version 2.00.10</a>
before proceeding with installation and use of this version.</b></p>
<p class=MsoNormal>This version of PAMGuard has been bundled with Java 13
(release 13.0.1). PSFX files generated in previous beta releases (2.xx.xx)
@ -1163,8 +1171,8 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nb
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>Bug
&nbsp; 456. Under certain conditions, the Ishmael detection plugin that is shown
at the bottom of the spectrogram can disappear about 500 msec behind the
&nbsp; 456. Under certain conditions, the Ishmael detection plugin that is
shown at the bottom of the spectrogram can disappear about 500 msec behind the
current time. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>5. </span><span
@ -1428,8 +1436,8 @@ classify clicks. </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'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
lang=EN-US> </span>Added option in Sound Acquisition settings dialog to override
filename time stamp and use PC local time instead. </p>
lang=EN-US> </span>Added option in Sound Acquisition settings dialog to
override filename time stamp and use PC local time instead. </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'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
@ -2340,8 +2348,8 @@ the new version. However please note the following:</span></p>
<p class=MsoListParagraph style='margin-left:54.0pt;text-indent:-36.0pt'><span
lang=EN-US>1.</span><span lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span><span lang=EN-US>New classes will be added to the configuration files, so
they will no longer work with older PAMGuard versions.</span></p>
</span><span lang=EN-US>New classes will be added to the configuration files,
so they will no longer work with older PAMGuard versions.</span></p>
<p class=MsoListParagraph style='margin-left:54.0pt;text-indent:-36.0pt'><span
lang=EN-US>2.</span><span lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -2464,8 +2472,8 @@ milliseconds. However, getDuration actually returns the number of samples.
<p class=MsoNormal><b><span lang=EN-US>Plug-Ins</span></b></p>
<p class=MsoNormal><span lang=EN-US>A major change in this version of PAMGuard is
how plug-ins are managed. PAMGuard now has the ability to dynamically load
<p class=MsoNormal><span lang=EN-US>A major change in this version of PAMGuard
is how plug-ins are managed. PAMGuard now has the ability to dynamically load
plug-in modules (saved as jar files) at runtime. This will greatly simplify the
process of testing and distributing newly developed modules, since only a small
jar file will be required rather than a new bespoke PAMGuard installation.</span></p>
@ -2474,9 +2482,9 @@ jar file will be required rather than a new bespoke PAMGuard installation.</span
unchanged, in most cases simply requiring the addition of an interface class.
&nbsp;Instructions for the development of new modules utilizing the plug-in
scheme can be found <a href="http://www.pamguard.org/16_HowtomakePlug-Ins.html"
target="_blank">here</a>. &nbsp;Plug-in modules can be downloaded from the PAMGuard
website here, but developers are encouraged to host and maintain their own
modules.</span></p>
target="_blank">here</a>. &nbsp;Plug-in modules can be downloaded from the
PAMGuard website here, but developers are encouraged to host and maintain their
own modules.</span></p>
<p class=MsoNormal><span lang=EN-US>Modules of interest to the general PAM
community will remain as part of the core PAMGuard installation. However,
@ -2797,9 +2805,9 @@ easy to understand options have been developed in a new options dialog.</p>
<p class=MsoListParagraph style='margin-left:38.25pt;text-indent:-20.25pt'>9.<span
style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Bug 281. Click classification dialog has grown too big to fit on the
screen. The options have now been split across three tabbed panes which solves
the problem.</p>
</span>Bug 281. Click classification dialog has grown too big to fit on the screen.
The options have now been split across three tabbed panes which solves the
problem.</p>
<p class=MsoListParagraph style='margin-left:38.25pt;text-indent:-20.25pt'>10.<span
style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;
@ -3103,10 +3111,10 @@ href="https://sourceforge.net/p/pamguard/bugs">https://sourceforge.net/p/pamguar
<p class=MsoListParagraph style='margin-left:47.25pt;text-indent:-29.25pt'><span
lang=EN-US>1.</span><span lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Spectrogram annotation marks. A simple system for marking spectrograms
during real time analysis has been incorporated. To use it, add the module, in
the spectrogram settings, select the annotation marks in the 'Mark Observers'
tab of the spectrogram configuration dialog, and also right click on the
</span>Spectrogram annotation marks. A simple system for marking spectrograms during
real time analysis has been incorporated. To use it, add the module, in the
spectrogram settings, select the annotation marks in the 'Mark Observers' tab
of the spectrogram configuration dialog, and also right click on the
spectrogram and select to display the annotations. Annotations are saved to the
database so you will also need a database module in your configuration. &nbsp;</p>
@ -3376,9 +3384,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>
@ -3908,11 +3916,11 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
<p class=MsoNormal>2. Improved offline viewer functionality. </p>
<p class=MsoNormal>The offline viewer is much improved with better data scrolling
and the ability to view data either stored in the database or the binary
storage system. Work has stated on functions which read and use data stored in
audio files. This is currently limited to re-calculating and displaying
displaying spectrogram data during viewer mode operation.&nbsp; </p>
<p class=MsoNormal>The offline viewer is much improved with better data
scrolling and the ability to view data either stored in the database or the
binary storage system. Work has stated on functions which read and use data
stored in audio files. This is currently limited to re-calculating and
displaying displaying spectrogram data during viewer mode operation.&nbsp; </p>
<p class=MsoNormal>3. Heading sensor readout</p>
@ -4013,8 +4021,8 @@ channels 0 and 1. Similarly if you switched sound cards, you may have to
reconfigure every detector and several of the displays to handle the changes in
channel numbering. </p>
<p class=MsoNormal>I have spent a considerable amount of time trying to work out
a better system for handling channel numbering in PAMGUARD and have decided
<p class=MsoNormal>I have spent a considerable amount of time trying to work
out a better system for handling channel numbering in PAMGUARD and have decided
that the only practical thing to do is to force all software channel numbering
back to a zero indexed system. i.e. even if you read out hardware channels
3,4,5 and 6, within PAMGUARD, everywhere apart from the Sound acquisition
@ -4602,9 +4610,9 @@ a serial port </p>
<p class=MsoNormal>New Likelihood detector. </p>
<p class=MsoNormal>The likelihood detector module is an implementation of a likelihood
ratio test with flexible algorithms and configuration to estimate likelihood.
It is </p>
<p class=MsoNormal>The likelihood detector module is an implementation of a
likelihood ratio test with flexible algorithms and configuration to estimate
likelihood. It is </p>
<p class=MsoNormal>suitable for detecting both short duration Odontocete clicks
(Sperm, Beaked, etc.) as well as moderate duration Mysticete calls (Humpback,

View File

@ -0,0 +1,4 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Tue Jul 16 19:29:56 BST 2024
nilus-3.1.jar>=
nilus-3.1.pom>=

Binary file not shown.

View File

@ -0,0 +1,9 @@
<?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"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>tethys.org</groupId>
<artifactId>nilus</artifactId>
<version>3.1</version>
<description>POM was created from install:install-file</description>
</project>

View File

@ -0,0 +1,4 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Fri Aug 16 08:59:15 BST 2024
nilus-3.1.jar>=
nilus-3.1.pom>=

View File

@ -0,0 +1,8 @@
#Fri Aug 02 15:37:21 BST 2024
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo|sources=1722609441199
github|douggillespie|https\://maven.pkg.github.com/douggillespie/xbee-java|sources=1722609441199
central|https\://repo1.maven.org/maven2|sources=1722609441199
talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1722609441199
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1722609441199
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1722609441199
repo|file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo|sources=1721155730840

Binary file not shown.

View File

@ -0,0 +1,16 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Fri Aug 02 15:37:21 BST 2024
@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1721155730838
https\://repo1.maven.org/maven2/.error=
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.error=
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.lastUpdated=1722609441195
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=1721155730561
https\://repo1.maven.org/maven2/.lastUpdated=1721155729103
https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact tethys.org\:nilus\:jar\:sources\:3.1 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: nexus.talanlabs.com
https\://maven.pkg.github.com/douggillespie/xbee-java/.error=
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardDG/repo/.lastUpdated=1721155729822
file\://C\:\\Users\\dg50\\source\\repos\\PAMGuardPAMGuard/repo/.error=
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1721155730818
https\://maven.pkg.github.com/douggillespie/xbee-java/.lastUpdated=1721155729785

Binary file not shown.

View File

@ -0,0 +1,9 @@
<?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"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>tethys.org</groupId>
<artifactId>nilus</artifactId>
<version>3.1</version>
<description>POM was created from install:install-file</description>
</project>

View File

@ -173,8 +173,19 @@ public class AcquisitionControl extends RawInputControlledUnit implements PamSet
registerDaqSystem(new SoundCardSystem(this));
if (PlatformInfo.calculateOS() == OSType.WINDOWS) {
long tic = System.currentTimeMillis();
long toc = tic;
registerDaqSystem(new ASIOSoundSystem(this));
toc = System.currentTimeMillis();
if (toc-tic>1000) {
System.out.printf("Registering ASIOSoundSystem took %3.1fs\n", (double)(toc-tic)/1000.);
}
tic = System.currentTimeMillis();
registerDaqSystem(new NewAsioSoundSystem(this));
toc = System.currentTimeMillis();
if (toc-tic>1000) {
System.out.printf("Registering NewAsioSoundSystem took %3.1fs\n", (double)(toc-tic)/1000.);
}
}
registerDaqSystem(new FileInputSystem(this));
registerDaqSystem(folderSystem = new FolderInputSystem(this));

View File

@ -77,7 +77,7 @@ public class AcquisitionProcess extends PamProcess {
protected PamRawDataBlock rawDataBlock;
private PamDataBlock<DaqStatusDataUnit> daqStatusDataBlock;
private DaqStatusDataBlock daqStatusDataBlock;
AcquisitionProcess acquisitionProcess;
@ -125,12 +125,11 @@ public class AcquisitionProcess extends PamProcess {
// PamUtils.makeChannelMap(acquisitionControl.acquisitionParameters.nChannels),
// acquisitionControl.acquisitionParameters.sampleRate));
addOutputDataBlock(rawDataBlock = new PamRawDataBlock(name, this, //Xiao Yan Deng
addOutputDataBlock(rawDataBlock = new PamRawDataBlock(name, this,
PamUtils.makeChannelMap(acquisitionControl.acquisitionParameters.nChannels,acquisitionControl.acquisitionParameters.getHardwareChannelList()),
acquisitionControl.acquisitionParameters.sampleRate));
daqStatusDataBlock = new PamDataBlock<DaqStatusDataUnit>(DaqStatusDataUnit.class, acquisitionControl.getUnitName(),
daqStatusDataBlock = new DaqStatusDataBlock(acquisitionControl.getUnitName(),
this, 0);
// daqStatusDataBlock.
addOutputDataBlock(daqStatusDataBlock);
@ -1241,6 +1240,9 @@ public class AcquisitionProcess extends PamProcess {
}
public InputStoreInfo getStoreInfo(boolean detail) {
if (runningSystem == null) {
runningSystem = acquisitionControl.findDaqSystem(null);
}
if (runningSystem instanceof DataInputStore) {
return ((DataInputStore) runningSystem).getStoreInfo(detail);
}

View File

@ -0,0 +1,23 @@
package Acquisition;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
import dataMap.OfflineDataMap;
import effort.EffortProvider;
import effort.binary.DataMapEffortProvider;
import generalDatabase.DBControlUnit;
public class DaqStatusDataBlock extends PamDataBlock<DaqStatusDataUnit> {
public DaqStatusDataBlock(String dataName, PamProcess parentProcess, int channelMap) {
super(DaqStatusDataUnit.class, dataName, parentProcess, channelMap);
}
@Override
public EffortProvider autoEffortProvider() {
// make a provider which will pick up on the database data.
// db data are written every 60s, so put 62s as max gap.
return new DataMapEffortProvider(this, DBControlUnit.class, 62000L);
}
}

View File

@ -946,8 +946,12 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
InputStoreInfo storeInfo = new InputStoreInfo(acquisitionControl, allFiles.size(), firstFileStart, lastFileStart, lastFileEnd);
if (detail) {
long[] allFileStarts = new long[allFiles.size()];
long[] allFileEnds = new long[allFiles.size()];
for (int i = 0; i < allFiles.size(); i++) {
allFileStarts[i] = getFileStartTime(allFiles.get(i).getAbsoluteFile());
WavFileType aFile = allFiles.get(i);
allFileStarts[i] = getFileStartTime(aFile.getAbsoluteFile());
aFile.getAudioInfo();
allFileEnds[i] = (allFileStarts[i] + (long) (aFile.getDurationInSeconds()*1000.));
if (allFileStarts[i] < firstFileStart) {
// System.out.printf("Swap first file from %s to %s\n", firstFile.getName(), allFiles.get(i).getName());
firstFile = allFiles.get(i);
@ -962,6 +966,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
storeInfo.setFirstFileStart(firstFileStart); // just incase changed.
storeInfo.setLastFileEnd(lastFileEnd); // just incase changed
storeInfo.setFileStartTimes(allFileStarts);
storeInfo.setFileEndTimes(allFileEnds);
}
System.out.println("FolderInputSystem: Get store info complete:");
return storeInfo;

View File

@ -2,6 +2,7 @@ package GPS;
import java.util.ListIterator;
import GPS.effort.GpsEffortProvider;
import nmeaEmulator.EmulatedData;
import nmeaEmulator.NMEAEmulator;
import pamScrollSystem.ViewLoadObserver;
@ -37,6 +38,7 @@ public class GPSDataBlock extends PamDataBlock<GpsDataUnit> implements NMEAEmula
public GPSDataBlock(PamProcess process) {
super(GpsDataUnit.class, process.getPamControlledUnit().getUnitName(), process, 1);
setSynchLock(NavDataSynchronisation.getSynchobject());
setEffortProvider(new GpsEffortProvider(this));
}
@Override

View File

@ -0,0 +1,96 @@
package GPS.effort;
import java.util.ArrayList;
import java.util.List;
import GPS.GPSDataBlock;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector;
import dataMap.OfflineDataMap;
import effort.EffortDataUnit;
import effort.EffortProvider;
public class GpsEffortProvider extends EffortProvider {
private GPSDataBlock gpsDataBlock;
private GpsEffortSymbolManager effortSymbolManager;
private EffortDataUnit realTimeData;
public GpsEffortProvider(GPSDataBlock parentDataBlock) {
super(parentDataBlock);
this.gpsDataBlock = parentDataBlock;
effortSymbolManager = new GpsEffortSymbolManager(gpsDataBlock);
}
@Override
public EffortDataUnit getEffort(long timeMilliseconds) {
return getSingleEffort();
}
@Override
public List<EffortDataUnit> getAllEffortThings() {
EffortDataUnit singleEff = getSingleEffort();
ArrayList<EffortDataUnit> effList = new ArrayList<>(1);
if (singleEff != null) {
effList.add(singleEff);
}
return effList;
}
@Override
public DataSelector getDataSelector(String selectorName) {
return null;
}
@Override
public PamSymbolManager getSymbolManager() {
return effortSymbolManager;
}
private EffortDataUnit getSingleEffort() {
if (!isViewer()) {
return realTimeData;
}
OfflineDataMap dataMap = gpsDataBlock.getPrimaryDataMap();
if (dataMap == null) {
return null;
}
EffortDataUnit effData = new EffortDataUnit(this, null, dataMap.getFirstDataTime(), dataMap.getLastDataTime());
return effData;
}
@Override
public String getName() {
return gpsDataBlock.getDataName();
}
@Override
public void realTimeStart(long timeMilliseconds) {
// Do nothing
}
@Override
public void realTimeStop(long timeMilliseconds) {
// Do nothing
}
@Override
public void newData(PamDataUnit pamDataUnit) {
if (realTimeData == null) {
realTimeData = new EffortDataUnit(this,null,pamDataUnit.getTimeMilliseconds(), pamDataUnit.getTimeMilliseconds());
}
else {
realTimeData.setEffortEnd(pamDataUnit.getTimeMilliseconds());
}
}
@Override
public void viewerLoadData() {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,22 @@
package GPS.effort;
import java.awt.Color;
import PamView.PamColors;
import PamView.PamSymbolType;
import PamView.PamColors.PamColor;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.SymbolOnlyManager;
import PamguardMVC.PamDataBlock;
public class GpsEffortSymbolManager extends SymbolOnlyManager {
private static Color defColour = PamColors.getInstance().getColor(PamColor.GPSTRACK);
private static SymbolData defaultSymbol = new SymbolData(PamSymbolType.SYMBOL_LINESEGMENT, 10, 10, false, defColour, defColour);
public GpsEffortSymbolManager(PamDataBlock pamDataBlock) {
super(pamDataBlock, defaultSymbol);
}
}

View File

@ -0,0 +1,27 @@
package Localiser;
import tethys.localization.LocalizationCreator;
/**
* Interface to attach to localisation algorithms which can provide basic information
* (primarily for better book keeping and Tethys output)
* @author dg50
*
*/
public interface LocalisationAlgorithm {
/**
* Get information about the localisation algorithm.
* @return algorithm information.
*/
public LocalisationAlgorithmInfo getAlgorithmInfo();
/**
* Get something that can make LocalisationType objects of a form
* a bit bespoke to the type of localiser. This may be better than having
* the standard functions in LocalizationBuilder guess what's best.
* @return can be null in which case standard functions will do the best they can.
*/
public LocalizationCreator getTethysCreator();
}

View File

@ -0,0 +1,31 @@
package Localiser;
import java.io.Serializable;
import PamDetection.LocContents;
import PamDetection.LocalisationInfo;
public interface LocalisationAlgorithmInfo {
/**
* Get the likely content flags for this localiser.
* @see LocalisationInfo
* @see LocContents
* @return localisation flags.
*/
public int getLocalisationContents();
/**
* Get the algorithm name
* @return algorithm name
*/
public String getAlgorithmName();
/**
* Get the algorithm parameters. Something else
* can turn these into xml for Tethys.
* @return algorithm parameters object. Might be null;
*/
public Serializable getParameters();
}

View File

@ -1,5 +1,7 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import pamMaths.PamVector;
/**
@ -8,7 +10,7 @@ import pamMaths.PamVector;
* @author Doug Gillespie
*
*/
public interface BearingLocaliser {
public interface BearingLocaliser extends LocalisationAlgorithm, LocalisationAlgorithmInfo {
/**
* Do any preparation necessary (e.g. creation of look up tables)

View File

@ -1,7 +1,13 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import pamMaths.PamVector;
import java.io.Serializable;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
@Deprecated
public class CombinedBearingLocaliser implements BearingLocaliser {
private BearingLocaliser firstLocaliser;
@ -23,6 +29,11 @@ public class CombinedBearingLocaliser implements BearingLocaliser {
firstSimplexStep[0] = firstSimplexStep[1] = Math.PI/180.;
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
}
@Override
public void prepare(int[] arrayElements, long timeMillis, double timingError) {
firstLocaliser.prepare(arrayElements, timeMillis, timingError);
@ -61,4 +72,25 @@ public class CombinedBearingLocaliser implements BearingLocaliser {
return res2;
}
@Override
public String getAlgorithmName() {
return "Combined Simplex bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,12 +1,17 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import Array.ArrayManager;
import Array.PamArray;
import Jama.LUDecomposition;
import Jama.Matrix;
import Jama.QRDecomposition;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import PamUtils.PamUtils;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
public class LSQBearingLocaliser implements BearingLocaliser {
@ -30,6 +35,11 @@ public class LSQBearingLocaliser implements BearingLocaliser {
this.timingError = timingError;
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
}
@Override
public void prepare(int[] arrayElements, long timeMillis, double timingError) {
/*
@ -71,12 +81,12 @@ public class LSQBearingLocaliser implements BearingLocaliser {
weightedHydrophoneVectors.set(iRow, e, v.getElement(e)/c*fitWeights[iRow]);
hydrophoneVectors.set(iRow, e, v.getElement(e)/c);
hydrophoneErrorVectors.set(iRow, e, errorVec.getElement(e)/c);
// hydrophoneUnitVectors.set(iRow, e, uv.getElement(e));
// hydrophoneUnitVectors.set(iRow, e, uv.getElement(e));
}
iRow++;
}
}
// luHydrophoneUnitMatrix = new LUDecomposition(hydrophoneUnitVectors);
// luHydrophoneUnitMatrix = new LUDecomposition(hydrophoneUnitVectors);
qrHydrophones = new QRDecomposition(weightedHydrophoneVectors);
}
@ -112,21 +122,21 @@ public class LSQBearingLocaliser implements BearingLocaliser {
@Override
public double[][] localise(double[] delays, long timeMillis) {
resetArray(timeMillis);
// qrHydrophones = new QRDecomposition(hydrophoneVectors);
// qrHydrophones = new QRDecomposition(hydrophoneVectors);
Matrix normDelays = new Matrix(delays.length, 1);
for (int i = 0; i < delays.length; i++) {
normDelays.set(i, 0, -delays[i]*fitWeights[i]);
}
// Matrix soln = luHydrophoneUnitMatrix.solve(normDelays);
// Matrix soln = luHydrophoneUnitMatrix.solve(normDelays);
Matrix soln2 = qrHydrophones.solve(normDelays);
double[][] angs = new double[2][2];
PamVector v = new PamVector(soln2.get(0, 0), soln2.get(1,0), soln2.get(2, 0));
// System.out.printf("Vector Norm = %4.3f: ", v.norm());
// System.out.printf("Vector Norm = %4.3f: ", v.norm());
double m = v.normalise();
angs[0][0] = Math.PI/2. - Math.atan2(v.getElement(0),v.getElement(1));
angs[0][1] = Math.asin(v.getElement(2));
// timingError = 1e-5;
// timingError = 1e-5;
// now take a look at angle errors
double oneDeg = Math.PI/180.;
@ -143,7 +153,7 @@ public class LSQBearingLocaliser implements BearingLocaliser {
l3 = logLikelihood(delays, angs[0][0] + aDiff, angs[0][1]);
er[0][i] = angs[1][0] = Math.sqrt(1./(l1+l3-2*l2))*aDiff;
l1a = logLikelihood(delays, angs[0][0], angs[0][1] - aDiff);
// l2 = logLikelihood(delays, angs[0][0], angs[0][1]);
// l2 = logLikelihood(delays, angs[0][0], angs[0][1]);
l3a = logLikelihood(delays, angs[0][0], angs[0][1] + aDiff);
er[1][i] = angs[1][1] = Math.sqrt(1./(l1a+l3a-2*l2))*aDiff;
}
@ -151,14 +161,14 @@ public class LSQBearingLocaliser implements BearingLocaliser {
// double ll[] = new double[21];
// double a[] = new double[2];
// timingError = 1.e-4;
// a[1] = angs[0][1];
// for (int i = 0; i < ll.length; i++) {
// a[0] = angs[0][0] + (-10 + i)*oneDeg;
// ll[i] = logLikelihood(delays, a);
// }
// double ll[] = new double[21];
// double a[] = new double[2];
// timingError = 1.e-4;
// a[1] = angs[0][1];
// for (int i = 0; i < ll.length; i++) {
// a[0] = angs[0][0] + (-10 + i)*oneDeg;
// ll[i] = logLikelihood(delays, a);
// }
return angs;
}
/**
@ -184,11 +194,11 @@ public class LSQBearingLocaliser implements BearingLocaliser {
*/
public double logLikelihood(double[] delays, double[] angles) {
return logLikelihood(delays, angles[0], angles[1]);
// Matrix whaleVec = new Matrix(3,1);
// whaleVec.set(0, 0, Math.cos(angles[1])*Math.cos(angles[0]));
// whaleVec.set(1, 0, Math.cos(angles[1])*Math.sin(angles[0]));
// whaleVec.set(2, 0, Math.sin(angles[1]));
// return logLikelihood(delays, whaleVec);
// Matrix whaleVec = new Matrix(3,1);
// whaleVec.set(0, 0, Math.cos(angles[1])*Math.cos(angles[0]));
// whaleVec.set(1, 0, Math.cos(angles[1])*Math.sin(angles[0]));
// whaleVec.set(2, 0, Math.sin(angles[1]));
// return logLikelihood(delays, whaleVec);
}
/**
* Calculate a log likelihood for a given whale vector.
@ -210,4 +220,23 @@ public class LSQBearingLocaliser implements BearingLocaliser {
return chi/2;
}
@Override
public String getAlgorithmName() {
return "Least Squares bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,15 +1,19 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays;
import Array.ArrayManager;
import Array.PamArray;
import Jama.Matrix;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.Correlations;
import PamDetection.LocContents;
import PamUtils.ArrayDump;
import PamUtils.PamUtils;
import PamUtils.SystemTiming;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
/**
* Maximum likelihood bearing localiser to get bearings from a closely
@ -61,6 +65,11 @@ public class MLGridBearingLocaliser implements BearingLocaliser {
prepare(arrayElements, timMillis, timingError, Math.toRadians(1), Math.toRadians(1));
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
}
synchronized private void prepare(int[] arrayElements, long timeMillis, double timingError, double thetaStep, double phiStep) {
this.timingError = timingError;
this.thetaStep = thetaStep;
@ -630,5 +639,24 @@ public class MLGridBearingLocaliser implements BearingLocaliser {
return hydrophoneMap;
}
@Override
public String getAlgorithmName() {
return "Maximum likelyhood grid bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,17 +1,22 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays;
import Array.ArrayManager;
import Array.PamArray;
import Jama.Matrix;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.Correlations;
import Localiser.algorithms.PeakPosition2D;
import Localiser.algorithms.PeakSearch;
import PamDetection.LocContents;
import PamUtils.ArrayDump;
import PamUtils.PamUtils;
import PamUtils.SystemTiming;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
import tethys.pamdata.AutoTethysProvider;
/**
* Revamp of the earlier MLGridBearingLocaliser but with a more sensible
@ -73,6 +78,11 @@ public class MLGridBearingLocaliser2 implements BearingLocaliser {
prepare(arrayElements, timMillis, timingError, Math.toRadians(3), Math.toRadians(3));
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
}
synchronized private void prepare(int[] arrayElements, long timeMillis, double timingError, double thetaStep, double phiStep) {
this.timingError = timingError;
this.thetaStep = thetaStep;
@ -738,4 +748,41 @@ public class MLGridBearingLocaliser2 implements BearingLocaliser {
return likelihoodLUT;
}
@Override
public String getAlgorithmName() {
return "Maximum likelyhood grid bearing localiser V2";
}
@Override
public Serializable getParameters() {
return new LocaliserParams(this.thetaStep, this.phiStep);
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
/**
* For passing to Tethys output.
* @author dg50
*
*/
public class LocaliserParams implements Serializable {
private static final long serialVersionUID = 1L;
public double thetaStep, phiStep;
public LocaliserParams(double thetaStep, double phiStep) {
super();
this.thetaStep = Math.toDegrees(thetaStep);
this.phiStep = Math.toDegrees(phiStep);
this.thetaStep = AutoTethysProvider.roundDecimalPlaces(this.thetaStep, 2);
this.phiStep = AutoTethysProvider.roundDecimalPlaces(this.phiStep, 2);
}
}
}

View File

@ -3,6 +3,8 @@
*/
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import PamDetection.LocContents;
/**
* @author dg50
*
@ -19,6 +21,11 @@ public class MLLineBearingLocaliser2 extends MLGridBearingLocaliser2 {
// TODO Auto-generated constructor stub
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY | LocContents.HAS_AMBIGUITY;
}
/**
* Convert a bin into an angle.
* @param bin bin index

View File

@ -1,13 +1,17 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays;
import Array.ArrayManager;
import Array.PamArray;
import Jama.Matrix;
import Jama.QRDecomposition;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import PamUtils.PamUtils;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
/**
* Really simple BearingLocaliser which works with two element closely
@ -17,111 +21,111 @@ import pamMaths.PamVector;
*/
public class PairBearingLocaliser implements BearingLocaliser {
public class LSQBearingLocaliser implements BearingLocaliser {
private int hydrophoneBitMap;
private long timeMillis;
private double timingError;
private Matrix hydrophoneVectors, hydrophoneUnitVectors;
private double[] hydrophoneSpacing;
private PamArray currentArray;
private int arrayType;
private PamVector[] arrayAxis;
// private LUDecomposition luHydrophoneUnitMatrix;
private QRDecomposition qrHydrophones;
public LSQBearingLocaliser(int hydrophoneBitMap, long timeMillis, double timingError) {
this.hydrophoneBitMap = hydrophoneBitMap;
this.timeMillis = timeMillis;
this.timingError = timingError;
}
@Override
public void prepare(int[] arrayElements, long timeMillis, double timingError) {
/*
* Set up the matrixes of inter hydrophone vectors.
*/
hydrophoneBitMap = PamUtils.makeChannelMap(arrayElements);
ArrayManager arrayManager = ArrayManager.getArrayManager();
currentArray = arrayManager.getCurrentArray();
arrayType = arrayManager.getArrayShape(currentArray, hydrophoneBitMap);
arrayAxis = arrayManager.getArrayDirections(currentArray, hydrophoneBitMap);
int nHyd = arrayElements.length;
int nDelay = (nHyd*(nHyd-1))/2;
hydrophoneVectors = new Matrix(nDelay, 3);
hydrophoneUnitVectors = new Matrix(nDelay, 3);
hydrophoneSpacing = new double[nDelay];
int iRow = 0;
for (int i = 0; i < nHyd; i++) {
PamVector vi = currentArray.getAbsHydrophoneVector(i, timeMillis);
for (int j = i+1; j <nHyd; j++) {
PamVector vj = currentArray.getAbsHydrophoneVector(j, timeMillis);
PamVector v = vj.sub(vi);
hydrophoneSpacing[iRow] = v.norm();
PamVector uv = v.getUnitVector();
for (int e = 0; e < 3; e++) {
hydrophoneVectors.set(iRow, e, v.getElement(e));
hydrophoneUnitVectors.set(iRow, e, uv.getElement(e));
}
iRow++;
}
}
// luHydrophoneUnitMatrix = new LUDecomposition(hydrophoneUnitVectors);
qrHydrophones = new QRDecomposition(hydrophoneUnitVectors);
}
@Override
public int getArrayType() {
return arrayType;
}
@Override
public int getHydrophoneMap() {
return hydrophoneBitMap;
}
@Override
public PamVector[] getArrayAxis() {
return arrayAxis;
}
/*
* @return true if a new grid needs to be created
*/
private boolean resetArray(long timeMillis){
if (currentArray == null || (this.timeMillis!=timeMillis && currentArray.getHydrophoneLocator().isChangeable())){
prepare(PamUtils.getChannelArray(hydrophoneBitMap), timeMillis, 1e-6);
this.timeMillis = timeMillis;
return true;
}
return false;
}
@Override
public double[][] localise(double[] delays, long timeMillis) {
resetArray(timeMillis);
Matrix normDelays = new Matrix(delays.length, 1);
double c = currentArray.getSpeedOfSound();
for (int i = 0; i < delays.length; i++) {
normDelays.set(i, 0, -delays[i]*c/hydrophoneSpacing[i]);
}
// Matrix soln = luHydrophoneUnitMatrix.solve(normDelays);
Matrix soln2 = qrHydrophones.solve(normDelays);
double[][] angs = new double[2][2];
PamVector v = new PamVector(soln2.get(0, 0), soln2.get(1,0), soln2.get(2, 0));
double m = v.normalise();
angs[0][0] = Math.PI/2. - Math.atan2(v.getElement(0),v.getElement(1));
angs[0][1] = Math.asin(v.getElement(2));
return angs;
}
}
// public class LSQBearingLocaliser implements BearingLocaliser {
//
// private int hydrophoneBitMap;
// private long timeMillis;
// private double timingError;
//
// private Matrix hydrophoneVectors, hydrophoneUnitVectors;
// private double[] hydrophoneSpacing;
// private PamArray currentArray;
// private int arrayType;
// private PamVector[] arrayAxis;
// // private LUDecomposition luHydrophoneUnitMatrix;
// private QRDecomposition qrHydrophones;
//
// public LSQBearingLocaliser(int hydrophoneBitMap, long timeMillis, double timingError) {
// this.hydrophoneBitMap = hydrophoneBitMap;
// this.timeMillis = timeMillis;
// this.timingError = timingError;
// }
//
// @Override
// public void prepare(int[] arrayElements, long timeMillis, double timingError) {
// /*
// * Set up the matrixes of inter hydrophone vectors.
// */
//
// hydrophoneBitMap = PamUtils.makeChannelMap(arrayElements);
// ArrayManager arrayManager = ArrayManager.getArrayManager();
// currentArray = arrayManager.getCurrentArray();
// arrayType = arrayManager.getArrayShape(currentArray, hydrophoneBitMap);
//
// arrayAxis = arrayManager.getArrayDirections(currentArray, hydrophoneBitMap);
//
// int nHyd = arrayElements.length;
// int nDelay = (nHyd*(nHyd-1))/2;
// hydrophoneVectors = new Matrix(nDelay, 3);
// hydrophoneUnitVectors = new Matrix(nDelay, 3);
// hydrophoneSpacing = new double[nDelay];
// int iRow = 0;
// for (int i = 0; i < nHyd; i++) {
// PamVector vi = currentArray.getAbsHydrophoneVector(i, timeMillis);
// for (int j = i+1; j <nHyd; j++) {
// PamVector vj = currentArray.getAbsHydrophoneVector(j, timeMillis);
// PamVector v = vj.sub(vi);
// hydrophoneSpacing[iRow] = v.norm();
// PamVector uv = v.getUnitVector();
// for (int e = 0; e < 3; e++) {
// hydrophoneVectors.set(iRow, e, v.getElement(e));
// hydrophoneUnitVectors.set(iRow, e, uv.getElement(e));
// }
// iRow++;
// }
// }
// // luHydrophoneUnitMatrix = new LUDecomposition(hydrophoneUnitVectors);
// qrHydrophones = new QRDecomposition(hydrophoneUnitVectors);
// }
//
// @Override
// public int getArrayType() {
// return arrayType;
// }
//
// @Override
// public int getHydrophoneMap() {
// return hydrophoneBitMap;
// }
//
// @Override
// public PamVector[] getArrayAxis() {
// return arrayAxis;
// }
//
// /*
// * @return true if a new grid needs to be created
// */
// private boolean resetArray(long timeMillis){
//
// if (currentArray == null || (this.timeMillis!=timeMillis && currentArray.getHydrophoneLocator().isChangeable())){
// prepare(PamUtils.getChannelArray(hydrophoneBitMap), timeMillis, 1e-6);
// this.timeMillis = timeMillis;
// return true;
// }
//
// return false;
// }
//
// @Override
// public double[][] localise(double[] delays, long timeMillis) {
// resetArray(timeMillis);
// Matrix normDelays = new Matrix(delays.length, 1);
// double c = currentArray.getSpeedOfSound();
// for (int i = 0; i < delays.length; i++) {
// normDelays.set(i, 0, -delays[i]*c/hydrophoneSpacing[i]);
// }
// // Matrix soln = luHydrophoneUnitMatrix.solve(normDelays);
// Matrix soln2 = qrHydrophones.solve(normDelays);
// double[][] angs = new double[2][2];
// PamVector v = new PamVector(soln2.get(0, 0), soln2.get(1,0), soln2.get(2, 0));
// double m = v.normalise();
// angs[0][0] = Math.PI/2. - Math.atan2(v.getElement(0),v.getElement(1));
// angs[0][1] = Math.asin(v.getElement(2));
// return angs;
// }
//
// }
private int[] phoneNumbers;
@ -206,6 +210,11 @@ public class PairBearingLocaliser implements BearingLocaliser {
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY | LocContents.HAS_AMBIGUITY;
}
/**
* Some hydrophone locators have arrays which change with time. In this case the ML grid localiser will need to recalculate the look up table for localised ppositions
*
@ -288,4 +297,22 @@ public class PairBearingLocaliser implements BearingLocaliser {
return speedOfSound;
}
@Override
public String getAlgorithmName() {
return "Pair bearing localiser";
}
@Override
public Serializable getParameters() {
return null;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -1,5 +1,6 @@
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
import java.io.Serializable;
import java.util.Arrays;
import org.apache.commons.math.FunctionEvaluationException;
@ -14,9 +15,13 @@ import Array.ArrayManager;
import Array.PamArray;
import Jama.Matrix;
import Jama.QRDecomposition;
import Localiser.LocalisationAlgorithmInfo;
import PamDetection.LocContents;
import PamUtils.PamUtils;
import pamMaths.PamVector;
import tethys.localization.LocalizationCreator;
@Deprecated
public class SimplexBearingLocaliser implements BearingLocaliser {
private int arrayType;
private Matrix hydrophoneVectors;
@ -39,6 +44,11 @@ public class SimplexBearingLocaliser implements BearingLocaliser {
this.timingError = timingError;
}
@Override
public int getLocalisationContents() {
return LocContents.HAS_BEARING | LocContents.HAS_AMBIGUITY;
}
@Override
public void prepare(int[] arrayElements, long timeMillis, double timingError) {
/*
@ -231,6 +241,26 @@ public class SimplexBearingLocaliser implements BearingLocaliser {
this.firstStep = firstStep;
}
@Override
public String getAlgorithmName() {
return "Simplex bearing localiser";
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
@Override
public Serializable getParameters() {
return null;
}
// private class BearingConvergence implements RealConvergenceChecker {
//
// @Override

View File

@ -38,6 +38,7 @@ import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
@ -83,6 +84,7 @@ import PamView.paneloverlay.overlaymark.MarkOverlayDraw;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModifier;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamObservable;
@ -90,6 +92,8 @@ import PamguardMVC.PamObserver;
import PamguardMVC.dataSelector.DataSelectDialog;
import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.debug.Debug;
import effort.EffortDataUnit;
import effort.EffortProvider;
import pamMaths.PamVector;
/**
@ -132,6 +136,8 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
private boolean repaintBase = false;
private EffortDataUnit latestEffort;
public MapPanel(MapController mapController, SimpleMap simpleMap) {
this.mapController = mapController;
this.simpleMapRef = simpleMap;
@ -786,6 +792,7 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
private GpsDataUnit lastDrawGpsDataUnit;
private Coordinate3d lastGpsCoodinate;
private PamSymbol latestSymbol;
long getMapStartTime() {
switch (PamController.getInstance().getRunMode()) {
@ -798,21 +805,69 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
return PamCalendar.getTimeInMillis();
}
public EffortProvider findEffortProvider() {
if (simpleMapRef.mapParameters.colourByEffort == false) {
return null;
}
if (simpleMapRef.effortDataBlock == null) {
return null;
}
return simpleMapRef.effortDataBlock.getEffortProvider();
}
private void paintTrack(Graphics g, PamDataUnit lastDrawnUnit) {
long mapStartTime = getMapStartTime();
g.setColor(PamColors.getInstance().getColor(PamColor.GPSTRACK));
GPSDataBlock gpsDataBlock = simpleMapRef.getGpsDataBlock();
if (gpsDataBlock == null) {
return;
}
PamSymbolChooser symbolModifier = null;
List<EffortDataUnit> effortThings = null;
EffortDataUnit currentEffortThing = null;
EffortProvider effortProvider = findEffortProvider();
PamSymbol effortSymbol = null;
Iterator<EffortDataUnit> effortIterator = null;
if (effortProvider != null) {
symbolModifier = effortProvider.getSymbolChooser(simpleMapRef.getSelectorName(), rectProj);
effortThings = effortProvider.getAllEffortThings();
if (effortThings == null || effortThings.size() == 0) {
effortThings = null;
}
else {
effortIterator = effortThings.iterator();
}
if (effortIterator != null && effortIterator.hasNext()) {
currentEffortThing = effortIterator.next();
if (symbolModifier != null) {
// effortSymbol = symbolModifier.getPamSymbol(rectProj, currentEffortThing);
effortSymbol = effortProvider.getPamSymbol(symbolModifier, currentEffortThing);
latestEffort = currentEffortThing;
latestSymbol = effortSymbol;
}
}
}
Graphics2D g2d = (Graphics2D) g;
long mapStartTime = getMapStartTime();
Color defaultColour = PamColors.getInstance().getColor(PamColor.GPSTRACK);
if (effortSymbol != null) {
g2d.setStroke(new BasicStroke(effortSymbol.getLineThickness()));
}
else {
g2d.setStroke(new BasicStroke(1));
}
if (effortSymbol != null && mapStartTime > currentEffortThing.getEffortStart()) {
g.setColor(effortSymbol.getLineColor());
}
else {
g.setColor(defaultColour);
}
// GPSControl gpsControl = GPSControl.getGpsControl();
// if (gpsControl == null) {
// return;
// }
// PamDataBlock<GpsDataUnit> gpsDataBlock = gpsControl.getGpsDataBlock();
GPSDataBlock gpsDataBlock = simpleMapRef.getGpsDataBlock();
if (gpsDataBlock == null) {
return;
}
long t1 = getMapStartTime(), t2 = Long.MAX_VALUE;
if (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW) {
t1 = simpleMapRef.getViewerScroller().getMinimumMillis();
@ -826,13 +881,48 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
GpsDataUnit dataUnit;
synchronized (gpsDataBlock.getSynchLock()) {
ListIterator<GpsDataUnit> gpsIterator = gpsDataBlock.getListIterator(0);
if (gpsIterator.hasNext()) {
dataUnit = gpsIterator.next();
if (gpsIterator.hasNext()) {
gpsData = dataUnit.getGpsData();
lastFixTime = dataUnit.getTimeMilliseconds();
c1 = rectProj.getCoord3d(gpsData.getLatitude(), gpsData.getLongitude(), 0.);
while (gpsIterator.hasNext()) {
dataUnit = gpsIterator.next();
// sort out effort colours.
// if (currentEffortThing != null) {
while (currentEffortThing != null && dataUnit.getTimeMilliseconds() > currentEffortThing.getEffortEnd()) {
// get the next one. then decide if we're in or not.
if (effortIterator.hasNext()) {
currentEffortThing = effortIterator.next();
if (symbolModifier != null) {
effortSymbol = effortProvider.getPamSymbol(symbolModifier, currentEffortThing);
}
}
else {
break;
}
// else {
// currentEffortThing = null;
// effortSymbol = null;
// }
}
// }
if (effortSymbol != null && currentEffortThing.inEffort(dataUnit.getTimeMilliseconds())) {
g.setColor(effortSymbol.getLineColor());
latestEffort = currentEffortThing;
latestSymbol = effortSymbol;
}
else {
g.setColor(defaultColour);
// latestSymbol = null;
}
gpsData = dataUnit.getGpsData();
if (gpsData.isDataOk() == false) {
continue;
@ -909,7 +999,41 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
private void paintNewGPSData(Graphics g, GpsDataUnit newGpsDataUnit) {
Coordinate3d c2;
// g.setColor(PamColors.getInstance().getColor(PamColor.GPSTRACK));
// if (latestSymbol != null) {
// float t = latestSymbol.getLineThickness();
// if (t != 1) {
// Graphics2D g2d = (Graphics2D) g;
// g2d.setStroke(new BasicStroke(t));
// }
// if (latestEffort != null && latestEffort.inEffort(newGpsDataUnit.getTimeMilliseconds())) {
// g.setColor(latestSymbol.getLineColor());
// }
// }
// else {
EffortProvider effortProvider = findEffortProvider();
boolean effSet = false;
if (effortProvider != null) {
latestEffort = effortProvider.getLastEffort();
if (latestEffort != null) {
PamSymbolChooser symbolModifier = effortProvider.getSymbolChooser(simpleMapRef.getSelectorName(), rectProj);
if (symbolModifier != null) {
PamSymbol symbol = effortProvider.getPamSymbol(symbolModifier, latestEffort);
// PamSymbol symbol = symbolModifier.getPamSymbol(rectProj, latestEffort);
if (symbol != null && latestEffort.inEffort(newGpsDataUnit.getTimeMilliseconds())) {
symbol.getSymbolData().setGraphicsProperties(g);
effSet = true;
}
}
}
}
if (!effSet) {
g.setColor(PamColors.getInstance().getColor(PamColor.GPSTRACK));
}
/**
* This can get quite long, so need to do the same iterating through the effort data as for normal plotting.
*/
GpsData gpsData = newGpsDataUnit.getGpsData();
c2 = rectProj.getCoord3d(gpsData.getLatitude(), gpsData.getLongitude(), 0.);
if (lastGpsCoodinate != null) {
@ -1055,7 +1179,7 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
mapDrawingOptions = null;
rectProj.setProjectorDrawingOptions(null);
}
DataSelector ds = dataBlock.getDataSelector(simpleMapRef.getUnitName(), false, DATASELECTNAME);
DataSelector ds = dataBlock.getDataSelector(simpleMapRef.getSelectorName(), false, DATASELECTNAME);
rectProj.setDataSelector(ds);
// see if the datablock has a symbol manager.
PamSymbolManager symbolManager = dataBlock.getPamSymbolManager();
@ -1252,13 +1376,21 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
@Override
public void addData(PamObservable o, PamDataUnit arg) {
// if (arg instanceof EffortDataUnit) {
// won't work since only the data send notifications.
// System.out.println("Effort add, so repaint base");
// repaintBaseDrawing();
// }
// PamDataBlock block = (PamDataBlock) o;
repaint(250);
}
@Override
public void updateData(PamObservable observable, PamDataUnit pamDataUnit) {
// if (pamDataUnit instanceof EffortDataUnit) {
// System.out.println("Effort update, so repaint base");
// repaintBaseDrawing();
// }
repaint(250);
}
@ -1340,6 +1472,10 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
aBlock.addObserver(this);
}
}
EffortProvider effBlock = findEffortProvider();
if (effBlock != null) {
effBlock.getParentDataBlock().addObserver(this);
}
}
protected void createKey() {
@ -1852,6 +1988,27 @@ public class MapPanel extends JPanelWithPamKey implements PamObserver, ColorMana
this.mapController = mapController;
}
@Override
public String getToolTipText(MouseEvent event) {
String tip = super.getToolTipText(event);
if (tip == null) {
return tip;
}
if (tip.startsWith("<html>GPS") == false) {
return tip;
}
return tip;
}
public EffortDataUnit findEffortThing(long timeMilliseconds) {
EffortProvider effortProvider = findEffortProvider();
if (effortProvider == null) {
return null;
}
return effortProvider.getEffort(timeMilliseconds);
}
}

View File

@ -95,6 +95,12 @@ public class MapParameters implements Serializable, Cloneable, ManagedParameters
public int symbolSize = Hydrophone.DefaultSymbolSize;
public boolean colourByEffort = false;
/**
* Name of data block providing effort data.
*/
public String effortDataSource;
private static final int defaultMapRange = 10000;
/**
* Value to store persistently between runs.

View File

@ -31,7 +31,12 @@ import Array.Hydrophone;
import Map.gridbaselayer.GridDialogPanel;
import PamView.dialog.PamDialog;
import PamView.dialog.PamGridBagContraints;
import PamView.dialog.SettingsButton;
import PamView.dialog.SourcePanel;
import PamView.panel.PamNorthPanel;
import PamguardMVC.PamDataBlock;
import effort.EffortProvider;
import effort.swing.EffortSourcePanel;
@ -65,6 +70,8 @@ public class MapParametersDialog extends PamDialog {
private JCheckBox showSurface = new JCheckBox("Show sea surface");
private JCheckBox colourByEffort = new JCheckBox("Colour track-line by efort");
private MapFileManager mapFileManager;
public JSpinner symbolSizeSpinner;
@ -79,6 +86,10 @@ public class MapParametersDialog extends PamDialog {
private SimpleMap simpleMap;
private EffortSourcePanel effortSourcePanel;
private SettingsButton effortSettings;
private MapParametersDialog(java.awt.Window parentFrame, SimpleMap simpleMap) {
super(parentFrame, "Map Options", true);
@ -110,15 +121,21 @@ public class MapParametersDialog extends PamDialog {
setDialogComponent(tabbedPane);
setHelpPoint("mapping.mapHelp.docs.overview");
// this.enableHelpButton(true);
colourByEffort.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
enableControls();
}
});
//hydroCheckBox.get
}
// MapParameters oldParameters, MapFileManager mapFile
public static MapParameters showDialog(java.awt.Window parentFrame, SimpleMap simpleMap) {
if (singleInstance == null || singleInstance.simpleMap != simpleMap) {
// if (singleInstance == null || singleInstance.simpleMap != simpleMap) {
singleInstance = new MapParametersDialog(parentFrame, simpleMap);
}
// }
singleInstance.mapParameters = simpleMap.mapParameters.clone();
singleInstance.mapFileManager = simpleMap.mapFileManager;
singleInstance.setParams();
@ -141,6 +158,8 @@ public class MapParametersDialog extends PamDialog {
keepShipCentred.setSelected(mapParameters.keepShipCentred);
headingUp.setSelected(mapParameters.headingUp);
showSurface.setSelected(mapParameters.hideSurface == false);
colourByEffort.setSelected(mapParameters.colourByEffort);
effortSourcePanel.setSource(mapParameters.effortDataSource);
filePanel.setMapFile(mapParameters.mapFile);
@ -177,6 +196,8 @@ public class MapParametersDialog extends PamDialog {
return showWarning("Range rings sepration must be > 0");
}
}
mapParameters.colourByEffort = colourByEffort.isSelected();
mapParameters.effortDataSource = effortSourcePanel.getSourceName();
}
catch (Exception Ex) {
return false;
@ -216,6 +237,14 @@ public class MapParametersDialog extends PamDialog {
GridBagLayout layout;
setLayout(layout = new GridBagLayout());
GridBagConstraints constraints = new PamGridBagContraints();
effortSourcePanel = new EffortSourcePanel(singleInstance);
effortSettings = new SettingsButton();
effortSettings.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showEffortSettings();
}
});
// t.setLayout(new GridLayout(4,3));
constraints.anchor = GridBagConstraints.WEST;
constraints.gridx = 0;
@ -224,37 +253,62 @@ public class MapParametersDialog extends PamDialog {
constraints.gridx ++;
addComponent(this,trackShowtime = new JTextField(7), constraints);
constraints.gridx ++;
addComponent(this,new JLabel(" s"), constraints);
addComponent(this,new JLabel(" s "), constraints);
constraints.gridx++;
addComponent(this, colourByEffort, constraints);
constraints.gridx += 2;
constraints.gridwidth = 1;
constraints.fill = constraints.NONE;
constraints.anchor = constraints.LINE_END;
addComponent(this, effortSettings, constraints);
constraints.gridx = 0;
constraints.gridy ++;
constraints.anchor = constraints.LINE_START;
addComponent(this,new JLabel("Data storage time "), constraints);
constraints.gridx ++;
addComponent(this,dataKeepTime = new JTextField(7), constraints);
constraints.gridx ++;
addComponent(this,new JLabel(" s"), constraints);
addComponent(this,new JLabel(" s "), constraints);
constraints.gridx++;
constraints.gridwidth = 3;
constraints.fill = constraints.HORIZONTAL;
addComponent(this, effortSourcePanel.getPanel(), constraints);
constraints.gridx = 0;
constraints.gridy ++;
constraints.gridwidth = 1;
addComponent(this,new JLabel("Data display time "), constraints);
constraints.gridx ++;
addComponent(this,dataShowTime = new JTextField(7), constraints);
constraints.gridx ++;
addComponent(this,new JLabel(" s"), constraints);
addComponent(this,new JLabel(" s "), constraints);
constraints.gridx = 0;
constraints.gridy ++;
constraints.gridwidth = 3;
constraints.gridwidth = 2;
addComponent(this,shipCheckBox, constraints);
constraints.gridy ++;
constraints.gridx += constraints.gridwidth;
addComponent(this,keepShipOnMap, constraints);
constraints.gridy ++;
constraints.gridx = 0;
constraints.gridy ++;
constraints.gridwidth = 3;
addComponent(this,keepShipCentred, constraints);
constraints.gridy ++;
constraints.gridx += constraints.gridwidth;
addComponent(this,headingUp, constraints);
constraints.gridy ++;
constraints.gridx = 0;
addComponent(this, showSurface, constraints);
}
protected void showEffortSettings() {
PamDataBlock effortBlock = effortSourcePanel.getSource();
if (effortBlock == null) {
return;
}
EffortProvider effortProvider = effortBlock.getEffortProvider();
if (effortProvider == null) {
return;
}
effortProvider.showOptionsDialog(singleInstance, simpleMap.getSelectorName());
}
}
class HydrophonePanel extends JPanel {
@ -491,6 +545,9 @@ public class MapParametersDialog extends PamDialog {
colourByChannel.setEnabled(hydroCheckBox.isSelected());
symbolSizeSpinner.setEnabled(hydroCheckBox.isSelected());
ringsRange.setEnabled(ringsType.getSelectedIndex() > 0);
boolean ec = colourByEffort.isSelected();
effortSettings.setSelected(ec);
effortSourcePanel.setEnabled(ec);
}

View File

@ -34,6 +34,7 @@ import PamUtils.LatLong;
import PamUtils.PamCoordinate;
import PamUtils.PamUtils;
import PamguardMVC.debug.Debug;
import effort.EffortDataUnit;
/**
* The Map Rectangle Projector.
@ -427,8 +428,16 @@ public class MapRectProjector extends MapProjector {
if (rPix > 20) {
return null;
}
EffortDataUnit effortData = mapPanelRef.findEffortThing(closest.getTimeMilliseconds());
if (effortData == null) {
return closest.getSummaryString();
}
else {
String effSummary = effortData.toString();
String str = closest.getSummaryString() + "Effort: " + effSummary;
return str;
}
}

View File

@ -101,6 +101,7 @@ import PamguardMVC.PamObservable;
import PamguardMVC.PamObserver;
import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.debug.Debug;
import effort.EffortProvider;
/**
* Mainly a container for map objects, holding the main MapPanel and the right
@ -201,6 +202,8 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
private GridbaseControl gridBaseControl;
protected PamDataBlock effortDataBlock;
// JToolTip mouseToolTip;
public SimpleMap(MapController mapController, boolean isMainTab, MapPanel mapPanel) {
@ -264,6 +267,14 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
this(mapController, isMainTab, new MapPanel(mapController, null));
}
/**
* Name for data selectors and data filters.
* @return
*/
public String getSelectorName() {
return getUnitName();
}
public String getUnitName() {
if (thisMapIndex != 0) {
return mapController.getUnitName()+thisMapIndex;
@ -571,6 +582,8 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
initViewerControls();
effortDataBlock = PamController.getInstance().getDataBlockByLongName(mapParameters.effortDataSource);
if (mapFileManager != null) {
mapFileManager.readFileData(mapParameters.mapFile);
}
@ -1146,10 +1159,24 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
}
}
}
subscribeEffortProvider();
return changes;
}
/**
* Subscribe the effort provider to the scroller.
*/
private void subscribeEffortProvider() {
if (viewerScroller == null) {
return;
}
EffortProvider effProv = mapPanel.findEffortProvider();
if (effProv != null) {
viewerScroller.addDataBlock(effProv.getParentDataBlock());
}
}
public PamScrollSlider getViewerScroller() {
return viewerScroller;
}
@ -1206,6 +1233,7 @@ public class SimpleMap extends JPanel implements PamObserver, PamScrollObserver,
getViewerScroller().reLoad();
}
}
effortDataBlock = PamController.getInstance().getDataBlockByLongName(mapParameters.effortDataSource);
}
@Override

View File

@ -8,6 +8,7 @@ public class InputStoreInfo {
private int nFiles;
private long firstFileStart, lastFileStart, lastFileEnd;
private long[] fileStartTimes;
private long[] allFileEnds;
public InputStoreInfo(DataInputStore dataInputStore, int nFiles, long firstFileStart, long lastFileStart, long lastFileEnd) {
super();
@ -97,6 +98,21 @@ public class InputStoreInfo {
this.lastFileEnd = lastFileEnd;
}
/**
* Set all file end times.
* @param allFileEnds
*/
public void setFileEndTimes(long[] allFileEnds) {
this.allFileEnds = allFileEnds;
}
/**
* @return the allFileEnds
*/
public long[] getAllFileEnds() {
return allFileEnds;
}
}

View File

@ -1334,7 +1334,13 @@ public class PamController implements PamControllerInterface, PamSettings {
}
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
for (int iP = 0; iP < pamControlledUnits.get(iU).getNumPamProcesses(); iP++) {
pamControlledUnits.get(iU).getPamProcess(iP).pamStart();
PamProcess pamProcess = pamControlledUnits.get(iU).getPamProcess(iP);
pamProcess.pamStart();
int nOut = pamProcess.getNumOutputDataBlocks();
for (int iB = 0; iB < nOut; iB++) {
PamDataBlock outBlock = pamProcess.getOutputDataBlock(iB);
outBlock.pamStart(startTime);
}
}
// long t2 = System.currentTimeMillis();
// System.out.printf("==================================Time taken to call
@ -1379,10 +1385,18 @@ public class PamController implements PamControllerInterface, PamSettings {
// statusCheckThread.start();
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
long stopTime = PamCalendar.getTimeInMillis();
// tell all controlled units to stop
for (int iU = 0; iU < pamControlledUnits.size(); iU++) {
for (int iP = 0; iP < pamControlledUnits.get(iU).getNumPamProcesses(); iP++) {
pamControlledUnits.get(iU).getPamProcess(iP).pamStop();
PamProcess pamProcess = pamControlledUnits.get(iU).getPamProcess(iP);
pamProcess.pamStop();
int nOut = pamProcess.getNumOutputDataBlocks();
for (int iB = 0; iB < nOut; iB++) {
PamDataBlock outBlock = pamProcess.getOutputDataBlock(iB);
outBlock.pamStop(stopTime);
}
}
}

View File

@ -36,7 +36,7 @@ public class PamguardVersionInfo {
/**
* Release date
*/
static public final String date = "24 June 2024";
static public final String date = "19 August 2024";
// /**
// * Release type - Beta or Core

View File

@ -11,6 +11,7 @@ public class LocContents implements LocalisationInfo {
/**Flags for what type of 'Raw' localisation information from a detection**/
/**
* Time delays are present
*/
@ -78,8 +79,47 @@ public class LocContents implements LocalisationInfo {
/**
* Errors parallel and perpendicular to the ships track.
*/
static public final int HAS_PERPENDICULARERRORS = 0x100;
static public final int HAS_PERPENDICULARERRORS = 0x1000;
static public final int[] allTypes = {HAS_TIMEDELAYS, HAS_ECHO, HAS_BEARING, HAS_BEARINGERROR, HAS_RANGE, HAS_RANGEERROR, HAS_DEPTH, HAS_DEPTHERROR,
HAS_LATLONG, HAS_XY, HAS_XYZ, HAS_AMBIGUITY, HAS_PERPENDICULARERRORS};
/**
* Main types of interest.
*/
static public final int[] mainTypes = {HAS_BEARING, HAS_RANGE, HAS_DEPTH, HAS_LATLONG, HAS_XY, HAS_XYZ};
public static String getTypeString(int type) {
switch (type) {
case HAS_TIMEDELAYS:
return "Time delays";
case HAS_ECHO:
return "Echoes";
case HAS_BEARING:
return "Bearing";
case HAS_BEARINGERROR:
return "Bearing Error";
case HAS_RANGE:
return "Range";
case HAS_DEPTH:
return "Depth";
case HAS_RANGEERROR:
return "Range Error";
case HAS_DEPTHERROR:
return "Depth Error";
case HAS_LATLONG:
return "Lat Long";
case HAS_XY:
return "XY";
case HAS_XYZ:
return "XYZ";
case HAS_AMBIGUITY:
return "Ambiguity";
case HAS_PERPENDICULARERRORS:
return "Perpendicular Errors";
}
return null;
}
/**
* bitmap of flags saying what's in the localisation information

View File

@ -46,6 +46,7 @@ import fftManager.PamFFTControl;
import group3dlocaliser.Group3DLocaliserControl;
import meygenturbine.MeygenTurbine;
import printscreen.PrintScreenControl;
import ravendata.RavenControl;
import rockBlock.RockBlockControl;
import tethys.TethysControl;
import turbineops.TurbineOperationControl;
@ -469,6 +470,12 @@ final public class PamModel implements PamSettings {
mi.setMaxNumber(1);
//mi.addGUICompatabilityFlag(PamGUIManager.FX); //has FX enabled GUI.
mi.setHidden(SMRUEnable.isEnable() == false);
mi = PamModuleInfo.registerControlledUnit(RavenControl.class.getName(), RavenControl.defaultName);
mi.setToolTipText("Import data from Raven selection tables");
mi.setModulesMenuGroup(utilitiesGroup);
mi.setHidden(SMRUEnable.isEnable() == false);
}
/*

View File

@ -234,6 +234,8 @@ public class PamModuleInfo implements PamDependent{
// Class[] paramList = new Class[1];
// paramList[0] = unitName.getClass();
boolean error = false;
long tic = System.currentTimeMillis();
long toc = tic;
try {
Constructor constructor = moduleClass.getConstructor(constrParams1);
newUnit = (PamControlledUnit) constructor.newInstance(pamConfiguration, unitName);
@ -262,6 +264,11 @@ public class PamModuleInfo implements PamDependent{
return null;
}
}
toc = System.currentTimeMillis();
if (toc-tic > 1000) {
System.out.printf("Module %s-%s was slow to load, taking %3.1f seconds\n", newUnit.getUnitType(),
newUnit.getUnitName(), (double)(toc-tic)/1000.);
}
setNInstances(nInstances + 1);

View File

@ -703,7 +703,7 @@ public class PamDetectionOverlayGraphics extends PanelOverlayDraw {
Coordinate3d topLeft = generalProjector.getCoord3d(pamDetection.getTimeMilliseconds(),
frequency[1], 0);
Coordinate3d botRight = generalProjector.getCoord3d(pamDetection.getTimeMilliseconds() +
pamDetection.getSampleDuration() * 1000./parentDataBlock.getSampleRate(),
pamDetection.getDurationInMilliseconds(),
frequency[0], 0);
if (botRight.x < topLeft.x){

View File

@ -306,6 +306,9 @@ abstract public class PamDialog extends JDialog {
* put the dialog near the mouse location.
*/
public void moveToMouseLocation() {
if (MouseInfo.getPointerInfo() == null) {
return;
}
Point mouse = MouseInfo.getPointerInfo().getLocation();
moveToLocation(mouse);
}

View File

@ -372,6 +372,10 @@ public class WarnOnce implements PamSettings {
return -1;
}
if (parent == null) {
parent = PamController.getMainFrame();
}
// show the warning
if (canShowDialog()) {
WarnOnceDialog wo = new WarnOnceDialog(parent, title, message, messageType, helpPoint, error, okButtonText, cancelButtonText);

View File

@ -2,6 +2,7 @@ package PamView.symbol;
import java.awt.Color;
import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import PamUtils.PamArrayUtils;
@ -131,6 +132,12 @@ public class StandardSymbolOptions extends PamSymbolOptions implements Serializa
* @param i - the index of the symbol modifier (not modified).
*/
public void setEnabled(boolean enabled, int i) {
if (isEnabled == null) {
isEnabled = new boolean[i+1];
}
else if (isEnabled.length < i+1) {
isEnabled = Arrays.copyOf(isEnabled, i+1);
}
isEnabled[i] = enabled;
}

View File

@ -1,6 +1,9 @@
package PamView.symbol;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.Serializable;
import PamView.PamSymbolType;
@ -165,4 +168,17 @@ public class SymbolData implements Serializable, Cloneable {
this.symbol = symbol;
}
/**
* Set the line properties for the given graphics handle.
* @param g
*/
public void setGraphicsProperties(Graphics g) {
if (lineColor != null) {
g.setColor(lineColor);
}
if (lineThickness != 1) {
((Graphics2D) g).setStroke(new BasicStroke(lineThickness));
}
}
}

View File

@ -0,0 +1,21 @@
package PamView.symbol;
import PamguardMVC.PamDataBlock;
/**
* Version of the standard symbol manager that only has the optoin on the main
* symbol type and no modifiers whatsoever.
* @author dg50
*
*/
public class SymbolOnlyManager extends StandardSymbolManager {
public SymbolOnlyManager(PamDataBlock pamDataBlock, SymbolData defaultSymbol) {
super(pamDataBlock, defaultSymbol);
// TODO Auto-generated constructor stub
}
@Override
public void addSymbolModifiers(PamSymbolChooser psc) {
}
}

View File

@ -49,6 +49,7 @@ import org.w3c.dom.Element;
import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionProcess;
import Localiser.LocalisationAlgorithm;
import pamScrollSystem.ViewLoadObserver;
import tethys.TethysControl;
import tethys.pamdata.AutoTethysProvider;
@ -57,10 +58,13 @@ import tethys.species.DataBlockSpeciesManager;
import dataGram.DatagramProvider;
import dataMap.BespokeDataMapGraphic;
import dataMap.OfflineDataMap;
import effort.EffortProvider;
import effort.binary.DataMapEffortProvider;
import annotation.DataAnnotationType;
import annotation.handler.AnnotationHandler;
import binaryFileStorage.BinaryDataSource;
import binaryFileStorage.BinaryOfflineDataMap;
import binaryFileStorage.BinaryStore;
import binaryFileStorage.SecondaryBinaryStore;
import PamController.OfflineDataStore;
import PamController.PamControlledUnit;
@ -1080,6 +1084,11 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
System.err.printf("Not loading %s since initialisation not yet complete\n", getDataName());
return false;
}
// long tenDays = 3600L*24L*1000L*10L;
// if (offlineDataLoadInfo.getEndMillis() - offlineDataLoadInfo.getStartMillis() > tenDays) {
// System.out.printf("Big many day data load %s to %s in %s", PamCalendar.formatDateTime(offlineDataLoadInfo.getStartMillis()),
// PamCalendar.formatDateTime(offlineDataLoadInfo.getEndMillis()) ,getLongDataName());
// }
saveViewerData();
@ -1124,6 +1133,11 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
lastViewerUID = Math.max(lastViewerUID, uid);
}
EffortProvider effProv = getEffortProvider();
if (effProv != null) {
effProv.viewerLoadData();
}
return loadOk;
}
@ -1268,6 +1282,10 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
*/
if (shouldNotify()) {
notifyInstantObservers(pamDataUnit);
EffortProvider effProvider = getEffortProvider();
if (effProvider != null) {
effProvider.newData(pamDataUnit);
}
}
if (offlineDataLoading.isCurrentOfflineLoadKeep()) {
@ -2531,6 +2549,42 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
this.localisationContents.addLocContent(localisationContents);
}
/**
* Find localisation algorithm for this data.
* This may be within the owning module, or a downstream algorithm.
* @return first found localisation algorithm or null;
*/
public LocalisationAlgorithm getLocalisationAlgorithm() {
/*
* first check downstream modules. If these are in use, they
* probably override anything internal, so look for these first.
*/
List<PamObserver> instObs = getInstantObservers();
for (PamObserver obs : instObs) {
if (obs instanceof LocalisationAlgorithm) {
return (LocalisationAlgorithm) obs;
}
if (obs instanceof PamProcess) {
PamProcess proc = (PamProcess) obs;
PamControlledUnit pcu = proc.getPamControlledUnit();
if (pcu == null) {
continue;
}
if (pcu instanceof LocalisationAlgorithm) {
return (LocalisationAlgorithm) pcu;
}
}
}
// if nothing downstream, then check the owning module
PamProcess proc = getParentProcess();
if (proc == null) return null;
PamControlledUnit pcu = proc.getPamControlledUnit();
if (pcu instanceof LocalisationAlgorithm) {
return (LocalisationAlgorithm) pcu;
}
return null;
}
public static final int ITERATOR_END = -1;
/**
@ -3017,7 +3071,16 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
case PamControllerInterface.HYDROPHONE_ARRAY_CHANGED:
clearDataOrigins();
break;
case PamController.INITIALIZATION_COMPLETE:
effortProvider = autoEffortProvider();
break;
case PamController.ADD_CONTROLLEDUNIT:
if (PamController.getInstance().isInitializationComplete()) {
effortProvider = autoEffortProvider();
}
break;
}
}
/**
@ -3621,6 +3684,8 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
private DataSelectorCreator dataSelectorCreator;
private EffortProvider effortProvider;
public void setRecordingTrigger(RecorderTrigger recorderTrigger) {
this.recorderTrigger = recorderTrigger;
RecorderControl.registerRecorderTrigger(recorderTrigger);
@ -4308,4 +4373,60 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
}
}
}
/**
* @return the effort provider.
*/
public EffortProvider getEffortProvider() {
return effortProvider;
}
/**
* Auto generate an effort provider. This may get called many times
* for blocks without effort, but that doesn't really matter since its
* only going to happen when opening dialogs, etc.
* @return
*/
public EffortProvider autoEffortProvider() {
if (effortProvider != null) {
// don't change if there already is one.
return effortProvider;
}
// see if we can do an auto binary one.
BinaryStore binaryStore = BinaryStore.findBinaryStoreControl();
if (binaryStore != null && getBinaryDataSource() != null) {
return new DataMapEffortProvider(this, BinaryStore.class);
}
// other options may follow ...
return null;
}
/**
* @param effortProvider the effortProvider to set
*/
protected void setEffortProvider(EffortProvider effortProvider) {
this.effortProvider = effortProvider;
}
/**
* Need this notification at startup time to perform a few standard actions.
* @param startTime
*/
public void pamStart(long startTime) {
EffortProvider effP = getEffortProvider();
if (effP != null) {
effP.realTimeStart(startTime);
}
}
/**
* Need this notification at stop time to perform a few standard actions.
* @param startTime
*/
public void pamStop(long stopTime) {
EffortProvider effP = getEffortProvider();
if (effP != null) {
effP.realTimeStop(stopTime);
}
}
}

View File

@ -977,8 +977,16 @@ abstract public class PamDataUnit<T extends PamDataUnit, U extends PamDataUnit>
// add frequency and amplitude information
double[] frequency = this.getFrequency();
if (frequency != null) {
boolean allzeros = true;
for (int i = 0; i < frequency.length; i++) {
if (frequency[i] > 0) {
allzeros = false;
}
}
if (!allzeros) {
str += "Frequency: " + FrequencyFormat.formatFrequencyRange(this.getFrequency(), true) + "<br>";
}
}
if (getAmplitudeDB() != 0) {
str += String.format("Amplitude: %3.1fdB<br>", getAmplitudeDB());
}

View File

@ -562,6 +562,20 @@ public class PamObservable {//extends PanelOverlayDraw {
return PamModel.getPamModel().getPamModelSettings().getThreadingJitterMillis();
}
/**
* @return the pamObservers
*/
protected List<PamObserver> getPamObservers() {
return pamObservers;
}
/**
* @return the instantObservers
*/
protected List<PamObserver> getInstantObservers() {
return instantObservers;
}
// @Override
// public boolean hasOptionsDialog(GeneralProjector generalProjector) {
// if (overlayDraw != null) {

View File

@ -34,6 +34,8 @@ import Acquisition.RawDataBinaryDataSource;
import PamController.PamController;
import PamDetection.RawDataUnit;
import PamUtils.PamUtils;
import dataMap.OfflineDataMap;
import effort.EffortProvider;
/**
* Extension of RecyclingDataBlock that is used for Raw audio data.
@ -602,6 +604,13 @@ public class PamRawDataBlock extends AcousticDataBlock<RawDataUnit> {
}
}
@Override
public EffortProvider autoEffortProvider() {
return null;
}
// @Override
// protected void findParentSource() {
// super.findParentSource();

View File

@ -62,7 +62,7 @@ public class RWEProcess extends PamProcess {
this.rweControl = rweControl;
rweDataBlock = new RWEDataBlock(rweControl, rweControl.getUnitName(), this, 0);
addOutputDataBlock(rweDataBlock);
rweDataBlock.setLocalisationContents(LocContents.HAS_BEARING);
// rweDataBlock.setLocalisationContents(LocContents.HAS_BEARING);
rweDataBlock.setDatagramProvider(new RWEDatagramProvider());
rweDataBlock.setOverlayDraw(new RWEOverlayGraphics(this, rweDataBlock));
StandardSymbolManager symbolManager = symbolManager = new RWESymbolManager(rweDataBlock, RWEOverlayGraphics.defaultSymbol, true);
@ -138,6 +138,11 @@ public class RWEProcess extends PamProcess {
rweChannelProcesses[i] = new RWEChannelProcess(this, i);
}
}
int nChan = PamUtils.getNumChannels(channelMap);
if (nChan > 1) {
// really needs properly setting up with channel groups
rweDataBlock.setLocalisationContents(LocContents.HAS_BEARING);
}
// checkBearingLocaliser(sourceDataBlock.getChannelMap());
}
@ -433,6 +438,7 @@ public class RWEProcess extends PamProcess {
int hydrophoneMap = sourceDataBlock.getChannelListManager().channelIndexesToPhones(chanMap);
return findBearingLocaliser(hydrophoneMap);
}
private synchronized BearingLocaliser findBearingLocaliser(int hydrophoneMap) {
int nPhones = PamUtils.getNumChannels(hydrophoneMap);
if (nPhones < 2) {

View File

@ -132,6 +132,7 @@ import PamguardMVC.PamProcess;
import PamguardMVC.PamRawDataBlock;
import PamguardMVC.SimpleDataObserver;
import PamguardMVC.dataOffline.OfflineDataLoading;
import PamguardMVC.dataSelector.DataSelectParams;
import PamguardMVC.dataSelector.DataSelector;
import dataPlotsFX.data.DataTypeInfo;
import fftManager.FFTDataBlock;
@ -2927,6 +2928,10 @@ InternalFrameListener, DisplayPanelContainer, SpectrogramParametersUser, PamSett
// PamCalendar.formatTime(currentTimeMilliseconds)));
String name = spectrogramDisplay.getDataSelectorName(panelId);
DataSelector dataSelector = usedDataBlock.getDataSelector(name, false);
if (dataSelector != null && dataSelector.getParams().getCombinationFlag() == DataSelectParams.DATA_SELECT_DISABLE) {
dataSelector = null;
}
directDrawProjector.setDataSelector(dataSelector);
if (usedDataBlock.getPamSymbolManager() != null) {
directDrawProjector.setPamSymbolChooser(usedDataBlock.getPamSymbolManager().getSymbolChooser(name, directDrawProjector));

View File

@ -4,6 +4,8 @@ import PamController.PamControlledUnit;
import PamView.symbol.StandardSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
import annotationMark.fx.MarkDataPlotInfo;
import annotationMark.fx.MarkPlotProviderFX;
import dataPlotsFX.data.TDDataProviderRegisterFX;
import dataPlotsFX.data.generic.GenericDataPlotProvider;
@ -28,7 +30,7 @@ public class MarkProcess extends PamProcess {
markDataBlock.setPamSymbolManager(new StandardSymbolManager(markDataBlock, MarkOverlayDraw.defaultSymbolData, false));
addOutputDataBlock(markDataBlock);
TDDataProviderRegisterFX.getInstance().registerDataInfo(genericDataPloProvider = new GenericDataPlotProvider(markDataBlock));
TDDataProviderRegisterFX.getInstance().registerDataInfo(genericDataPloProvider = new MarkPlotProviderFX(markDataBlock));
// markDataBlock.setOverlayDraw(new S);
}

View File

@ -0,0 +1,29 @@
package annotationMark.fx;
import PamDetection.AbstractLocalisation;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import dataPlotsFX.data.generic.GenericDataPlotInfo;
import dataPlotsFX.layout.TDGraphFX;
public class MarkDataPlotInfo extends GenericDataPlotInfo {
public MarkDataPlotInfo(MarkPlotProviderFX tdDataProvider, TDGraphFX tdGraph, PamDataBlock pamDataBlock) {
super(tdDataProvider, tdGraph, pamDataBlock);
// TODO Auto-generated constructor stub
}
public Double getBearingValue(PamDataUnit pamDataUnit) {
AbstractLocalisation locData = pamDataUnit.getLocalisation();
if (locData == null) {
return null;
}
double[] angles = locData.getAngles();
if (angles != null) {
return Math.toDegrees(angles[0]);
}
return null;
}
}

View File

@ -0,0 +1,20 @@
package annotationMark.fx;
import annotationMark.MarkDataBlock;
import dataPlotsFX.data.TDDataInfoFX;
import dataPlotsFX.data.generic.GenericDataPlotProvider;
import dataPlotsFX.layout.TDGraphFX;
public class MarkPlotProviderFX extends GenericDataPlotProvider {
public MarkPlotProviderFX(MarkDataBlock parentDataBlock) {
super(parentDataBlock);
}
@Override
public TDDataInfoFX createDataInfo(TDGraphFX tdGraph) {
return new MarkDataPlotInfo(this, tdGraph, getDataBlock());
}
}

View File

@ -25,7 +25,15 @@ public class AsioDriverInfos {
}
/**
* Gets called back from the jni call to callJniGetAsioDrivers
* @param driverName
* @param maxChannels
* @param sampleRateInfo
*/
public void addDriverToList(String driverName, int[] maxChannels, int[]sampleRateInfo){
lastDriverEnumeration = System.currentTimeMillis();
System.out.printf("Getting driver detail for ASIO %s took %3.1fs\n", driverName, (double) (lastDriverEnumeration-driverEnumerationStart)/1000.);
ArrayList<Integer>sampleRates = new ArrayList<Integer>();
ArrayList<Integer>maxAvailableChannels = new ArrayList<Integer>();
for(int i = 0;i<sampleRateInfo.length;i++){
@ -34,13 +42,22 @@ public class AsioDriverInfos {
}
AsioDriverInfo asioDriverInfo = new AsioDriverInfo(driverName, maxAvailableChannels,sampleRates);
asioDriverList.add(asioDriverInfo);
driverEnumerationStart = System.currentTimeMillis();
}
long driverEnumerationStart;
long lastDriverEnumeration;
private ArrayList<AsioDriverInfo> getAsioDriverList() {
clearDriverList();
long t1 = System.currentTimeMillis();
driverEnumerationStart = t1;
asioJniInterface.callJniGetAsioDrivers(this);
long t2 = System.currentTimeMillis();
System.out.printf("Call to asioJniInterface.callJniGetAsioDrivers took %3.1fs\n", (double) (t2-t1)/1000.);
for(int i = 0; i<asioDriverList.size();i++){
System.out.printf("ASIO drivers: " + asioDriverList.get(i).driverName + " maxChannels: " + asioDriverList.get(i).maxChannels + " Can sample at ");
long tic = System.currentTimeMillis();
boolean firstHz = true;
for(int j = 0;j<asioDriverList.get(i).sampleRateInfo.size();j++){
if (firstHz == false) {
@ -53,10 +70,15 @@ public class AsioDriverInfos {
firstHz = false;
}
System.out.printf(" Hz\n");
long toc = System.currentTimeMillis();
if (toc-tic > 1000) {
System.out.printf("Checking cababilities for ASIO %s took %3.1fs\n", asioDriverList.get(i).driverName,
(double) (toc-tic)/1000.);
}
// System.out.println();
// System.out.println("Java:: just called asioJniInterface.callJniGetAsioDrivers(this);");
// System.out.flush();
}
// System.out.println();
// System.out.println("Java:: just called asioJniInterface.callJniGetAsioDrivers(this);");
// System.out.flush();
return asioDriverList;
}
@ -65,11 +87,14 @@ public class AsioDriverInfos {
// System.out.println("getCurrentAsioDriverList():: asioDriverList.size()=" + asioDriverList.size());
// System.out.flush();
if(asioDriverList.size()==0){
return asioDriverList = getAsioDriverList();
long tic = System.currentTimeMillis();
asioDriverList = getAsioDriverList();
long toc = System.currentTimeMillis();
if (toc-tic>1000) {
System.out.printf("Enumerating ASIO driver list took %3.1fs\n", (double)(toc-tic)/1000.);
}
}
else{
return asioDriverList;
}
}

View File

@ -10,14 +10,18 @@ import java.util.List;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings;
import PamController.PamController;
import PamController.PamSettingManager;
import PamController.PamSettings;
import PamDetection.LocContents;
import PamUtils.SimpleObservable;
import PamguardMVC.PamDataUnit;
import beamformer.algorithms.BeamAlgorithmProvider;
import bearinglocaliser.algorithms.BearingAlgorithm;
import bearinglocaliser.algorithms.BearingAlgorithmProvider;
import bearinglocaliser.annotation.BearingAnnotationType;
import bearinglocaliser.beamformer.BeamFormBearingWrapper;
@ -28,9 +32,10 @@ import bearinglocaliser.toad.TOADBearingProvider;
import offlineProcessing.OLProcessDialog;
import offlineProcessing.OfflineTaskGroup;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX2AWT;
import tethys.localization.LocalizationCreator;
import userDisplay.UserDisplayControl;
public class BearingLocaliserControl extends PamControlledUnit implements PamSettings {
public class BearingLocaliserControl extends PamControlledUnit implements PamSettings, LocalisationAlgorithm, LocalisationAlgorithmInfo {
public static final String unitType = "Bearing Calculator";
@ -228,4 +233,52 @@ public class BearingLocaliserControl extends PamControlledUnit implements PamSet
public String getHelpPoint() {
return helpPoint;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return this;
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
private BearingAlgorithm findAlgorithm() {
BearingAlgorithmGroup[] groups = bearingProcess.getBearingAlgorithmGroups();
if (groups == null) {
return null;
}
for (int i = 0; i < groups.length; i++) {
BearingAlgorithm ba = groups[i].bearingAlgorithm;
if (ba != null) {
return ba;
}
}
return null;
}
@Override
public int getLocalisationContents() {
int cont = LocContents.HAS_BEARING | LocContents.HAS_BEARINGERROR;
// work out if we should also add ambiguity. How to work that out ?
return cont;
}
@Override
public String getAlgorithmName() {
// BearingAlgorithm ba = findAlgorithm();
// if (ba == null) {
// return null;
// }
// ba.getParams().
return getUnitType();
}
@Override
public Serializable getParameters() {
return bearingLocaliserParams;
}
}

View File

@ -39,11 +39,12 @@ import org.w3c.dom.Element;
import rocca.RoccaControl;
import soundPlayback.PlaybackControl;
import targetMotionOld.TargetMotionLocaliser;
import tethys.localization.LocalizationCreator;
import binaryFileStorage.BinaryStore;
import Filters.FilterDialog;
import Filters.FilterParams;
import Localiser.LocalisationAlgorithm;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.detectionGroupLocaliser.GroupDetection;
import PamController.PamConfiguration;
import PamController.PamControlledUnit;
@ -112,7 +113,7 @@ import offlineProcessing.OfflineTaskGroup;
*
*/
public class ClickControl extends PamControlledUnit implements PamSettings {
public class ClickControl extends PamControlledUnit implements PamSettings, LocalisationAlgorithm {
protected ClickDetector clickDetector;
@ -1293,5 +1294,16 @@ public class ClickControl extends PamControlledUnit implements PamSettings {
return clickFFTDataOrganiser;
}
@Override
public LocalisationAlgorithmInfo getAlgorithmInfo() {
return clickDetector.getLocaliserInfo();
}
@Override
public LocalizationCreator getTethysCreator() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -2,6 +2,7 @@ package clickDetector;
import java.util.ListIterator;
import Localiser.LocalisationAlgorithm;
import pamScrollSystem.ViewLoadObserver;
import tethys.TethysControl;
import tethys.pamdata.TethysDataProvider;
@ -336,5 +337,15 @@ public class ClickDataBlock extends AcousticDataBlock<ClickDetection> implement
return new DataAutomationInfo(DataAutomation.AUTOMATIC);
}
@Override
public LocalisationAlgorithm getLocalisationAlgorithm() {
/*
* This is usually the bearing algorithm from click control.
* Howeveer, someone may have added an additional bearing localiser
* in which case, the default function should find that.
*/
return super.getLocalisationAlgorithm();
}
}

View File

@ -42,6 +42,7 @@ import Filters.Filter;
import Filters.FilterMethod;
import Filters.FilterType;
import Localiser.DelayMeasurementParams;
import Localiser.LocalisationAlgorithmInfo;
import Localiser.algorithms.Correlations;
import Localiser.algorithms.DelayGroup;
import Localiser.algorithms.TimeDelayData;
@ -312,19 +313,19 @@ public class ClickDetector extends PamProcess {
offlineEventDataBlock.SetLogging(offlineEventLogging);
targetMotionSQLLogging = new TargetMotionSQLLogging(2);
offlineEventLogging.addAddOn(targetMotionSQLLogging);
if (isViewer) {
// offlineEventDataBlock = new
// OfflineEventDataBlock(clickControl.getUnitName()+"_OfflineEvents",
// this, 0);
// offlineEventLogging = new OfflineEventLogging(clickControl,
// offlineEventDataBlock);
// targetMotionSQLLogging = new TargetMotionSQLLogging(2);
// offlineEventLogging.addAddOn(targetMotionSQLLogging);
// offlineEventDataBlock.SetLogging(offlineEventLogging);
} else { // for normal and mixed mode.
// if (isViewer) {
// // offlineEventDataBlock = new
// // OfflineEventDataBlock(clickControl.getUnitName()+"_OfflineEvents",
// // this, 0);
// // offlineEventLogging = new OfflineEventLogging(clickControl,
// // offlineEventDataBlock);
// // targetMotionSQLLogging = new TargetMotionSQLLogging(2);
// // offlineEventLogging.addAddOn(targetMotionSQLLogging);
// // offlineEventDataBlock.SetLogging(offlineEventLogging);
// } else { // for normal and mixed mode.
offlineEventDataBlock.setLocalisationContents(LocContents.HAS_BEARING | LocContents.HAS_RANGE
| LocContents.HAS_LATLONG | LocContents.HAS_AMBIGUITY | LocContents.HAS_PERPENDICULARERRORS);
}
// }
// set up the subtable for the Event Logger, and force creation
offlineEventLogging.setSubLogging(getClickDataBlock().getOfflineClickLogging());
@ -458,6 +459,8 @@ public class ClickDetector extends PamProcess {
nChannelGroups = GroupedSourcePanel.countChannelGroups(cp.getChannelBitmap(), cp.getChannelGroups());
int groupChannels;
channelGroupDetectors = new ChannelGroupDetector[nChannelGroups];
int locContents = 0;
for (int i = 0; i < nChannelGroups; i++) {
groupChannels = GroupedSourcePanel.getGroupChannels(i, cp.getChannelBitmap(), cp.getChannelGroups());
channelGroupDetectors[i] = new ChannelGroupDetector(i, groupChannels);
@ -467,9 +470,21 @@ public class ClickDetector extends PamProcess {
if (multiThread) {
channelGroupDetectors[i].halfBuiltClicks.addObserver(newClickMonitor, true);
}
if (channelGroupDetectors[i].bearingLocaliser != null) {
locContents |= channelGroupDetectors[i].bearingLocaliser.getLocalisationContents();
}
// System.out.println("Group " + i + " contains channels list " +
// groupChannels);
}
outputClickData.setLocalisationContents(locContents);
if (locContents == 0) {
offlineEventDataBlock.setLocalisationContents(0);
}
else {
int eventLocCont = LocContents.HAS_LATLONG | LocContents.HAS_XYZ | LocContents.HAS_RANGE;
eventLocCont |= (locContents & LocContents.HAS_AMBIGUITY);
offlineEventDataBlock.setLocalisationContents(eventLocCont);
}
globalChannelList = new int[nChan = PamUtils
.getNumChannels(clickControl.clickParameters.getChannelBitmap())];
@ -2095,4 +2110,22 @@ public class ClickDetector extends PamProcess {
super.destroyProcess();
newClickMonitor.destroyProcess();
}
/**
* Get information about the internal bearing localiser. Will have to do
* just for the first sub detector.
* @return
*/
public LocalisationAlgorithmInfo getLocaliserInfo() {
if (channelGroupDetectors == null || channelGroupDetectors.length == 0) {
return null;
}
BearingLocaliser bl = channelGroupDetectors[0].bearingLocaliser;
if (bl == null) {
return null;
}
else {
return bl.getAlgorithmInfo();
}
}
}

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Vector;
import Localiser.LocalisationAlgorithm;
import Localiser.detectionGroupLocaliser.GroupDetection;
import PamController.PamController;
import PamController.PamControllerInterface;
@ -16,9 +17,11 @@ import PamController.PamViewParameters;
import PamUtils.PamCalendar;
import PamView.symbol.StandardSymbolManager;
import pamScrollSystem.ViewLoadObserver;
import targetMotionOld.TargetMotionLocaliser;
import tethys.TethysControl;
import tethys.pamdata.TethysDataProvider;
import tethys.species.DataBlockSpeciesManager;
import clickDetector.ClickControl;
import clickDetector.ClickDetection;
//import staticLocaliser.StaticLocaliserControl;
//import staticLocaliser.StaticLocaliserProvider;
@ -317,6 +320,20 @@ public class OfflineEventDataBlock extends SuperDetDataBlock<OfflineEventDataUni
return new DataAutomationInfo(DataAutomation.MANUALANDAUTOMATIC);
}
@Override
public LocalisationAlgorithm getLocalisationAlgorithm() {
/**
* Need to override the default, which would have been finding the
* main click control. Here, we need to explicitly find the
* Target Motion Localiser
*/
ClickControl clickControl = clickDetector.getClickControl();
ClicksOffline clicksOffline = clickControl.getClicksOffline();
TargetMotionLocaliser<GroupDetection> tml = clickControl.getTargetMotionLocaliser();
return tml;
// return super.getLocalisationAlgorithm();
}
}

View File

@ -27,9 +27,11 @@ public class ClickEventTethysDataProvider extends AutoTethysProvider {
@Override
public GranularityEnumType[] getAllowedGranularities() {
// these are by definition grouped.
GranularityEnumType[] allowed = {GranularityEnumType.GROUPED};
return allowed;
}
@Override
public Detection createDetection(PamDataUnit dataUnit, TethysExportParams tethysExportParams,
StreamExportParams streamExportParams) {
@ -59,14 +61,19 @@ public class ClickEventTethysDataProvider extends AutoTethysProvider {
addUserDefined(params, numName, number.toString());
}
// @Override
// public boolean wantExportDialogCard(ExportWizardCard wizPanel) {
//// if (wizPanel.getClass() == GranularityCard.class) {
//// return false;
//// }
//// else {
// return true;
//// }
// }
@Override
public boolean wantExportDialogCard(ExportWizardCard wizPanel) {
if (wizPanel.getClass() == GranularityCard.class) {
return false;
}
else {
public boolean granularityOK(GranularityEnumType granularityType) {
return true;
}
}
}

View File

@ -24,11 +24,13 @@ import dataPlotsFX.data.TDDataInfoFX;
import dataPlotsFX.data.TDDataProviderFX;
import dataPlotsFX.data.TDScaleInfo;
import dataPlotsFX.layout.TDGraphFX;
import dataPlotsFX.layout.TDSettingsPane;
import dataPlotsFX.projector.TDProjectorFX;
import javafx.geometry.Point2D;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import pamViewFX.fxNodes.PamSymbolFX;
/**
* Generic data plot info which can work for a wide variety of data types. May still
@ -57,7 +59,7 @@ public class GenericDataPlotInfo extends TDDataInfoFX {
private TDSymbolChooserFX managedSymbolChooser;
private GenericSettingsPane genericSettingsPane;
/**
* The frequency info
*/
@ -76,10 +78,10 @@ public class GenericDataPlotInfo extends TDDataInfoFX {
bearingScaleInfo.setReverseAxis(true); //set the axis to be reverse so 0 is at top of graph
ampScaleInfo = new GenericScaleInfo(100, 200, ParameterType.AMPLITUDE, ParameterUnits.DB);
slantScaleInfo = new GenericScaleInfo(0, 180, ParameterType.SLANTBEARING, ParameterUnits.DEGREES);
frequencyInfo = new GenericScaleInfo(0, 1, ParameterType.FREQUENCY, ParameterUnits.HZ);
Arrays.fill(frequencyInfo.getPlotChannels(),1); //TODO-manage plot pane channels somehow.
frequencyInfo.setMaxVal(pamDataBlock.getSampleRate()/2);
genericSettingsPane = new GenericSettingsPane(this);
addScaleInfo(bearingScaleInfo);
addScaleInfo(slantScaleInfo);
@ -118,6 +120,11 @@ public class GenericDataPlotInfo extends TDDataInfoFX {
g.setLineDashes(null);
g.setLineWidth(2);
TDSymbolChooserFX symbolChooser = getSymbolChooser();
PamSymbolFX symbol = null;
if (symbolChooser != null) {
symbol = symbolChooser.getPamSymbol(pamDataUnit, type);
}
double[] f = pamDataUnit.getFrequency();
if (f == null) {
@ -131,10 +138,14 @@ public class GenericDataPlotInfo extends TDDataInfoFX {
double y1 = tdProjector.getYPix(f[1]);
double x0 = tdProjector.getTimePix(pamDataUnit.getTimeMilliseconds()-scrollStart);
double x1 = tdProjector.getTimePix(pamDataUnit.getEndTimeInMilliseconds()-scrollStart);
g.setStroke(getSymbolChooser().getPamSymbol(pamDataUnit, type).getLineColor());
if (symbol != null) {
g.setStroke(symbol.getLineColor());
g.setLineWidth(symbol.getLineThickness());
Color fillCol = symbol.getFillColor();
double alpha = fillCol.getOpacity();
g.setFill(Color.color(fillCol.getRed(), fillCol.getGreen(), fillCol.getBlue(), alpha)); //add alpha
}
Color fillCol = getSymbolChooser().getPamSymbol(pamDataUnit, type).getFillColor();
g.setFill(Color.color(fillCol.getRed(), fillCol.getGreen(), fillCol.getBlue(), 0.4)); //add alpha
double y = Math.min(y0, y1);
double h = Math.abs(y1-y0);
@ -174,6 +185,11 @@ public class GenericDataPlotInfo extends TDDataInfoFX {
}
@Override
public TDSettingsPane getGraphSettingsPane() {
return genericSettingsPane;
}
@Override
public Double getDataValue(PamDataUnit pamDataUnit) {
@ -261,9 +277,9 @@ public class GenericDataPlotInfo extends TDDataInfoFX {
@Override
public TDSymbolChooserFX getSymbolChooser() {
if (managedSymbolChooser == null) {
// if (managedSymbolChooser == null) {
managedSymbolChooser = createSymbolChooser();
}
// }
return managedSymbolChooser;
}

View File

@ -0,0 +1,104 @@
package effort;
import PamUtils.PamCalendar;
import PamguardMVC.PamDataUnit;
public class EffortDataUnit extends PamDataUnit {
/**
* Value for effort end to say that effort is ongoing.
*/
public static final long ONGOINGEFFORT = Long.MAX_VALUE/2;
private PamDataUnit referenceDataUnit;
private EffortProvider effortProvider;
public EffortDataUnit(EffortProvider effortProvider, PamDataUnit referenceDataUnit, long effortStart, long effortEnd) {
super(effortStart);
getBasicData().setEndTime(effortEnd);
this.effortProvider = effortProvider;
this.setReferenceDataUnit(referenceDataUnit);
}
/**
*
* @return Start of effort period.
*/
public long getEffortStart() {
return getTimeMilliseconds();
}
/**
*
* @return End of effort period.
*/
public long getEffortEnd() {
return getEndTimeInMilliseconds();
}
/**
* Set the effort end time
* @param endTime
*/
public void setEffortEnd(long endTime) {
getBasicData().setEndTime(endTime);
}
/**
*
* @param timeMilliseconds
* @return time is in effort period
*/
public boolean inEffort(long timeMilliseconds) {
return (timeMilliseconds >= getEffortStart() && timeMilliseconds <= getEffortEnd());
}
/**
* Description of the effort, for tool tips, etc.
* @return
*/
public String getEffortDescription() {
return this.getSummaryString();
}
/**
* @return the referenceDataUnit
*/
public PamDataUnit getReferenceDataUnit() {
return referenceDataUnit;
}
/**
* @param referenceDataUnit the referenceDataUnit to set
*/
public void setReferenceDataUnit(PamDataUnit referenceDataUnit) {
this.referenceDataUnit = referenceDataUnit;
}
@Override
public String toString() {
String str;
if (getEffortEnd() >= ONGOINGEFFORT/2) {
str = String.format("%s ongoing from %s",effortProvider.getName(), PamCalendar.formatDBDateTime(getEffortStart()));
}
else {
str = String.format("%s %s to %s",effortProvider.getName(), PamCalendar.formatDBDateTime(getEffortStart()), PamCalendar.formatDBDateTime(getEffortEnd()));
}
if (referenceDataUnit != null) {
str += "<br>" + referenceDataUnit.getSummaryString();
}
return str;
}
@Override
public int compareTo(PamDataUnit o) {
if (o instanceof EffortDataUnit) {
EffortDataUnit oth = (EffortDataUnit) o;
return (int) (oth.getEffortStart()-getEffortStart());
}
return 0;
}
}

View File

@ -0,0 +1,50 @@
package effort;
import java.util.ArrayList;
import PamController.PamController;
import PamguardMVC.PamDataBlock;
/**
* Singleton class to provide management for all types of Effort in PAMGuard.
* @author dg50
*
*/
public class EffortManager {
private static EffortManager singleInstance;
private EffortManager() {
}
/**
* Get singleton instance of EffortManager
* @return
*/
public static EffortManager getEffortManager() {
if (singleInstance == null) {
singleInstance = new EffortManager();
}
return singleInstance;
}
/**
* Get a list of all data blocks that might provide effort data.
* @return
*/
public ArrayList<PamDataBlock> getEffortDataBlocks() {
ArrayList<PamDataBlock> allBlocks = getPamController().getDataBlocks();
ArrayList<PamDataBlock> effortBlocks = new ArrayList();
for (PamDataBlock aBlock : allBlocks) {
if (aBlock.getEffortProvider() != null) {
effortBlocks.add(aBlock);
}
}
return effortBlocks;
}
private PamController getPamController() {
return PamController.getInstance();
}
}

View File

@ -0,0 +1,192 @@
package effort;
import java.awt.Frame;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import Map.MapParametersDialog;
import PamController.PamController;
import PamView.GeneralProjector;
import PamView.PamSymbol;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
import PamView.symbol.SwingSymbolOptionsPanel;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelectDialog;
import PamguardMVC.dataSelector.DataSelector;
/**
* Set of functions that can be returned from any datablock which can
* give information about effort. For detectors with binary storage, they
* will return a standard binary store effort provider. Others, e.g.
* logger forms, acquisition, etc. can so something much more bespoke. <p>
* For real time, will need quite different behaviour to offline. Datablocks
* with a effortProvider are going to notify this and a local list will be
* kept of starts and ends for the entire operation period. This will be
* overridden for differeing offline scenarios and bespoke cases such as
* logger forms (so need to get a notification in here for every data unit too !)
* @author dg50
*
*/
public abstract class EffortProvider {
private PamDataBlock parentDataBlock;
private boolean isViewer;
public EffortProvider(PamDataBlock parentDataBlock) {
super();
this.parentDataBlock = parentDataBlock;
this.isViewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
}
/**
* Notified at real time start.
* @param timeMilliseconds
*/
public abstract void realTimeStart(long timeMilliseconds);
/**
* notified at real time end
* @param timeMilliseconds
*/
public abstract void realTimeStop(long timeMilliseconds); ;
/**
* Notified for real time data.
* @param pamDataUnit
*/
public abstract void newData(PamDataUnit pamDataUnit); ;
/**
* Get the effort for a specific time.
* @param timeMilliseconds
* @return Effort thing. Can be null if off effort.
*/
public EffortDataUnit getEffort(long timeMilliseconds) {
List<EffortDataUnit> allEfforts = getAllEffortThings();
if (allEfforts == null) {
return null;
}
Iterator<EffortDataUnit> it = allEfforts.iterator();
while (it.hasNext()) {
EffortDataUnit next = it.next();
if (timeMilliseconds >= next.getEffortStart() && timeMilliseconds <= next.getEffortEnd()) {
return next;
}
}
return null;
}
/**
* Called when viewer data have been loaded for the parent datablock.
*/
public abstract void viewerLoadData();
/**
* Get all effort things. e.g. for binary data this is more or less a copy of
* the datamap (perhaps new units without the gaps).
* @return
*/
public abstract List<EffortDataUnit> getAllEffortThings();
/**
* @return the parentDataBlock
*/
public PamDataBlock getParentDataBlock() {
return parentDataBlock;
}
/**
* Get a data selector. For specialist effort modules, this will probably call
* through to the datablocks data selection system. Others, such as binaryEffortProvider
* can return null since they are either on or off.
* @param selectorName
* @return
*/
public abstract DataSelector getDataSelector(String selectorName);
/**
* Get the name of this effort provider.
*/
public abstract String getName();
/**
* Get a symbol manager. For specialist effort modules, this will probably call
* through to the datablocks existing symbol management system. Others, such as binaryEffortProvider
* will need a chooser for the simple on/off data types. .
* @return
*/
public abstract PamSymbolManager getSymbolManager();
public PamSymbolChooser getSymbolChooser(String chooserName, GeneralProjector projector) {
PamSymbolManager symbolManager = getSymbolManager();
if (symbolManager == null) {
return null;
}
return symbolManager.getSymbolChooser(chooserName, projector);
}
public PamSymbol getPamSymbol(String symbolChooserName, PamDataUnit dataUnit, GeneralProjector projector) {
PamSymbolChooser chooser = getSymbolChooser(symbolChooserName, projector);
return getPamSymbol(chooser, dataUnit);
}
/**
* Need to use this to get symbols for effort instead of direct calls into
* the symbol chooser, since the symbol chooser will almost definitely want
* it's own type of data unit, NOT the EffortDataUnit which will probably crash
* due to a cast exception.
* @param chooser
* @param dataUnit
* @return
*/
public PamSymbol getPamSymbol(PamSymbolChooser chooser, PamDataUnit dataUnit) {
if (chooser == null) {
return null;
}
// possible that the data is an Effort unit that wraps a real data unit. Need to
// probably pass the original.
if (dataUnit instanceof EffortDataUnit) {
PamDataUnit refData = ((EffortDataUnit) dataUnit).getReferenceDataUnit();
if (refData != null) {
dataUnit = refData;
}
}
return chooser.getPamSymbol(chooser.getProjector(), dataUnit);
}
public boolean showOptionsDialog(Window parent, String observerName) {
PamSymbolChooser symbolChooser = getSymbolChooser(observerName, null);
if (symbolChooser == null) {
return false;
}
SwingSymbolOptionsPanel panel = symbolChooser.getSwingOptionsPanel(null);
if (panel == null) {
return false;
}
DataSelectDialog dataSelectDialog = new DataSelectDialog(parent, parentDataBlock, null, symbolChooser);
boolean ans = dataSelectDialog.showDialog();
return ans;
}
/**
* @return the isViewer
*/
public boolean isViewer() {
return isViewer;
}
public EffortDataUnit getLastEffort() {
List<EffortDataUnit> all = getAllEffortThings();
if (all == null || all.size() == 0) {
return null;
}
return all.get(all.size()-1);
}
}

View File

@ -0,0 +1,158 @@
package effort.binary;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import PamController.OfflineDataStore;
import PamController.PamController;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector;
import binaryFileStorage.BinaryStore;
import dataMap.OfflineDataMap;
import dataMap.OfflineDataMapPoint;
import effort.EffortDataUnit;
import effort.EffortProvider;
/**
* Effort provider for most types of datablock that bases itself off one of the
* datamaps, binary (preferred) or database. Binary better since database doesn't really
* have proper effort data for most blocks.
* However, we want this to work online too, so will need to have quite different functionality
* for real time and viewer operations.
* @author dg50
*
*/
public class DataMapEffortProvider extends EffortProvider {
private DataMapSymbolManager binarySymbolManager;
private Class<?> dataStoreClass;
private long maxGap = 0;
private ArrayList<EffortDataUnit> allEfforts;
/**
*
* @param parentDataBlock
* @param dataStoreClass
* @param maxGapMillis
*/
public DataMapEffortProvider(PamDataBlock parentDataBlock, Class<?> dataStoreClass, long maxGapMillis) {
super(parentDataBlock);
this.dataStoreClass = dataStoreClass;
this.maxGap = maxGapMillis;
binarySymbolManager = new DataMapSymbolManager(parentDataBlock);
}
/**
*
* @param parentDataBlock
* @param dataStoreClass
*/
public DataMapEffortProvider(PamDataBlock parentDataBlock, Class dataStoreClass) {
this(parentDataBlock, dataStoreClass, 0);
}
@Override
public String getName() {
return getParentDataBlock().getDataName();
}
// @Override
// public EffortDataUnit getEffort(long timeMilliseconds) {
// OfflineDataMap dataMap = findDataMap();
// if (dataMap == null) {
// return null;
// }
// OfflineDataMapPoint foundPt = dataMap.findMapPoint(timeMilliseconds);
// if (foundPt != null) {
// return new DataMapEffortThing(this, getParentDataBlock(), foundPt.getStartTime(), foundPt.getEndTime());
// }
// return null;
// }
@Override
public List<EffortDataUnit> getAllEffortThings() {
return allEfforts;
}
private OfflineDataMap findDataMap() {
if (dataStoreClass == null) {
return getParentDataBlock().getPrimaryDataMap();
}
try {
OfflineDataStore dataStore = (OfflineDataStore) PamController.getInstance().findControlledUnit(dataStoreClass, null);
if (dataStore != null) {
return getParentDataBlock().getOfflineDataMap(dataStore);
}
}
catch (Exception e) {
}
return null;
}
@Override
public DataSelector getDataSelector(String selectorName) {
// TODO Auto-generated method stub
return null;
}
@Override
public PamSymbolManager getSymbolManager() {
return binarySymbolManager;
}
@Override
public void realTimeStart(long timeMilliseconds) {
if (allEfforts == null) {
allEfforts = new ArrayList<>();
}
EffortDataUnit newEffort = new EffortDataUnit(this, null, timeMilliseconds, EffortDataUnit.ONGOINGEFFORT);
allEfforts.add(newEffort);
}
@Override
public void realTimeStop(long timeMilliseconds) {
if (allEfforts == null || allEfforts.size() == 0) {
return;
}
EffortDataUnit lastEff = allEfforts.get(allEfforts.size()-1);
lastEff.setEffortEnd(timeMilliseconds);
}
@Override
public void newData(PamDataUnit pamDataUnit) {
// do nothing for individual data units.
}
@Override
public void viewerLoadData() {
// should merge continuous binary data into one big lump or several big lumps if duty cycled.
OfflineDataMap dataMap = findDataMap();
if (dataMap == null) {
return;
}
ArrayList<EffortDataUnit> allPoints = new ArrayList<>();
Iterator<OfflineDataMapPoint> it = dataMap.getListIterator();
DataMapEffortThing currentThing = null;
while (it.hasNext()) {
OfflineDataMapPoint pt = it.next();
if (currentThing == null || pt.getStartTime() - currentThing.getEffortEnd() > maxGap) {
currentThing = new DataMapEffortThing(this, getParentDataBlock(), pt.getStartTime(), pt.getEndTime());
allPoints.add(currentThing);
}
else {
currentThing.setEffortEnd(pt.getEndTime());
}
}
allEfforts = allPoints;
}
}

View File

@ -0,0 +1,22 @@
package effort.binary;
import PamguardMVC.PamDataBlock;
import effort.EffortDataUnit;
import effort.EffortProvider;
public class DataMapEffortThing extends EffortDataUnit {
private PamDataBlock parentDatablock;
public DataMapEffortThing(EffortProvider effortProvider, PamDataBlock parentDatablock, long effortStart, long effortEnd) {
super(effortProvider, null, effortStart, effortEnd);
this.parentDatablock = parentDatablock;
}
@Override
public String getEffortDescription() {
String str = String.format("%s", parentDatablock.getDataName());
return str;
}
}

View File

@ -0,0 +1,18 @@
package effort.binary;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.SymbolOnlyManager;
import PamguardMVC.PamDataBlock;
public class DataMapSymbolManager extends SymbolOnlyManager {
public static SymbolData defaultSymbol = new SymbolData();
public DataMapSymbolManager(PamDataBlock pamDataBlock) {
super(pamDataBlock, defaultSymbol);
}
}

View File

@ -0,0 +1,28 @@
package effort.swing;
import java.awt.Window;
import java.util.ArrayList;
import PamView.dialog.SourcePanel;
import PamguardMVC.PamDataBlock;
import effort.EffortManager;
public class EffortSourcePanel extends SourcePanel {
public EffortSourcePanel(Window ownerWindow) {
super(ownerWindow, PamDataBlock.class, false, false);
}
public EffortSourcePanel(Window ownerWindow, String borderTitle) {
super(ownerWindow, borderTitle, PamDataBlock.class, false, false);
}
@Override
public ArrayList<PamDataBlock> getCompatibleDataBlocks() {
return EffortManager.getEffortManager().getEffortDataBlocks();
}
}

View File

@ -33,6 +33,11 @@ import pamScrollSystem.PamScroller;
import pamScrollSystem.PamScrollerData;
import userDisplay.UserDisplayControl;
/**
* Record scroll effort.
* @author dg50
*
*/
public class EffortControl extends PamControlledUnit implements PamSettings{
public static String unitType = "Scroll Effort";

View File

@ -32,8 +32,8 @@ public class DBMapMakingDialog extends PamDialog {
JPanel p = new JPanel();
p.setBorder(new TitledBorder("Creating data map"));
p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
p.add(databaseName = new JLabel(""));
p.add(streamName = new JLabel(""));
p.add(databaseName = new JLabel(" "));
p.add(streamName = new JLabel(" "));
p.add(streamProgress = new JProgressBar());
// p.setPreferredSize(new Dimension(400, 200));
streamName.setPreferredSize(new Dimension(250, 5));

View File

@ -402,10 +402,10 @@ public class EmptyTableDefinition implements Cloneable {
protected EmptyTableDefinition clone() {
try {
EmptyTableDefinition clone = (EmptyTableDefinition) super.clone();
clone.pamTableItems = new ArrayList<>();
for (PamTableItem tableItem : this.pamTableItems) {
clone.pamTableItems.add(tableItem.clone());
}
// clone.pamTableItems = new ArrayList<>();
// for (PamTableItem tableItem : this.pamTableItems) {
// clone.pamTableItems.add(tableItem.clone());
// }
return clone;
} catch (CloneNotSupportedException e) {
e.printStackTrace();

View File

@ -144,13 +144,16 @@ public class LookUpTables {
String topic1 = list.get(i).getTopic().trim();
for (int j = i+1; j < n; j++) {
String code2 = list.get(j).getCode().trim();
String topic2 = list.get(j).getTopic().trim();
String topic2 = list.get(j).getTopic();
if (topic2 != null) {
topic2 = topic2.trim();
if (code.equals(code2) && topic1.equals(topic2)) {
isRepeat[j] = true;
nRepeat++;
}
}
}
}
if (nRepeat == 0) {
return;
}
@ -183,7 +186,7 @@ public class LookUpTables {
return null;
}
ArrayList<String> topics = new ArrayList<>();
String qStr = "SELECT DISTINCT Topic FROM " + lutTableDef.getTableName();
String qStr = "SELECT DISTINCT Topic FROM " + lutTableDef.getTableName() + " WHERE TOPIC IS NOT NULL";
try {
Statement stmt = con.getConnection().createStatement();
boolean ok = stmt.execute(qStr);

View File

@ -17,8 +17,8 @@ public class Group3DParams implements Serializable, Cloneable, ManagedParameters
public static final long serialVersionUID = 1L;
@Deprecated
private GroupedSourceParameters groupedSourceParams;
// @Deprecated
// private GroupedSourceParameters groupedSourceParams;
private String sourceName;
@ -146,9 +146,9 @@ public class Group3DParams implements Serializable, Cloneable, ManagedParameters
* @return the sourceName
*/
public String getSourceName() {
if (sourceName == null && groupedSourceParams != null) {
sourceName = groupedSourceParams.getDataSource();
}
// if (sourceName == null && groupedSourceParams != null) {
// sourceName = groupedSourceParams.getDataSource();
// }
return sourceName;
}

View File

@ -56,7 +56,6 @@ import pamScrollSystem.AbstractPamScrollerAWT;
import pamScrollSystem.ScrollPaneAddon;
import PamView.PamTabPanel;
import PamView.panel.PamPanel;
import PamView.symbol.StandardSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamController.PamControlledUnitSettings;
@ -67,7 +66,6 @@ import PamUtils.PamCalendar;
import PamUtils.XMLUtils;
import loggerForms.controlDescriptions.ControlTypes;
import loggerForms.controlDescriptions.InputControlDescription;
import loggerForms.PropertyTypes;
import loggerForms.controlDescriptions.ControlDescription;
import loggerForms.formdesign.FormEditDialog;
import loggerForms.formdesign.FormEditor;
@ -75,6 +73,7 @@ import loggerForms.formdesign.FormList;
import loggerForms.propertyInfos.BEARINGinfo;
import loggerForms.propertyInfos.HEADINGinfo;
import loggerForms.propertyInfos.RANGEinfo;
import loggerForms.symbol.LoggerSymbolManager;
/**
*
* @author Graham Weatherup - SMRU
@ -242,7 +241,7 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
formsDataBlock = new FormsDataBlock(this, getFormName(), formsControl.getFormsProcess(), 0);
formsDataBlock.SetLogging(new FormsLogging(this,formsDataBlock));
formsDataBlock.setOverlayDraw(new LoggerFormGraphics(formsControl, this));
formsDataBlock.setPamSymbolManager(new StandardSymbolManager(formsDataBlock, LoggerFormGraphics.defaultSymbol, false));
formsDataBlock.setPamSymbolManager(new LoggerSymbolManager(formsDataBlock));
setTimeOfNextSave();
@ -1068,7 +1067,7 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
normalForm = createForm();
formComponent = normalForm.getComponent();
}
formsDataDisplayTable = new FormsDataDisplayTable(this);
formsDataDisplayTable = new FormsDataDisplayTable(formsControl, this);
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, formComponent, formsDataDisplayTable.getMainPanel());
if (formSettingsControl.getFormSettings().splitPanelPosition != null) {
@ -1122,7 +1121,8 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
}
public LoggerForm createForm() {
return new LoggerForm(this,LoggerForm.NewDataForm);
boolean viewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
return new LoggerForm(this, viewer ? LoggerForm.NewDataForm : LoggerForm.NewDataForm);
}
@ -1230,6 +1230,22 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
removeForm(parentFrame);
}
}
/**
* Delete a data unit from memory and from database.
* @param dataUnit
* @return
*/
public boolean deleteDataUnit(FormsDataUnit dataUnit) {
if (dataUnit == null) {
return false;
}
boolean ans = getFormsDataBlock().remove(dataUnit, true);
if (formsDataDisplayTable != null) {
formsDataDisplayTable.dataChanged();
}
return ans;
}
/**
* Create a new subtab form on the appropriate sub tab panel.
*/
@ -1647,6 +1663,15 @@ public class FormDescription implements Cloneable, Comparable<FormDescription> {
}
}
public void optionsChange() {
if (normalForm != null) {
normalForm.optionsChange();
}
if (formsDataDisplayTable != null) {
formsDataDisplayTable.optionsChange();
}
}
/**
* Get a count of open sub tab forms.
* @return the number of open sub tab forms.

View File

@ -16,6 +16,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.logging.LogManager;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
@ -34,6 +35,7 @@ import loggerForms.FormDescription.FormPlotOptionsStore;
import loggerForms.monitor.FormsMonitorMaster;
import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings;
import PamController.PamController;
import PamController.PamControllerInterface;
import PamController.PamSettingManager;
import PamController.PamSettings;
@ -48,13 +50,11 @@ import PamView.PamTabPanel;
import PamView.PamView;
import PamguardMVC.PamDataBlock;
/**
*
* @author Graham Weatherup
* controls the logger forms module
* @author Graham Weatherup controls the logger forms module
*/
public class FormsControl extends PamControlledUnit {
public class FormsControl extends PamControlledUnit implements PamSettings {
public static ArrayList<String> restrictedTitles = new ArrayList<String>();
@ -71,6 +71,8 @@ public class FormsControl extends PamControlledUnit {
private FormsMonitorMaster formsMonitor;
private FormsParameters formsParameters = new FormsParameters();
// /** A set of dummy parameters, used solely to pull together different settings for XML export */
// private FormsTempParams dummyParams;
@ -83,8 +85,7 @@ public class FormsControl extends PamControlledUnit {
formsTabPanel = new FormsTabPanel(this);
formsAlertSidePanel = new FormsAlertSidePanel(this);
formsMonitor = new FormsMonitorMaster(this, formsProcess);
// dummyParams = new FormsTempParams();
// PamSettingManager.getInstance().registerSettings(this);
PamSettingManager.getInstance().registerSettings(this);
}
@ -108,8 +109,7 @@ public class FormsControl extends PamControlledUnit {
String keywordString = null;
try {
keywordString = DBControlUnit.findDatabaseControl().getDatabaseSystem().getKeywords();
}
catch (NullPointerException e) {
} catch (NullPointerException e) {
return false;
}
@ -117,7 +117,7 @@ public class FormsControl extends PamControlledUnit {
if (keywordString != null) {
keywords = keywordString.split(",");
for (String k:keywords){
for (String k : keywords) {
restrictedTitles.add(k);
}
}
@ -131,7 +131,7 @@ public class FormsControl extends PamControlledUnit {
keywords = keywordString.split(",");
for (String k:keywords){
for (String k : keywords) {
restrictedTitles.add(k);
}
// System.out.println(keywordString);
@ -141,20 +141,21 @@ public class FormsControl extends PamControlledUnit {
} catch (SQLException e) {
e.printStackTrace();
return false;
}
catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#notifyModelChanged(int)
*/
@Override
public void notifyModelChanged(int changeType) {
switch(changeType) {
switch (changeType) {
case PamControllerInterface.INITIALIZATION_COMPLETE:
generateForms();
break;
@ -173,6 +174,7 @@ public class FormsControl extends PamControlledUnit {
/**
* Get the form description for a specific index.
*
* @param iForm form index
* @return for description
*/
@ -182,6 +184,7 @@ public class FormsControl extends PamControlledUnit {
/**
* Get a form index from a form description
*
* @param formDescription Form Descriptions
* @return form index or -1 if not found
*/
@ -191,11 +194,12 @@ public class FormsControl extends PamControlledUnit {
/**
* Find a form which has a particular order value.
*
* @param order order (starts from 1 generally)
* @return a form, or null if none have that order.
*/
public FormDescription findFormByOrder(int order) {
for (FormDescription aForm:formDescriptions) {
for (FormDescription aForm : formDescriptions) {
PropertyDescription formProperty = aForm.findProperty(PropertyTypes.ORDER);
if (formProperty == null) {
continue;
@ -210,6 +214,7 @@ public class FormsControl extends PamControlledUnit {
/**
* Find a form description with a given name.
*
* @param formName
* @return form description or null.
*/
@ -217,7 +222,7 @@ public class FormsControl extends PamControlledUnit {
if (formName == null) {
return null;
}
for (FormDescription ad:formDescriptions) {
for (FormDescription ad : formDescriptions) {
if (ad.getFormName().equals(formName)) {
return ad;
}
@ -228,16 +233,16 @@ public class FormsControl extends PamControlledUnit {
return null;
}
public Character getOutputTableNameCounterSuffix(FormDescription thisFormDescription){
public Character getOutputTableNameCounterSuffix(FormDescription thisFormDescription) {
String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String thisTableName = thisFormDescription.getDBTABLENAME();
int count=0;
int count = 0;
int position = 0;
for (FormDescription formDescription : formDescriptions){
if ((formDescription.getDBTABLENAME()==thisFormDescription.getDBTABLENAME())){
position=count;
for (FormDescription formDescription : formDescriptions) {
if ((formDescription.getDBTABLENAME() == thisFormDescription.getDBTABLENAME())) {
position = count;
break;
}
@ -258,10 +263,9 @@ public class FormsControl extends PamControlledUnit {
return letters.charAt(position);
}
/**
* Generates a list of tables beginning with UDF_ and reads
* their contents into a FormDescription
* Generates a list of tables beginning with UDF_ and reads their contents into
* a FormDescription
*/
public void readUDFTables() {
/*
@ -289,31 +293,27 @@ public class FormsControl extends PamControlledUnit {
try {
DatabaseMetaData dbmd = dbCon.getConnection().getMetaData();
String[] types = {"TABLE"};
ResultSet resultSet = dbmd.getTables(null, null, "%", types);//not getting all tables from db in ODB
String[] types = { "TABLE" };
ResultSet resultSet = dbmd.getTables(null, null, "%", types);// not getting all tables from db in ODB
//Loop through database tables
while (resultSet.next()){
// Loop through database tables
while (resultSet.next()) {
String tableName = resultSet.getString(3);
// System.out.println("LogFor: "+tableName);
//If starts with 'UDF_' create form description from it.
if( tableName.toUpperCase().startsWith("UDF_")){
// If starts with 'UDF_' create form description from it.
if (tableName.toUpperCase().startsWith("UDF_")) {
udfTableNameList.add(tableName);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
if (UDFErrors.size()>0){
if (UDFErrors.size() > 0) {
}
for (String tableName:udfTableNameList){
for (String tableName : udfTableNameList) {
FormDescription formDescription = new FormDescription(this, tableName);
formDescriptions.add(formDescription);
}
@ -324,7 +324,7 @@ public class FormsControl extends PamControlledUnit {
// finally create the datablocks.
// at the same time, can reset the order properties to a simple sequence.
int iForm = 0;
for (FormDescription aFD:formDescriptions) {
for (FormDescription aFD : formDescriptions) {
formsProcess.addOutputDataBlock(aFD.getFormsDataBlock());
aFD.setFormOrderProperty(++iForm);
/*
@ -339,20 +339,23 @@ public class FormsControl extends PamControlledUnit {
}
}
public void addFormDescription(String newFormName){
public void addFormDescription(String newFormName) {
FormDescription formDescription = new FormDescription(this, newFormName);
formsProcess.addOutputDataBlock(formDescription.getFormsDataBlock());
}
/**
* Get the correct type of reference to the forms tab panel.
*
* @return reference to the forms tab panel.
*/
public FormsTabPanel getFormsTabPanel() {
return formsTabPanel;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#getTabPanel()
*/
@Override
@ -372,8 +375,6 @@ public class FormsControl extends PamControlledUnit {
}
/**
* @return the formsProcess
*/
@ -381,7 +382,9 @@ public class FormsControl extends PamControlledUnit {
return formsProcess;
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#createDetectionMenu(java.awt.Frame)
*/
@Override
@ -402,8 +405,19 @@ public class FormsControl extends PamControlledUnit {
// }
detMenu.add(menuItem = new JMenuItem("Regenerate all forms"));
menuItem.addActionListener(new ReGenerateForms(parentFrame));
if (PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW) {
JCheckBoxMenuItem changebox = new JCheckBoxMenuItem("Allow Viewer changes");
changebox.setToolTipText("Allow the editing, adding, and deleting of data in Viewer mode");
changebox.setSelected(formsParameters.allowViewerChanges);
changebox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
formsParameters.allowViewerChanges = changebox.isSelected();
notifyOptionsChange();
}
});
detMenu.add(changebox);
}
return detMenu;
}
@ -419,9 +433,16 @@ public class FormsControl extends PamControlledUnit {
@Override
public void actionPerformed(ActionEvent arg0) {
newLoggerform(parentFrame);
}
}
private void notifyOptionsChange() {
if (formDescriptions == null) {
return;
}
for (FormDescription formDesc: formDescriptions) {
formDesc.optionsChange();
}
}
class ReGenerateForms implements ActionListener {
@ -443,11 +464,13 @@ public class FormsControl extends PamControlledUnit {
class EditForm implements ActionListener {
private FormDescription formDescription;
private Frame parentFrame;
public EditForm(Frame parentFrame, FormDescription formDescription) {
super();
this.parentFrame = parentFrame;
this.formDescription = formDescription;
}
@Override
public void actionPerformed(ActionEvent arg0) {
this.formDescription.editForm(parentFrame);
@ -456,11 +479,13 @@ public class FormsControl extends PamControlledUnit {
/**
* Create a new logger form
*
* @param parentFrame parent frame
* @return selected name for new form, or null if nothing created.
*/
public String newLoggerform(Frame parentFrame) {
String newName = JOptionPane.showInputDialog(parentFrame, "Enter the name for the new user form", "New Logger Form", JOptionPane.OK_CANCEL_OPTION);
String newName = JOptionPane.showInputDialog(parentFrame, "Enter the name for the new user form",
"New Logger Form", JOptionPane.OK_CANCEL_OPTION);
if (newName == null) {
return null;
}
@ -473,7 +498,7 @@ public class FormsControl extends PamControlledUnit {
message += "\nNote that youwill have to exit PAMGUARD and enter form control data by hand into this table.";
message += "\nFuture releases will (hopefully) contain a more friendly programmable interface";
int ans = JOptionPane.showConfirmDialog(parentFrame, message, "Create Form", JOptionPane.OK_CANCEL_OPTION);
if(ans == JOptionPane.CANCEL_OPTION) {
if (ans == JOptionPane.CANCEL_OPTION) {
return null;
}
UDFTableDefinition tableDef = new UDFTableDefinition(newName);
@ -485,7 +510,6 @@ public class FormsControl extends PamControlledUnit {
return newName;
}
/**
* Generate all forms and associated processes, notifying databases, maps, etc
* so that any required actions can be taken.
@ -525,12 +549,13 @@ public class FormsControl extends PamControlledUnit {
/**
* Delete and recreate all forms / form data, etc.
*
* @param parentFrame
*/
public void regenerateForms(Window parentFrame) {
formsTabPanel.removeAllForms();
for (FormDescription formDescription:formDescriptions) {
for (FormDescription formDescription : formDescriptions) {
formDescription.destroyForms();
}
formDescriptions.clear();
@ -565,14 +590,16 @@ public class FormsControl extends PamControlledUnit {
boolean ans = FormsPlotOptionsDialog.showDialog(parentFrame, this);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
*
* @see PamController.PamControlledUnit#canClose()
*/
@Override
public boolean canClose() {
// return false if any forms have open sub forms.
int subFormCount = 0;
for (FormDescription fd:formDescriptions) {
for (FormDescription fd : formDescriptions) {
subFormCount += fd.getSubformCount();
}
if (subFormCount == 0) {
@ -587,7 +614,7 @@ public class FormsControl extends PamControlledUnit {
* Rewrite all UDF tables in forms which have been altered.
*/
public void rewriteChangedUDFTables() {
for (FormDescription aForm:formDescriptions) {
for (FormDescription aForm : formDescriptions) {
if (aForm.isNeedsUDFSave()) {
aForm.writeUDFTable(null);
aForm.setNeedsUDFSave(false);
@ -614,10 +641,10 @@ public class FormsControl extends PamControlledUnit {
return new ModuleStatus(ModuleStatus.STATUS_OK);
}
/**
* Some things that are meant to be boolean are coming out as int or string so
* need to do some type checking.
*
* @param value
* @return
*/
@ -640,45 +667,28 @@ public class FormsControl extends PamControlledUnit {
return null;
}
// @Override
// public Serializable getSettingsReference() {
// return (Serializable) dummyParams;
// }
//
// @Override
// public long getSettingsVersion() {
// return 0;
// }
//
// @Override
// public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
// return false;
// }
//
// /**
// * Private class to pass along various parameter classes that Logger forms use
// *
// * @author mo55
// *
// */
// private class FormsTempParams implements ManagedParameters {
//
// @Override
// public PamParameterSet getParameterSet() {
// PamParameterSet ps = new PamParameterSet(this);
// try {
// Field field = FormsControl.this.getClass().getDeclaredField("formDescriptions");
// ps.put(new PrivatePamParameterData(this, field) {
// @Override
// public Object getData() throws IllegalArgumentException, IllegalAccessException {
// return formDescriptions;
// }
// });
// } catch (NoSuchFieldException | SecurityException e) {
// e.printStackTrace();
// }
// return ps;
// }
// }
@Override
public Serializable getSettingsReference() {
return formsParameters;
}
@Override
public long getSettingsVersion() {
return FormsParameters.serialVersionUID;
}
@Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
this.formsParameters = (FormsParameters) pamControlledUnitSettings.getSettings();
return true;
}
/**
* @return the formsParameters
*/
public FormsParameters getFormsParameters() {
return formsParameters;
}
}

View File

@ -7,6 +7,8 @@ import PamguardMVC.PamProcess;
import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.dataSelector.DataSelectorCreator;
import loggerForms.dataselect.FormDataSelCreator;
import loggerForms.effort.FormsEffortUnit;
import loggerForms.effort.LoggerEffortProvider;
import loggerForms.monitor.FormsDataSelectorCreator;
/**
*
@ -17,6 +19,8 @@ public class FormsDataBlock extends PamDataBlock<FormsDataUnit> {
private FormDescription formDescription;
private LoggerEffortProvider loggerEffortProvider;
public FormsDataBlock(FormDescription formDescription, String dataName,
PamProcess parentProcess, int channelMap) {
super(FormsDataUnit.class, dataName, parentProcess, channelMap);
@ -25,6 +29,7 @@ public class FormsDataBlock extends PamDataBlock<FormsDataUnit> {
setDataSelectCreator(new FormDataSelCreator(this, formDescription));
// setBinaryDataSource(new FormsBinaryIO(formDescription.getFormsControl(), this));
// setNaturalLifetimeMillis(60000);
setEffortProvider(loggerEffortProvider = new LoggerEffortProvider(this));
}
public FormDescription getFormDescription() {

View File

@ -4,10 +4,15 @@
package loggerForms;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
@ -20,6 +25,7 @@ import PamController.PamController;
import PamUtils.PamCalendar;
import PamView.PamTable;
import PamView.dialog.PamDialog;
import PamView.dialog.warn.WarnOnce;
import PamguardMVC.PamDataBlock;
/**
@ -37,11 +43,13 @@ public class FormsDataDisplayTable {
private JScrollPane scrollPane;
private FormsControl formsControl;
/**
* @param formDescription
*/
public FormsDataDisplayTable(FormDescription formDescription) {
// TODO Auto-generated constructor stub
public FormsDataDisplayTable(FormsControl formsControl, FormDescription formDescription) {
this.formsControl = formsControl;
this.formDescription=formDescription;
// GridLayout(rows,columns)
@ -63,36 +71,16 @@ public class FormsDataDisplayTable {
formsTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
// for now, don't allow edits in viewer mode.
if (PamController.getInstance().getRunMode() != PamController.RUN_PAMVIEW) {
// if (PamController.getInstance().getRunMode() != PamController.RUN_PAMVIEW) {
formsTable.addMouseListener(new EditDataListener());
}
// }
scrollPane = new JScrollPane(formsTable);
mainPanel.add(scrollPane);
// mainPanel.setPreferredSize(new Dimension(800, 200));
}
// class TimerListener implements ActionListener {
// boolean doneLayout;
// public void actionPerformed(ActionEvent ev) {
// // table.
//// nmeaTableData.fireTableRowsUpdated(0, 10);
// formsTableDataModel.fireTableDataChanged();
//
// if (doneLayout == false && formsTableDataModel.getRowCount() > 0) {
// doneLayout = true;
// }
// }
// }
class TableListListener implements ListSelectionListener {
@Override
@ -108,9 +96,15 @@ public class FormsDataDisplayTable {
formDescription.viewDataUnit(formsDataUnit);
}
}
}
private boolean canEdit() {
if (PamController.getInstance().getRunMode() != PamController.RUN_PAMVIEW) {
return true;
}
if (formsControl == null) return false;
return formsControl.getFormsParameters().allowViewerChanges;
}
/**
* Find the data unit for a particular row in the table.
* @param iRow
@ -125,9 +119,11 @@ public class FormsDataDisplayTable {
class EditDataListener extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
if (canEdit() == false) {
return;
}
if (e.getClickCount() == 2) {
// FormsDataBlock formsDataBlock = formDescription.getFormsDataBlock();
int row = formsTable.getSelectedRow();
FormsDataUnit formsDataUnit = findDataUnitForRow(row);
@ -135,14 +131,32 @@ public class FormsDataDisplayTable {
PamDialog.showWarning(null, "WARNING", "could not find formsDataUnit");
return;
}
FormsDataUnitEditor due = new FormsDataUnitEditor(formDescription,formsDataUnit);
editDataUnit(formsDataUnit);
}
}
@Override
public void mousePressed(MouseEvent e) {
maybePopup(e);
}
@Override
public void mouseReleased(MouseEvent e) {
maybePopup(e);
}
private void maybePopup(MouseEvent e) {
if (e.isPopupTrigger() == false) {
return;
}
if (canEdit() == false) {
return;
}
int row = formsTable.getSelectedRow();
showPopupMenu(e.getPoint());
}
}
@ -259,8 +273,68 @@ public class FormsDataDisplayTable {
return mainPanel;
}
public void showPopupMenu(Point pt) {
FormsDataUnit dataUnit = findDataUnitForRow(formsTable.getSelectedRow());
JPopupMenu menu = new JPopupMenu();
JMenuItem menuItem;
if (dataUnit != null) {
menuItem = new JMenuItem("Edit row ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
editDataUnit(dataUnit);
}
});
menu.add(menuItem);
}
menuItem = new JMenuItem("Create row ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addDataUnit();
}
});
menu.add(menuItem);
if (dataUnit != null) {
menu.addSeparator();
menuItem = new JMenuItem("Delete row ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deleteDataUnit(dataUnit);
}
});
menu.add(menuItem);
}
menu.show(formsTable, pt.x, pt.y);
}
private boolean editDataUnit(FormsDataUnit dataUnit) {
FormsDataUnitEditor due = new FormsDataUnitEditor(formDescription, dataUnit);
return true;
}
private boolean deleteDataUnit(FormsDataUnit dataUnit) {
if (dataUnit == null) {
return false;
}
int ans = WarnOnce.showWarning("Delete logger form data", "Are you sure you want to delete data Id " + dataUnit.getDatabaseIndex(), WarnOnce.OK_CANCEL_OPTION);
if (ans != WarnOnce.OK_OPTION) {
return false;
}
formDescription.deleteDataUnit(dataUnit);
return true;
}
private boolean addDataUnit() {
formDescription.viewDataUnit(null);
return false;
}
/**
* Called when data have changed in the datablock.
@ -276,4 +350,12 @@ public class FormsDataDisplayTable {
public JScrollPane getScrollPane() {
return scrollPane;
}
/**
* Some optins have changed.
*/
public void optionsChange() {
// TODO Auto-generated method stub
}
}

View File

@ -2,7 +2,10 @@ package loggerForms;
import GPS.GpsData;
import PamUtils.PamCalendar;
import PamView.GeneralProjector;
import PamguardMVC.PamDataUnit;
import generalDatabase.SQLTypes;
import loggerForms.controlDescriptions.ControlDescription;
/**
*
* @author Graham Weatherup
@ -12,9 +15,6 @@ import PamguardMVC.PamDataUnit;
* UTCmillisecond
* PCLocalTime
*
*
*
*
*/
public class FormsDataUnit extends PamDataUnit {
@ -94,6 +94,82 @@ public class FormsDataUnit extends PamDataUnit {
return formOriginLatLong;
}
@Override
public long getTimeMilliseconds() {
Long time = findTimeValue(PropertyTypes.STARTTIME);
if (time != null) {
return time;
}
return super.getTimeMilliseconds();
}
/**
* Find one of the time property controls and get its value.
* @param timeProperty
* @return
*/
public Long findTimeValue(PropertyTypes timeProperty) {
if (formData == null) {
return null;
}
PropertyDescription prop = formDescription.findProperty(timeProperty);
if (prop == null) {
return null;
}
String ctrlTitle = prop.getItemInformation().getStringProperty("Title");
if (ctrlTitle == null) {
return null;
}
int timeControlIndex = formDescription.findInputControlByName(ctrlTitle);
if (timeControlIndex < 0 || timeControlIndex >= formData.length) {
return null;
}
Object timeObj = formData[timeControlIndex];
/*
* this should have found the time contol in the form of a string from the database.
* try to unpack it.
*/
Long timeMillis = SQLTypes.millisFromTimeStamp(timeObj);
return timeMillis;
}
/**
* find a correctly set property value for the end time (if set).
* @return
*/
public Long getSetEndTime() {
return findTimeValue(PropertyTypes.ENDTIME);
}
@Override
public long getEndTimeInMilliseconds() {
Long time = findTimeValue(PropertyTypes.ENDTIME);
if (time != null) {
return time;
}
return super.getEndTimeInMilliseconds();
}
@Override
public String getSummaryString() {
String str = String.format("<html><b>%s</b>", formDescription.getFormNiceName());
Object[] data = getFormData();
int iDat = 0;
for (ControlDescription cd:formDescription.getInputControlDescriptions()) {
if (data[iDat] == null) {
str += String.format("<p>%s: -", cd.getTitle());
}
else {
str += String.format("<p>%s: %s", cd.getTitle(), data[iDat].toString());
}
iDat++;
}
str += "</html>";
return str;
}
}

View File

@ -16,8 +16,6 @@ import PamUtils.PamCalendar;
public class FormsDataUnitEditor{
/**
* @param formDescription
* @param formsDataUnit
@ -29,8 +27,6 @@ public class FormsDataUnitEditor{
JFrame frame=PamController.getInstance().getGuiFrameManager().getFrame(frameNo);
FormsDataUnit updatedData = FormsDataUnitEditDialog.showDialog(frame, formDescription, formsDataUnit);
if (updatedData != null) {

View File

@ -2,16 +2,20 @@ package loggerForms;
import java.util.ArrayList;
import PamController.PamViewParameters;
import loggerForms.controlDescriptions.ControlDescription;
import loggerForms.controlDescriptions.InputControlDescription;
import pamScrollSystem.ViewLoadObserver;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import generalDatabase.PamConnection;
import generalDatabase.PamTableDefinition;
import generalDatabase.SQLLogging;
import generalDatabase.SQLTypes;
public class FormsLogging extends SQLLogging {
FormDescription formDescription;
private FormDescription formDescription;
protected FormsLogging(FormDescription formDescription, PamDataBlock pamDataBlock) {
super(pamDataBlock);
@ -20,53 +24,34 @@ public class FormsLogging extends SQLLogging {
setTableDefinition(formDescription.getOutputTableDef());
}
// @Override
// public void setTableData(PamDataUnit pamDataUnit) {
//
// FormsDataUnit formDataUnit = (FormsDataUnit) pamDataUnit;
// int dataLen = formDataUnit.getFormData().length;
// int tableLen= getTableDefinition().getTableItemCount();
//
//// for (int j=0;j<tableLen;j++){
//// System.out.println(getTableDefinition().getTableItem(j).getName());
//// }
//
// int diff = tableLen-dataLen;
// // put number of standard items as static is pamtable item/table(ie diff ~3-5)
//
//// System.out.printf("Save Forms Data "+PamCalendar.formatDateTime(formDataUnit.getTimeMilliseconds())+"\n");
//
// for (int i=0;i<dataLen;i++){
//// System.out.printf("INTS.. %d dataLen:%d, tableLen:%d, diff:%d \n",i,dataLen,tableLen,diff);
//// if ((formDataUnit.getFormData()[i]==null)){
//// System.out.println("Object "+i+" to save: ~null");
//// getTableDefinition().getTableItem(i+diff).setValue(null); //be null;
//// }else{
//// System.out.println("Object "+i+" to save: "+formDataUnit.getFormData()[i].toString());
//// System.out.println("Name: "+getTableDefinition().getTableItem(i+diff).getName());
//// System.out.println("Data: "+formDataUnit.getFormData()[i]);
// getTableDefinition().getTableItem(i+diff).setValue(formDataUnit.getFormData()[i]);//object
//
//// }
//
// }
//
// }
@Override
public String getViewerLoadClause(SQLTypes sqlTypes, PamViewParameters pvp) {
// modified clause in case the form defines a start time element in which
// case we need an OR of that and UTC.
String standardClause = super.getViewerLoadClause(sqlTypes, pvp);
PropertyDescription startProp = formDescription.findProperty(PropertyTypes.STARTTIME);
if (startProp == null) {
return standardClause;
}
String startName = startProp.getDbTitle();
if (startName == null) {
return standardClause;
}
startName = PamTableDefinition.deblankString(startName); // replace blanks with underscores.
startName = sqlTypes.formatColumnName(startName); // wrap as standard for this database taype.
String t1 = sqlTypes.formatDBDateTimeQueryString(pvp.viewStartTime);
String t2 = sqlTypes.formatDBDateTimeQueryString(pvp.viewEndTime);
String newClause = String.format(" WHERE (UTC BETWEEN %s AND %s) OR (%s BETWEEN %s AND %s) ORDER BY %s, UTC, UTCMilliseconds",
t1, t2, startName, t1, t2, startName);
return newClause;
}
@Override
public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) {
FormsDataUnit formDataUnit = (FormsDataUnit) pamDataUnit;
Object[] datas = formDataUnit.getFormData();
// for(LoggerControl lc:formDataUnit.getLoggerForm().getInputControls()){
//
// lc.moveDataToTableItems();
//// for (FormsTableItem fti:lc.getControlDescription().getFormsTableItems()){
////
//// getTableDefinition().getTableItem(fti).setValue(lc.getData());
////
//// }
// }
ArrayList<InputControlDescription> inputCtrls = formDescription.getInputControlDescriptions();
InputControlDescription cd;
@ -76,9 +61,6 @@ public class FormsLogging extends SQLLogging {
}
// for (ControlDescription controlDescription:formDescription.getInputControlDescriptions()){
// controlDescription.moveDataTo
// }
}
/* (non-Javadoc)
@ -98,21 +80,6 @@ public class FormsLogging extends SQLLogging {
}
}
//
// int dataLen = formDescription.getInputControlDescriptions().size();
// int tableLen= getTableDefinition().getTableItemCount();
// int diff = tableLen-dataLen;
// Object[] formData = new Object[dataLen];
// int tableIndex;
// for (int j=0;j<dataLen;j++){
// tableIndex = j+diff;
// formData[j] = getTableDefinition().getTableItem(j+diff).getValue();
// if (formData[j] != null && formData[j].getClass() == String.class) {
// formData[j] = ((String) formData[j]).trim();
// }
// }
// formDescription.getf
FormsDataUnit formsDataUnit = new FormsDataUnit(null, timeMilliseconds, formDescription, formData);
formsDataUnit.setDatabaseIndex(databaseIndex);
@ -120,16 +87,17 @@ public class FormsLogging extends SQLLogging {
return formsDataUnit;
}
// LoggerForm.
// return new FormsDataUnit(null, timeMilliseconds, formDescription, formData);
@Override
public boolean loadViewData(PamConnection con, PamViewParameters pamViewParameters, ViewLoadObserver loadObserver) {
boolean ans = super.loadViewData(con, pamViewParameters, loadObserver);
if (ans) {
getPamDataBlock().sortData();
}
return ans;
}
}

View File

@ -0,0 +1,26 @@
package loggerForms;
import java.io.Serializable;
/**
* Some general parameters for PAMGuard Viewer mode
* @author dg50
*
*/
public class FormsParameters implements Serializable, Cloneable{
public static final long serialVersionUID = 1L;
public boolean allowViewerChanges = false;
@Override
protected FormsParameters clone() {
try {
return (FormsParameters) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -10,6 +10,7 @@ import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -50,6 +51,7 @@ import PamView.PamColors;
import PamView.dialog.PamButton;
import PamView.dialog.PamDialog;
import PamView.dialog.PamLabel;
import PamView.dialog.warn.WarnOnce;
import PamView.panel.PamPanel;
import PamView.panel.VerticalLayout;
import PamguardMVC.PamDataBlock;
@ -136,6 +138,7 @@ public class LoggerForm{
public static final int PreviewDataForm = 2;
private int NewOrEdit;
private LoggerFormPanel lastRow;
private FormsDataUnit restoredDataUnit;
//// /**
//// * used to hold reference to dataUnit being edited in "edit" mode
@ -605,21 +608,35 @@ public class LoggerForm{
* Enable / disable buttons
* <p> for now this is basically just disabling buttons if
* we're in viewer mode. A More sophisticated function
* might consider enabling / diabling depending on whether
* might consider enabling / disabling depending on whether
* or not a form can be saved.
*/
public void enableControls() {
boolean isViewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
if (saveButton != null) saveButton.setEnabled(!isViewer);
if (clearButton != null) clearButton.setEnabled(!isViewer);
if (cancelButton != null) cancelButton.setEnabled(!isViewer);
boolean viewerEds = false;
if (formDescription != null) {
FormsControl formsControl = formDescription.getFormsControl();
viewerEds = formsControl.getFormsParameters().allowViewerChanges;
}
if (saveButton != null) {
saveButton.setEnabled(!isViewer || viewerEds);
if (isViewer) {
saveButton.setText(restoredDataUnit == null ? "Save" : "Update...");
}
}
if (clearButton != null) {
clearButton.setEnabled(!isViewer);
}
if (cancelButton != null) {
cancelButton.setEnabled(!isViewer);
}
}
class SaveButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Save")) {
// if (e.getActionCommand().equals("Save")) {
String er = getFormErrors();
getFormWarnings();
@ -628,7 +645,7 @@ public class LoggerForm{
if (er==null){
save();
}
}
// }
}
}
@ -636,17 +653,16 @@ public class LoggerForm{
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Save")) {
// if (e.getActionCommand().equals("Save")) {
String er = getFormErrors();
getFormWarnings();
if (er==null){
save();
formDescription.removeSubtabform(loggerForm);
}
}
// }
}
}
@ -737,10 +753,17 @@ public class LoggerForm{
* @param formsDataUnit
*/
void restoreData(FormsDataUnit formsDataUnit){
restoredDataUnit = formsDataUnit;
if (formsDataUnit != null) {
// this.formsDataUnit = formsDataUnit;
Object[] formData = formsDataUnit.getFormData();
transferDataArrayToForm(formData);
}
else {
clear();
}
enableControls();
}
/**
* Transfers data from the from controls to the data array which will
@ -840,14 +863,40 @@ public class LoggerForm{
* Extract and save teh data inot a new PAmDAtaUnit.
*/
private void save() {
//create form data object v
//create form data object
Object[] formData = extractFormData();
if (NewOrEdit==NewDataForm){
boolean isViewer = PamController.getInstance().getRunMode() == PamController.RUN_PAMVIEW;
boolean isNew = true;
if (isViewer && restoredDataUnit != null) {
isNew = false;
}
if (isNew){
FormsDataUnit formDataUnit = new FormsDataUnit(loggerForm,PamCalendar.getTimeInMillis(), formDescription, formData);
// dU.setParentDataBlock(formDescription.getFormsDataBlock());
// System.out.println(formDescription.getXMLData(formDataUnit));
formDescription.getFormsDataBlock().addPamData(formDataUnit);
// in viewer mode, will need to do something to get this to save.
if (isViewer) {
formDescription.getFormsDataBlock().getLogging().logData(DBControlUnit.findConnection(), formDataUnit);
formDescription.getFormsDataBlock().sortData();
}
}
else {
// update the data form. Ask first.
Frame win = formDescription.getFormsControl().getGuiFrame();
String msg = "Do you want to update this form with new data ?";
int ans = WarnOnce.showWarning(win, "Logger forms: " + formDescription.getFormName(), msg, WarnOnce.OK_CANCEL_OPTION);
if (ans == WarnOnce.OK_OPTION) {
if (restoredDataUnit == null) {
WarnOnce.showWarning(win, "Logger forms: " + formDescription.getFormName(), "No data to update", WarnOnce.WARNING_MESSAGE);
}
else {
restoredDataUnit.setFormsData(loggerForm, formData);
// should update database on next SaveData, but not before.
formDescription.getFormsDataBlock().updatePamData(restoredDataUnit, PamCalendar.getTimeInMillis());
formDescription.getFormsDataBlock().sortData();
}
}
}
// else if(NewOrEdit==EditDataForm && formsDataUnit != null){
// formsDataUnit.setFormsData(formData);
@ -914,6 +963,9 @@ public class LoggerForm{
public JButton getSaveButton() {
return saveButton;
}
public void optionsChange() {
enableControls();
}
// public GpsData getOriginLatLong(FormsDataUnit formsDataUnit) {
// GpsData gps = getOrigin(GPSOriginSystem.class, formsDataUnit);

View File

@ -32,6 +32,7 @@ import PamView.PamSymbolType;
import PamView.PanelOverlayDraw;
import PamView.GeneralProjector.ParameterType;
import PamView.GeneralProjector.ParameterUnits;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataUnit;
@ -189,7 +190,7 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
double shipCourse = plotOrigin.getCourseOverGround();
double shipHead = plotOrigin.getHeading();
PamSymbol plotSymbol = getPlotSymbol(formDataUnit);
PamSymbol plotSymbol = getPlotSymbol(generalProjector, formDataUnit);
Coordinate3d detOrigin = generalProjector.getCoord3d(plotOrigin.getLatitude(), plotOrigin.getLongitude(), plotOrigin.getHeight());
// see if there is range heading and bearing data.
@ -248,7 +249,7 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
int nControls = data.length;
ControlDescription controlDescription;
ArrayList<InputControlDescription> controlDescriptions = formDescription.getInputControlDescriptions();
PamSymbol plotSymbol = getPlotSymbol(dataUnit);
PamSymbol plotSymbol = getPlotSymbol(generalProjector, dataUnit);
if (plotSymbol == null) {
return null;
}
@ -354,7 +355,22 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
* @param pamDataUnit data unit to plot
* @return symbol.
*/
private PamSymbol getPlotSymbol(FormsDataUnit dataUnit) {
private PamSymbol getPlotSymbol(GeneralProjector projector, FormsDataUnit dataUnit) {
/**
* Try to use the new selector system. If it's not there, then revert to
* the older system.
*/
PamSymbolChooser chooser = null;
if (projector != null) {
chooser = projector.getPamSymbolChooser();
}
if (chooser != null) {
PamSymbol chosenSymbol = chooser.getPamSymbol(projector, dataUnit);
if (chosenSymbol != null) {
return chosenSymbol;
}
}
/**
* first go through all the controls and see which is
* the first one that's initiated plotting. If it's
@ -409,22 +425,7 @@ public class LoggerFormGraphics extends PanelOverlayDraw {
@Override
public String getHoverText(GeneralProjector generalProjector,
PamDataUnit dataUnit, int iSide) {
FormsDataUnit formsDU = (FormsDataUnit) dataUnit;
String str = String.format("<html><b>%s</b>", formDescription.getFormNiceName());
Object[] data = formsDU.getFormData();
int iDat = 0;
for (ControlDescription cd:formDescription.getInputControlDescriptions()) {
if (data[iDat] == null) {
str += String.format("<p>%s: -", cd.getTitle());
}
else {
str += String.format("<p>%s: %s", cd.getTitle(), data[iDat].toString());
}
iDat++;
}
str += "</html>";
return str;
return dataUnit.getSummaryString();
}
private void createSymbols() {

View File

@ -1,7 +1,7 @@
package loggerForms;
public enum PropertyTypes {
ORDER, AUTOALERT,SUBTABS,POPUP,HIDDEN,AUTORECORD,BEARING,
STARTTIME, ENDTIME, ORDER, AUTOALERT,SUBTABS,POPUP,HIDDEN,AUTORECORD,BEARING,
RANGE,HEADING,FONT,DBTABLENAME,
FORMCOLOUR,FORMCOLOR,
HOTKEY,NOCLEAR,NOCANCEL,NOTOFFLINE,NOTONLINE,
@ -16,6 +16,10 @@ public enum PropertyTypes {
public String getDescription() {
switch (this) {
case STARTTIME:
return "Form start time. Will be used as main data UTC. If undefined, form time is save time";
case ENDTIME:
return "Form end time. Will be used data end time in period data";
case AUTOALERT:
return "A warning will be issued if the form has not been completed for a set time";
case AUTORECORD:

View File

@ -3,8 +3,6 @@
*/
package loggerForms.controlDescriptions;
import generalDatabase.EmptyTableDefinition;
import java.sql.Types;
import javax.swing.JPanel;
@ -12,7 +10,6 @@ import javax.swing.JPanel;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import PamUtils.XMLUtils;
import loggerForms.FormDescription;
import loggerForms.FormsDataUnit;
import loggerForms.FormsTableItem;
@ -37,7 +34,6 @@ public abstract class ControlDescription extends ItemDescription {
protected ControlDescription(FormDescription formDescription, ItemInformation itemInformation) {
super(formDescription, itemInformation);
eType = ControlTypes.valueOf(getType());
// System.out.println(getType()+";"+eType.toString());
}
@ -88,11 +84,6 @@ public abstract class ControlDescription extends ItemDescription {
return formsTableItems;
}
private ControlTypes eType;
/**

View File

@ -0,0 +1,15 @@
package loggerForms.effort;
import effort.EffortDataUnit;
import loggerForms.FormsDataUnit;
public class FormsEffortUnit extends EffortDataUnit {
private FormsDataUnit parentFormUnit;
public FormsEffortUnit(LoggerEffortProvider loggerEffortProvider, FormsDataUnit parentFormUnit, long formEndTime) {
super(loggerEffortProvider, parentFormUnit, parentFormUnit.getTimeMilliseconds(), formEndTime);
this.parentFormUnit = parentFormUnit;
}
}

View File

@ -0,0 +1,165 @@
package loggerForms.effort;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import PamController.PamController;
import PamView.symbol.PamSymbolManager;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector;
import dataMap.OfflineDataMap;
import effort.EffortDataUnit;
import effort.EffortProvider;
import loggerForms.FormDescription;
import loggerForms.FormsDataBlock;
import loggerForms.FormsDataUnit;
public class LoggerEffortProvider extends EffortProvider {
private FormsDataBlock formsDataBlock;
private ArrayList<EffortDataUnit> onlineEffort;
public LoggerEffortProvider(FormsDataBlock parentDataBlock) {
super(parentDataBlock);
this.formsDataBlock = parentDataBlock;
FormDescription formsDescription = parentDataBlock.getFormDescription();
}
// @Override
// public EffortDataUnit getEffort(long timeMilliseconds) {
// ListIterator<FormsDataUnit> iterator = formsDataBlock.getListIterator(timeMilliseconds, 0, PamDataBlock.MATCH_BEFORE, PamDataBlock.POSITION_BEFORE);
// FormsDataUnit currentUnit = null;
// FormsDataUnit nextUnit = null;
// if (iterator == null) {
// return null;
// }
//
// if (iterator.hasNext()) {
// currentUnit = iterator.next();
// }
// if (iterator.hasNext()) {
// nextUnit = iterator.next();
// }
// if (currentUnit == null) {
// return null;
// }
// long endTime = getEndTime(currentUnit, nextUnit);
//
// return new FormsEffortUnit(this, currentUnit, endTime);
// }
private long getEndTime(FormsDataUnit currentUnit, FormsDataUnit nextUnit) {
Long end = currentUnit.getSetEndTime();
if (end != null) {
return end;
}
if (nextUnit == null) {
return getLastDatasetTime();
}
else {
return nextUnit.getTimeMilliseconds();
}
}
@Override
public List<EffortDataUnit> getAllEffortThings() {
return onlineEffort;
}
@Override
public void viewerLoadData() {
ArrayList<EffortDataUnit> allList = new ArrayList();
ListIterator<FormsDataUnit> iterator = formsDataBlock.getListIterator(0);
FormsDataUnit currentUnit = null;
FormsDataUnit nextUnit = null;
if (iterator.hasNext()) {
currentUnit = iterator.next();
}
while (iterator.hasNext()) {
nextUnit = iterator.next();
long end = getEndTime(currentUnit, nextUnit);
allList.add(new FormsEffortUnit(this, currentUnit, end));
currentUnit = nextUnit;
}
if (currentUnit != null) {
long end = getEndTime(currentUnit, null);
allList.add(new FormsEffortUnit(this, currentUnit, end));
}
onlineEffort = allList;
}
@Override
public DataSelector getDataSelector(String selectorName) {
// TODO Auto-generated method stub
return null;
}
@Override
public PamSymbolManager getSymbolManager() {
return formsDataBlock.getPamSymbolManager();
}
/**
* Get the last time of any data in this dataset from any data map.
* @return
*/
private long getLastDatasetTime() {
long lastTime = Long.MIN_VALUE;
ArrayList<PamDataBlock> allData = PamController.getInstance().getDataBlocks();
for (PamDataBlock aBlock : allData) {
OfflineDataMap dataMap = aBlock.getPrimaryDataMap();
if (dataMap != null) {
lastTime = Math.max(lastTime, dataMap.getLastDataTime());
}
}
return lastTime;
}
@Override
public String getName() {
return formsDataBlock.getDataName();
}
@Override
public void realTimeStart(long timeMilliseconds) {
// Don't do anything with start and end of processing
}
@Override
public void realTimeStop(long timeMilliseconds) {
// Don't do anything with start and end of processing
}
@Override
public void newData(PamDataUnit pamDataUnit) {
// generate effort things from incoming form data.
if (onlineEffort == null) {
onlineEffort = new ArrayList<>();
}
FormsEffortUnit lastEffort = null;
if (onlineEffort.size() > 0) {
lastEffort = (FormsEffortUnit) onlineEffort.get(onlineEffort.size()-1);
}
FormsDataUnit formDataUnit = (FormsDataUnit) pamDataUnit;
long thisStart = formDataUnit.getTimeMilliseconds();
Long thisEnd = formDataUnit.getSetEndTime();
if (lastEffort != null) {
/*
* If the previous effort didn't have a end time, then use this start as that's end.
*/
if (lastEffort.getEffortEnd() >= EffortDataUnit.ONGOINGEFFORT/2) {
lastEffort.setEffortEnd(thisStart);
}
}
if (thisEnd == null) {
thisEnd = EffortDataUnit.ONGOINGEFFORT;
}
FormsEffortUnit newEffort = new FormsEffortUnit(this, formDataUnit, thisEnd);
onlineEffort.add(newEffort);
}
}

View File

@ -11,6 +11,7 @@ import loggerForms.ItemInformation;
import loggerForms.PropertyDescription;
import loggerForms.PropertyTypes;
import loggerForms.UDColName;
import loggerForms.controlDescriptions.ControlTypes;
import loggerForms.formdesign.propertypanels.AutoAlertPanel;
import loggerForms.formdesign.propertypanels.BearingPanel;
import loggerForms.formdesign.propertypanels.BooleanPanel;
@ -26,6 +27,7 @@ import loggerForms.formdesign.propertypanels.PropertyPanel;
import loggerForms.formdesign.propertypanels.RangePanel;
import loggerForms.formdesign.propertypanels.SymbolPanel;
import loggerForms.formdesign.propertypanels.TextPanel;
import loggerForms.formdesign.propertypanels.XReferencePanel;
/**
* Layer that sits between the form description and the actual edit
@ -154,6 +156,10 @@ public class FormEditor {
public PropertyPanel makePropertyPanel(PropertyTypes propertyType) {
switch (propertyType) {
case STARTTIME:
return new XReferencePanel(this, propertyType, ControlTypes.TIMESTAMP);
case ENDTIME:
return new XReferencePanel(this, propertyType, ControlTypes.TIMESTAMP);
case AUTOALERT:
return new IntegerPanel(this, propertyType, UDColName.AutoUpdate, "Alert operator every", "minutes");
case AUTORECORD:

View File

@ -0,0 +1,95 @@
package loggerForms.formdesign.propertypanels;
import java.util.ArrayList;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import loggerForms.ItemInformation;
import loggerForms.PropertyTypes;
import loggerForms.UDColName;
import loggerForms.controlDescriptions.ControlTypes;
import loggerForms.formdesign.ControlTitle;
import loggerForms.formdesign.FormEditor;
import loggerForms.formdesign.FormEditor.EditNotify;
/**
* Property form for a cross reference sontrol.
* @author dg50
*
*/
public class XReferencePanel extends PropertyPanel {
private ControlTypes controlType;
private JComboBox<String> fieldNames;
public XReferencePanel(FormEditor formEditor, PropertyTypes propertyType, ControlTypes controlType) {
super(formEditor, propertyType);
this.controlType = controlType;
addItem(new JLabel(" Use "));
addItem(fieldNames = new JComboBox<String>());
}
/* (non-Javadoc)
* @see loggerForms.formdesign.propertypanels.PropertyPanel#notifyChanges(loggerForms.formdesign.FormEditor.EditNotify)
*/
@Override
public void notifyChanges(EditNotify notifyType) {
fillComboBox();
}
/**
* Fill the combo box with a list of all control names that have
* numeric data which might be used for bearing information.
*/
private void fillComboBox() {
String currentValue = (String) fieldNames.getSelectedItem();
fieldNames.removeAllItems();
ArrayList<ControlTitle> ctrlTitles = formEditor.getControlTitles();
for (ControlTitle title:ctrlTitles) {
if (title.getType() == null) {
continue;
}
if (title.getType() == controlType) {
fieldNames.addItem(title.getItemInformation().getStringProperty(UDColName.Title.toString()));
}
}
if (currentValue != null) {
fieldNames.setSelectedItem(currentValue);
}
else {
// pushProperty();
}
}
@Override
public void propertyEnable(boolean enabled) {
fieldNames.setEnabled(enabled);
}
@Override
public void pushProperty(ItemInformation itemInformation) {
super.pushProperty(itemInformation);
if (itemInformation == null) {
return;
}
try {
fieldNames.setSelectedItem(itemInformation.getStringProperty(UDColName.Title.toString()));
}
catch (Exception e) {};
}
@Override
public ItemInformation fetchProperty(ItemInformation itemInformation) {
itemInformation = super.fetchProperty(itemInformation);
if (itemInformation == null) {
return null;
}
itemInformation.setProperty(UDColName.Title.toString(), fieldNames.getSelectedItem());
return itemInformation;
}
}

View File

@ -0,0 +1,53 @@
package loggerForms.symbol;
import java.awt.Color;
import PamView.GeneralProjector;
import PamView.PamColors;
import PamView.PamSymbolType;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataUnit;
import loggerForms.FormDescription;
import loggerForms.controlDescriptions.ControlDescription;
/**
* Integer symbol modifier. Basically returns the whale colour rotation.
* @author dg50
*
*/
public class IntegerSymbolModifier extends LoggerSymbolModifier {
public IntegerSymbolModifier(FormDescription formDescription, ControlDescription controlDescription,
PamSymbolChooser symbolChooser, int modifyableBits) {
super(formDescription, controlDescription, symbolChooser, modifyableBits);
}
@Override
public SymbolData getSymbolData(GeneralProjector projector, PamDataUnit dataUnit) {
Object data = getControlData(dataUnit);
if (data == null) {
return null;
}
int number = 0;
if (data instanceof String) {
try {
number = Integer.valueOf(data.toString());
}
catch (NumberFormatException e) {
return null;
}
}
if (data instanceof Number) {
try {
number = Integer.valueOf(data.toString());
}
catch (Exception e) {
return null;
}
}
Color col = PamColors.getInstance().getChannelColor(number);
return new SymbolData(PamSymbolType.SYMBOL_CIRCLE, 1, 1, true, col, col);
}
}

View File

@ -0,0 +1,23 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.symbol.StandardSymbolChooser;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataBlock;
import dataPlots.data.SimpleSymbolChooser;
import loggerForms.FormsDataBlock;
public class LoggerSymbolChooser extends StandardSymbolChooser {
private FormsDataBlock formsDataBlock;
public LoggerSymbolChooser(StandardSymbolManager standardSymbolManager, FormsDataBlock pamDataBlock,
String displayName, SymbolData defaultSymbol, GeneralProjector projector) {
super(standardSymbolManager, pamDataBlock, displayName, defaultSymbol, projector);
this.formsDataBlock = pamDataBlock;
}
}

View File

@ -0,0 +1,130 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.PamSymbol;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.PamSymbolManager;
import PamView.symbol.StandardSymbolChooser;
import PamView.symbol.StandardSymbolManager;
import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModType;
import PamguardMVC.PamDataBlock;
import loggerForms.FormDescription;
import loggerForms.FormsDataBlock;
import loggerForms.LoggerFormGraphics;
import loggerForms.PropertyDescription;
import loggerForms.PropertyTypes;
import loggerForms.controlDescriptions.ControlDescription;
import loggerForms.formdesign.FormList;
import loggerForms.formdesign.propertypanels.SymbolPanel;
public class LoggerSymbolManager extends StandardSymbolManager {
private FormsDataBlock formsDataBlock;
private SymbolData standardFormSymbol;
public LoggerSymbolManager(FormsDataBlock pamDataBlock) {
super(pamDataBlock, LoggerFormGraphics.defaultSymbol);
this.formsDataBlock = pamDataBlock;
}
@Override
protected LoggerSymbolChooser createSymbolChooser(String displayName, GeneralProjector projector) {
return new LoggerSymbolChooser(this, formsDataBlock, displayName, getDefaultSymbol(), projector);
}
@Override
public SymbolData getDefaultSymbol() {
/**
* the default default is a generic one for logger data. See if it is overridden by a symbol
* specified for the form.
*/
SymbolData formSymbol = getFormSymbol();
if (formSymbol != null) {
return formSymbol;
}
else {
return super.getDefaultSymbol();
}
}
/**
* Get the default symbol for the form. Might be null,
* though might have been set in the form properties.
* @return
*/
public SymbolData getFormSymbol() {
if (standardFormSymbol == null) {
FormDescription formDescription = formsDataBlock.getFormDescription();
PropertyDescription formProperty = formDescription.findProperty(PropertyTypes.SYMBOLTYPE);
if (formProperty == null) {
return null;
}
PamSymbol symbol = SymbolPanel.createSymbol(formProperty.getItemInformation());
if (symbol != null) {
standardFormSymbol = symbol.getSymbolData();
}
}
return standardFormSymbol;
}
@Override
public void addSymbolModifiers(PamSymbolChooser psc) {
// probably don't want the standard ones.
// super.addSymbolModifiers(psc);
/*
* now add symbol modifiers for each control in the form.
* This will primarily be lookups which should have defined colours.
* May be able to do other controls based on their type / null / >0 values.
* Focus on lut's for now.
*/
FormDescription formDescription = formsDataBlock.getFormDescription();
FormList<ControlDescription> ctrls = formDescription.getControlDescriptions();
for (ControlDescription ctrlDescription : ctrls) {
LoggerSymbolModifier modifier = createSymbolModifier(formDescription, ctrlDescription, psc);
if (modifier != null) {
psc.addSymbolModifier(modifier);
}
}
}
private LoggerSymbolModifier createSymbolModifier(FormDescription formDescription,
ControlDescription ctrlDescription, PamSymbolChooser psc) {
switch (ctrlDescription.getEType()) {
case CHAR:
break;
case CHECKBOX:
break;
case COUNTER:
return new IntegerSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.FILLCOLOUR | SymbolModType.LINECOLOUR);
case DOUBLE:
break;
case INTEGER:
return new IntegerSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.FILLCOLOUR | SymbolModType.LINECOLOUR);
case LATLONG:
break;
case LOOKUP:
return new LookupSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.EVERYTHING);
case NMEACHAR:
break;
case NMEAFLOAT:
break;
case NMEAINT:
break;
case SHORT:
return new IntegerSymbolModifier(formDescription, ctrlDescription, psc, SymbolModType.FILLCOLOUR | SymbolModType.LINECOLOUR);
case SINGLE:
break;
case STATIC:
break;
case TIME:
break;
case TIMESTAMP:
break;
default:
break;
}
return null;
}
}

View File

@ -0,0 +1,66 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamView.symbol.modifier.SymbolModifier;
import PamguardMVC.PamDataUnit;
import loggerForms.FormDescription;
import loggerForms.FormsDataUnit;
import loggerForms.controlDescriptions.ControlDescription;
abstract public class LoggerSymbolModifier extends SymbolModifier {
protected FormDescription formDescription;
protected ControlDescription controlDescription;
protected int controlIndex;
public LoggerSymbolModifier(FormDescription formDescription, ControlDescription controlDescription,
PamSymbolChooser symbolChooser, int modifyableBits) {
super(controlDescription.getTitle(), symbolChooser, modifyableBits);
this.formDescription = formDescription;
this.controlDescription = controlDescription;
controlIndex = formDescription.getControlIndex(controlDescription);
}
/**
* Get the data object for this control from the data unit.
* @param dataUnit
* @return
*/
public Object getControlData(PamDataUnit dataUnit) {
if (dataUnit instanceof FormsDataUnit == false) {
return null;
}
FormsDataUnit formDataUnit = (FormsDataUnit) dataUnit;
Object[] data = formDataUnit.getFormData();
if (data == null || data.length <= controlIndex || controlIndex < 0) {
return null;
}
return data[controlIndex];
}
/**
* @return the formDescription
*/
protected FormDescription getFormDescription() {
return formDescription;
}
/**
* @return the controlDescription
*/
protected ControlDescription getControlDescription() {
return controlDescription;
}
/**
* @return the controlIndex
*/
protected int getControlIndex() {
return controlIndex;
}
}

View File

@ -0,0 +1,42 @@
package loggerForms.symbol;
import PamView.GeneralProjector;
import PamView.PamSymbol;
import PamView.symbol.PamSymbolChooser;
import PamView.symbol.SymbolData;
import PamguardMVC.PamDataUnit;
import generalDatabase.lookupTables.LookupItem;
import generalDatabase.lookupTables.LookupList;
import loggerForms.FormDescription;
import loggerForms.FormsDataUnit;
import loggerForms.controlDescriptions.CdLookup;
import loggerForms.controlDescriptions.ControlDescription;
public class LookupSymbolModifier extends LoggerSymbolModifier {
public LookupSymbolModifier(FormDescription formDescription, ControlDescription controlDescription,
PamSymbolChooser symbolChooser, int modifyableBits) {
super(formDescription, controlDescription, symbolChooser, modifyableBits);
}
@Override
public SymbolData getSymbolData(GeneralProjector projector, PamDataUnit dataUnit) {
Object data = getControlData(dataUnit);
if (data == null) {
return null;
}
LookupList lutList = ((CdLookup)controlDescription).getLookupList();
int lutIndex = lutList.indexOfCode(data.toString());
LookupItem lutItem = lutList.getLookupItem(lutIndex);
if (lutItem == null) {
return null;
}
PamSymbol symbol = lutItem.getSymbol();
if (symbol == null) {
return null;
}
return symbol.getSymbolData();
}
}

View File

@ -0,0 +1,35 @@
package ravendata;
import java.io.Serializable;
/**
* Information on a Raven table non standard column.
* @author dg50
*
*/
public class RavenColumnInfo implements Serializable {
private static final long serialVersionUID = 1L;
public int ravenTableIndex;
public String name;
public int maxStrLength;
public Integer sqlType;
public RavenColumnInfo(int ravenTableIndex, String name) {
super();
this.ravenTableIndex = ravenTableIndex;
this.name = name;
}
public RavenColumnInfo(String name, int maxStrLength, Integer sqlType) {
super();
this.name = name;
this.maxStrLength = maxStrLength;
this.sqlType = sqlType;
}
}

View File

@ -0,0 +1,119 @@
package ravendata;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.JMenuItem;
import PamController.PamConfiguration;
import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings;
import PamController.PamSettingManager;
import PamController.PamSettings;
import ravendata.swing.RavenImportDialog;
/**
* System for importing and displaying data from Raven selection tables.
* @author dg50
*
*/
public class RavenControl extends PamControlledUnit implements PamSettings {
private RavenProcess ravenProcess;
private static final String unitType = "Raven Import";
public static final String defaultName = unitType;
private RavenParameters ravenParameters = new RavenParameters();
public RavenControl(String unitName) {
super(unitType, unitName);
this.ravenProcess = new RavenProcess(this);
addPamProcess(ravenProcess);
PamSettingManager.getInstance().registerSettings(this);
if (isViewer()) {
ravenProcess.getRavenLogging().addExtraColumns(ravenParameters.getExtraColumns());
}
}
public RavenControl(PamConfiguration pamConfiguration, String unitType, String unitName) {
super(pamConfiguration, unitType, unitName);
}
@Override
public JMenuItem createDetectionMenu(Frame parentFrame) {
JMenuItem menuItem = new JMenuItem("Import Raven data ...");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
importData(parentFrame);
}
});
return menuItem;
}
protected void importData(Frame parentFrame) {
RavenParameters newParams = RavenImportDialog.showDialog(parentFrame, ravenParameters);
if (newParams == null) {
return;
}
ravenParameters = newParams;
// import the data. 1. Check for existing and delete, 2. Import, 3. rebuild datamap, 4. load data
RavenFileReader fileReader = null;
ArrayList<RavenDataRow> ravenData = null;
try {
fileReader = new RavenFileReader(this, ravenParameters.importFile);
ravenData = fileReader.readTable();
fileReader.closeFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
sortExtraColumns(fileReader, ravenData);
if (ravenData != null) {
ravenProcess.createPAMGuardData(fileReader, ravenData);
}
}
/**
* Check some information on column types.
* @param fileReader
* @param ravenData
*/
private void sortExtraColumns(RavenFileReader fileReader, ArrayList<RavenDataRow> ravenData) {
/*
* primarily need to add the extra columns to the SQL interface to make sure it's going to
* save the additional data.
* Also put them into the module parameters.
*/
ravenParameters.setExtraColumns(fileReader.getExtraColumns());
ravenProcess.getRavenLogging().addExtraColumns(fileReader.getExtraColumns());
}
@Override
public Serializable getSettingsReference() {
return ravenParameters;
}
@Override
public long getSettingsVersion() {
return RavenParameters.serialVersionUID;
}
@Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
ravenParameters = (RavenParameters) pamControlledUnitSettings.getSettings();
return true;
}
}

Some files were not shown because too many files have changed in this diff Show More