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

This commit is contained in:
Douglas Gillespie 2023-09-08 13:26:11 +01:00
commit dbeaa66821
37 changed files with 652 additions and 433 deletions

View File

@ -388,7 +388,10 @@ PamguardBeta_ViewerMode.exe):</p>
<h1><a name="_LATEST_VERSION_2.02.03"></a><a name="_VERSION_2.02.07_January"></a><em><span <h1><a name="_LATEST_VERSION_2.02.03"></a><a name="_VERSION_2.02.07_January"></a><em><span
style='font-size:12.0pt;font-family:"Cambria",serif;font-style:normal'><a style='font-size:12.0pt;font-family:"Cambria",serif;font-style:normal'><a
href="#_Latest_Version_2.02.08">LATEST VERSION 2.02.08 May 2023</a></span></em></h1> href="#_Version_2.02.09_June">Latest Version 2.02.09 June 2023</a></span></em></h1>
<h1><em><span style='font-size:12.0pt;font-family:"Cambria",serif;font-style:
normal'><a href="#_Version_2.02.08_May">Version 2.02.08 May 2023</a></span></em></h1>
<h1><em><span style='font-size:12.0pt;font-family:"Cambria",serif;font-style: <h1><em><span style='font-size:12.0pt;font-family:"Cambria",serif;font-style:
normal'><a href="#_Latest_Version_2.02.07">Version 2.02.07 January 2023</a></span></em></h1> normal'><a href="#_Latest_Version_2.02.07">Version 2.02.07 January 2023</a></span></em></h1>
@ -454,7 +457,17 @@ Version 2.00.10 June 2017</a></span></h1>
<h1><a name="_Latest_Version_2.02.03_1"></a><a name="_Latest_Version_2.02.05"></a><a <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.06"></a><a name="_Latest_Version_2.02.07"></a><a
name="_Latest_Version_2.02.08"></a><span lang=EN-US>Latest Version 2.02.08 May name="_Latest_Version_2.02.08"></a><a name="_Version_2.02.09_June"></a><span
lang=EN-US>Version 2.02.09 June 2023</span></h1>
<h2><span lang=EN-US>Bug Fixes</span></h2>
<p class=MsoNormal><span lang=EN-US>Time zone displays: Fixed some bugs
associated with options to have PAMGuard display times in local time, rather
than UTC. This was affecting times typed into the scroll bars of displays which
were reading local time, even when set to use UTC. </span></p>
<h1><a name="_Version_2.02.08_May"></a><span lang=EN-US>Version 2.02.08 May
2023</span></h1> 2023</span></h1>
<h2><span lang=EN-US>Bug Fixes</span></h2> <h2><span lang=EN-US>Bug Fixes</span></h2>
@ -463,25 +476,41 @@ name="_Latest_Version_2.02.08"></a><span lang=EN-US>Latest Version 2.02.08 May
which mostly occurred when processing large datasets of many offline files, has which mostly occurred when processing large datasets of many offline files, has
been fixed.</span></p> been fixed.</span></p>
<p class=MsoNormal><span lang=EN-US>Data Map: “Scroll To Data” pop-up menu,
which didnt always scroll to the correct place, is now fixed. </span></p>
<p class=MsoNormal><span lang=EN-US>Bearing Localiser offline: If reprocessing
bearings, the localizer was not correctly loading required raw or FFT data to
input to the cross correlation algorithm. This is now fixed so that you can
reprocess bearings in viewer mode. </span></p>
<p class=MsoNormal><span lang=EN-US>Map files: Added additional exception handlers
to handle corrupt map files. </span></p>
<h2><span lang=EN-US>New Features</span></h2> <h2><span lang=EN-US>New Features</span></h2>
<p class=MsoNormal><span lang=EN-US>Restart Options: When you restart <p class=MsoNormal><span lang=EN-US>Restart Options: When you restart
processing of offline files, if output data already exist (binary data of processing of offline files, if output data already exist (binary data of
within database tables) you will be asked if you want to overwrite the data, cancel, within database tables) you will be asked if you want to overwrite the data,
or try to continue from where to left off. </span></p> cancel, or try to continue from where to left off. </span></p>
<p class=MsoNormal><span lang=EN-US>Updated SoundTrap sud file interface so <p class=MsoNormal><span lang=EN-US>Updated SoundTrap sud file interface so
that PAMGuard now extracts and stores the Click Detector settings from the sud that PAMGuard now extracts and stores the Click Detector settings from the sud
files and stores them within the PAMGuard configuration. This does not affect files and stores them within the PAMGuard configuration. This does not affect
processing, but is important for record keeping. </span></p> processing, but is important for record keeping. </span></p>
<p class=MsoNormal><span lang=EN-US>GPS options to use any valid RMC or GGA
string. Not all GPS receivers output their RMC data as GPRMC e.g. some may
output as GNRMC. A new option allows the GPS module to use any string, whatever
the first two characters of the string name may be. </span></p>
<h1><span lang=EN-US>Version 2.02.07 January 2023</span></h1> <h1><span lang=EN-US>Version 2.02.07 January 2023</span></h1>
<h2><span lang=EN-US>Bug Fixes</span></h2> <h2><span lang=EN-US>Bug Fixes</span></h2>
<p class=MsoNormal><span lang=EN-US>Use of localization sensor and orientation <p class=MsoNormal><span lang=EN-US>Use of localization sensor and orientation data
data for static hydrophones had a bug whereby it would continually forget for static hydrophones had a bug whereby it would continually forget angle
angle offsets applied to static hydrophones in viewer mode. This is now fixed. </span></p> offsets applied to static hydrophones in viewer mode. This is now fixed. </span></p>
<p class=MsoNormal><span lang=EN-US>Click tool bar: Correctly shows event <p class=MsoNormal><span lang=EN-US>Click tool bar: Correctly shows event
selection options even if no species classification options are in place. </span></p> selection options even if no species classification options are in place. </span></p>
@ -491,8 +520,8 @@ selection options even if no species classification options are in place. </span
mode. Now fixed. </span></p> mode. Now fixed. </span></p>
<p class=MsoNormal><span lang=EN-US>ROCCA: Fixed (another) memory leak which <p class=MsoNormal><span lang=EN-US>ROCCA: Fixed (another) memory leak which
caused PAMGuard to crash when processing large data sets with the ROCCA classifier. caused PAMGuard to crash when processing large data sets with the ROCCA
</span></p> classifier. </span></p>
<p class=MsoNormal><span lang=EN-US>Ishmael Modules: Fixed bug which <p class=MsoNormal><span lang=EN-US>Ishmael Modules: Fixed bug which
occasionally caused crashes when processing many files offline. </span></p> occasionally caused crashes when processing many files offline. </span></p>
@ -534,10 +563,10 @@ whistle classification module.</span></p>
<p class=MsoNormal><span lang=EN-US>SoundTrap SUD file reading. If youre using <p class=MsoNormal><span lang=EN-US>SoundTrap SUD file reading. If youre using
SoundTrap autonomous recorders from Ocean Instruments, you no longer need to SoundTrap autonomous recorders from Ocean Instruments, you no longer need to
decompress the SoundTrap files prior to processing. This will save time and a decompress the SoundTrap files prior to processing. This will save time and a
lot of disk space. Extraction of clicks from the inbuilt SoundTrap Click lot of disk space. Extraction of clicks from the inbuilt SoundTrap Click detector
detector can also happen while processing SUD file data with other detectors, can also happen while processing SUD file data with other detectors, thereby
thereby streamlining the whole processing chain. Read the online Help for streamlining the whole processing chain. Read the online Help for details.
details. &nbsp;&nbsp;</span></p> &nbsp;&nbsp;</span></p>
<h1><span lang=EN-US>Version 2.02.05 October 2022</span></h1> <h1><span lang=EN-US>Version 2.02.05 October 2022</span></h1>
@ -640,9 +669,9 @@ selections from drop down lists within any form.</p>
<p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>&nbsp;</p>
<p class=MsoNormal>Note that updates have also been made to the Matlab <p class=MsoNormal>Note that updates have also been made to the Matlab interface
interface to PAMGuard binary files, which has now also been migrated to GitHub to PAMGuard binary files, which has now also been migrated to GitHub at <a
at <a href="https://github.com/PAMGuard/PAMGuardMatlab">https://github.com/PAMGuard/PAMGuardMatlab</a>. href="https://github.com/PAMGuard/PAMGuardMatlab">https://github.com/PAMGuard/PAMGuardMatlab</a>.
</p> </p>
<h1>&nbsp;</h1> <h1>&nbsp;</h1>
@ -800,9 +829,9 @@ Update whistle and moan detector to better handle small stubs or spurs coming
off the side of whistles </p> off the side of whistles </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>13. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>13. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
Extend the Hyperbolic Localiser to handle 2D planar arrays (previously limited lang=EN-US> </span>Extend the Hyperbolic Localiser to handle 2D planar arrays
to 3D volumetric arrays) </p> (previously limited to 3D volumetric arrays) </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>14. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>14. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
@ -816,20 +845,20 @@ decimating/upsampling by a non-integer amount </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>16. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>16. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
Noise Level Outputs - as an aid to performance diagnosis, some detectors Noise Level Outputs - as an aid to performance diagnosis, some detectors
(currently the GPL, Click Detector and Whistle and Moan Detector) are outputting (currently the GPL, Click Detector and Whistle and Moan Detector) are
additional noise metrics to their binary output files. These can be read with outputting additional noise metrics to their binary output files. These can be
the <a href="https://sourceforge.net/projects/pamguard/files/Matlab/">PAMGuard read with the <a href="https://sourceforge.net/projects/pamguard/files/Matlab/">PAMGuard
Matlab library</a> and used to diagnose system performance in varying noise Matlab library</a> and used to diagnose system performance in varying noise conditions.
conditions. Improved displays within PAMGuard for these noise metrics will be Improved displays within PAMGuard for these noise metrics will be included in a
included in a future release. </p> future release. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>17. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>17. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
An implementation of the Generalized Power Law Detector, developed by Tyler lang=EN-US> </span>An implementation of the Generalized Power Law Detector,
Helble ([Helble et al., ÃÂA generalized power-law detection algorithm for humpback developed by Tyler Helble ([Helble et al., ÃÂA generalized power-law detection
whale vocalizationsÃÂ, The Journal of the Acoustical Society of America, vol. algorithm for humpback whale vocalizationsÃÂ, The Journal of the Acoustical
131, no. 4, pp. 2682ÃÂ2699, 2012) is now available. For details, see the Society of America, vol. 131, no. 4, pp. 2682ÃÂ2699, 2012) is now available.
online help </p> For details, see the online help </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>18. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>18. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
@ -941,9 +970,10 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nb
lang=EN-US> </span>Better auto-scaling in Ishmael Detector graphics window. </p> lang=EN-US> </span>Better auto-scaling in Ishmael Detector graphics window. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>7. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>7. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
Change to Windows temporary folder location, to get around Windows Security lang=EN-US> </span>Change to Windows temporary folder location, to get around
settings that were preventing some modules from working properly. </p> Windows Security settings that were preventing some modules from working
properly. </p>
<!-- ************************************************************************************************************************** --><!-- ************************************************************************************************************************** --> <!-- ************************************************************************************************************************** --><!-- ************************************************************************************************************************** -->
@ -1171,8 +1201,8 @@ lang=EN-US> </span>Bug 436. Bug in Serial Port interface was occassionally
causing PAMGuard to crash without error message.</p> causing PAMGuard to crash without error message.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>5. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>5. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
Bug 437. Right whale detector crashing if no input was set.</p> lang=EN-US> </span>Bug 437. Right whale detector crashing if no input was set.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>6. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>6. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
@ -1449,8 +1479,8 @@ Upgrades to the Group Localiser, including better error estimation.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span <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 style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
lang=EN-US> </span>Click Train Detector upgrades, including ability to import lang=EN-US> </span>Click Train Detector upgrades, including ability to import time
time chunks from csv file for batch processing.</p> chunks from csv file for batch processing.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3. </span><span <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 lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
@ -1721,10 +1751,10 @@ lang=EN-US> </span>Better way of coupling scrollers in User Display panels -
see new options in main menu.</p> see new options in main menu.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span <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> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
Added Matched Template Click Classifier. Classifies clicks based on an ideal lang=EN-US> </span>Added Matched Template Click Classifier. Classifies clicks
template to match and a template to reject. An example of this is to classify based on an ideal template to match and a template to reject. An example of
beaked whale clicks in an environment with dolphin clicks.</p> this is to classify beaked whale clicks in an environment with dolphin clicks.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3. </span><span <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> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
@ -1840,11 +1870,11 @@ to work with whistles.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3. </span><span <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> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
Added option to export all settings and parameters as an XML-formatted file. Added option to export all settings and parameters as an XML-formatted file. Note
Note that this required changes to the structure of the Array Manager, and as that this required changes to the structure of the Array Manager, and as such
such any settings (psf) files created with this version of Pamguard cannot be any settings (psf) files created with this version of Pamguard cannot be used
used in older versions. Older psf files can be loaded with this version, but in older versions. Older psf files can be loaded with this version, but will be
will be converted.</p> converted.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4. </span><span <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><span lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
@ -1988,8 +2018,8 @@ invalid parameters. Have added diagnostics to prevent this.</p>
<p class=MsoNormal><b><span lang=EN-US>Upgrades</span></b></p> <p class=MsoNormal><b><span lang=EN-US>Upgrades</span></b></p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1. </span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
User is now able to specify Soundtrap date/time format</p> lang=EN-US> </span>User is now able to specify Soundtrap date/time format</p>
<!-- ************************************************************************************************************************** --> <!-- ************************************************************************************************************************** -->
@ -2096,11 +2126,11 @@ the PAMGuard Viewer the older data will be converted to the new format (see
below for details).</span></p> below for details).</span></p>
<p class=MsoNormal><span lang=EN-US>The most significant change in the binary <p class=MsoNormal><span lang=EN-US>The most significant change in the binary
file format is the addition of a Unique Data Identifier (UID) to each unit of file format is the addition of a Unique Data Identifier (UID) to each unit of data.
data. This is intended to aid in offline analysis by making it easier for the This is intended to aid in offline analysis by making it easier for the user to
user to link what they are seeing on different PAMGuard displays and also to link what they are seeing on different PAMGuard displays and also to link with
link with any data post processed in Matlab or other custom analysis software. any data post processed in Matlab or other custom analysis software. UIDÃÂs
UIDÃÂs are also added to PAMGuard database tables. </span></p> are also added to PAMGuard database tables. </span></p>
<h4><span lang=EN-US>Converting Old Data</span></h4> <h4><span lang=EN-US>Converting Old Data</span></h4>
@ -2161,10 +2191,10 @@ 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 <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; 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;
</span><span lang=EN-US>Display colour options will be lost and most data displayed </span><span lang=EN-US>Display colour options will be lost and most data
on the map may default to black. This is due to the above changes to how displayed on the map may default to black. This is due to the above changes to
colours are managed. Changing back to the colours of your choice is relatively how colours are managed. Changing back to the colours of your choice is
simple through the PAMGuard GUI. </span></p> relatively simple through the PAMGuard GUI. </span></p>
<p class=MsoListParagraph style='margin-left:54.0pt;text-indent:-36.0pt'><span <p class=MsoListParagraph style='margin-left:54.0pt;text-indent:-36.0pt'><span
lang=EN-US>&nbsp;</span></p> lang=EN-US>&nbsp;</span></p>
@ -2206,8 +2236,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>3.</span><span <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; lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Rocca Module: added StartHr, ProportionWhists and ProportionClicks </span>Rocca Module: added StartHr, ProportionWhists and ProportionClicks parameters
parameters to Event classifier</p> to Event classifier</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4.</span><span <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; lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -2358,10 +2388,10 @@ high sample rate. </span></p>
<p class=MsoListParagraph style='text-indent:-18.0pt'>2.<span style='font-size-adjust: none; <p class=MsoListParagraph style='text-indent:-18.0pt'>2.<span style='font-size-adjust: none;
font-stretch: normal'><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; font-stretch: normal'><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span><span lang=EN-US>Bug 305. Date and Time not being correctly </span></span><span lang=EN-US>Bug 305. Date and Time not being correctly extracted
extracted from wav files created using SoundTrap recorders. Fixed by correctly from wav files created using SoundTrap recorders. Fixed by correctly finding
finding and unpacking information in the accompanying xml log files that come and unpacking information in the accompanying xml log files that come with
with SoundTrap files. </span></p> SoundTrap files. </span></p>
<h1><a name="_Latest_Version_1.15.06"></a><span lang=EN-US>Version 1.15.06 <h1><a name="_Latest_Version_1.15.06"></a><span lang=EN-US>Version 1.15.06
November 2016</span></h1> November 2016</span></h1>
@ -2488,8 +2518,8 @@ detector has been tidied up so that there are a) All Click, b) Tracked Clicks
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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>When tracking online, all the click marking information </span><span lang=EN-US>When tracking online, all the click marking information
is written to the same database tables as are used for offline target motion is written to the same database tables as are used for offline target motion
analysis. This means than when reviewing data offline, the tracks created in real analysis. This means than when reviewing data offline, the tracks created in
time are now available for review and further analysis. </span></p> real time are now available for review and further analysis. </span></p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4.</span><span <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; lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -2719,8 +2749,8 @@ same click multiple times</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1.</span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1.</span><span
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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>Bug 253. Database import fails when Access database </span><span lang=EN-US>Bug 253. Database import fails when Access database contains
contains queries. Fixed.</span></p> queries. Fixed.</span></p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2.</span><span <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; lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -3099,8 +3129,9 @@ to read on a time. Fixed</p>
<p class=MsoNormal><i>Menu Layout</i></p> <p class=MsoNormal><i>Menu Layout</i></p>
<p class=MsoNormal>The PAMGuard menus have been rearranged into a more intuitive <p class=MsoNormal>The PAMGuard menus have been rearranged into a more
grouping which we believe will help users find functionality more easily. </p> intuitive grouping which we believe will help users find functionality more
easily. </p>
<p class=MsoNormal>'Detection' menu has been renamed to 'Settings' since many <p class=MsoNormal>'Detection' menu has been renamed to 'Settings' since many
menu items within this menu were not directly to do with 'Detection'.</p> menu items within this menu were not directly to do with 'Detection'.</p>
@ -3166,23 +3197,23 @@ whistles as well. </p>
<p class=MsoNormal>This module, funded by NOAA for the South West Fisheries <p class=MsoNormal>This module, funded by NOAA for the South West Fisheries
Science Centre (SWFSC), measures pitch and roll from analogue accelerometer Science Centre (SWFSC), measures pitch and roll from analogue accelerometer
sensors in a hydrophone. Data are fed real time into the updated hydrophone sensors in a hydrophone. Data are fed real time into the updated hydrophone
array manager in order that bearings from a tetrahedral tracking array are array manager in order that bearings from a tetrahedral tracking array are correctly
correctly calculated in real world coordinates. </p> calculated in real world coordinates. </p>
<p class=MsoNormal><i>Wild ArcGIS Interface</i> (Maps and Mapping group)</p> <p class=MsoNormal><i>Wild ArcGIS Interface</i> (Maps and Mapping group)</p>
<p class=MsoNormal>This module, developed by Michael Oswald / SWFSC, allows <p class=MsoNormal>This module, developed by Michael Oswald / SWFSC, allows
PAMGuard to output data in a format suitable for display in the WILD ArcGIS marine PAMGuard to output data in a format suitable for display in the WILD ArcGIS
mammal survey package. See online help for details. </p> marine mammal survey package. See online help for details. </p>
<p class=MsoNormal><i>Alarms</i> (Utilities Group)</p> <p class=MsoNormal><i>Alarms</i> (Utilities Group)</p>
<p class=MsoNormal>This is a general system of visual and audio alarms <p class=MsoNormal>This is a general system of visual and audio alarms developed
developed by Doug Gillespie for use on a variety of projects. The alarms can be by Doug Gillespie for use on a variety of projects. The alarms can be coupled
coupled to any module or detector in PAMGuard. Where appropriate, modules can to any module or detector in PAMGuard. Where appropriate, modules can control
control which of their data will cause an alarm action (e.g. in the Click which of their data will cause an alarm action (e.g. in the Click detector you
detector you can set which types of classified click will fire the alarm). See can set which types of classified click will fire the alarm). See online help
online help for details. &nbsp;</p> for details. &nbsp;</p>
<p class=MsoNormal><i>Noise Band Monitor</i> (Sound Processing Group)</p> <p class=MsoNormal><i>Noise Band Monitor</i> (Sound Processing Group)</p>
@ -3230,9 +3261,9 @@ different. Details are available in the online help. </p>
<p class=MsoNormal>Can now read raw audio data direct from FLAC files. <a <p class=MsoNormal>Can now read raw audio data direct from FLAC files. <a
href="http://en.wikipedia.org/wiki/FLAC">FLAC</a> is a lossless compression href="http://en.wikipedia.org/wiki/FLAC">FLAC</a> is a lossless compression
algorithm for audio data. Files, or folders of files are accessed in the same algorithm for audio data. Files, or folders of files are accessed in the same way
way as WAV and AIFF files in the Sound Acquisition module. In a future release as WAV and AIFF files in the Sound Acquisition module. In a future release we
we also hope to provide support for writing FLAC files from the sound recorder also hope to provide support for writing FLAC files from the sound recorder
module. </p> module. </p>
<p class=MsoNormal><i>Sound Recorder Module</i></p> <p class=MsoNormal><i>Sound Recorder Module</i></p>
@ -3276,9 +3307,8 @@ shaped Finite Impulse Response filters (see online help for details). </p>
<p class=MsoNormal><i>Radar Display</i></p> <p class=MsoNormal><i>Radar Display</i></p>
<p class=MsoNormal>Can now show bearings relative to true North OR the vessel <p class=MsoNormal>Can now show bearings relative to true North OR the vessel heading.
heading. Also has the option of only showing certain types of click and Also has the option of only showing certain types of click and whistle.</p>
whistle.</p>
<p class=MsoNormal><b>Bug Fixes</b></p> <p class=MsoNormal><b>Bug Fixes</b></p>
@ -3357,8 +3387,8 @@ survey software package.</p>
<p class=MsoNormal style='margin-left:36.0pt'><i>Core Functionality</i></p> <p class=MsoNormal style='margin-left:36.0pt'><i>Core Functionality</i></p>
<p class=MsoNormal style='margin-left:36.0pt'>New storage options have been <p class=MsoNormal style='margin-left:36.0pt'>New storage options have been implemented
implemented which give the user greater control of where data are stored. </p> which give the user greater control of where data are stored. </p>
<p class=MsoNormal style='margin-left:36.0pt'>Modules have been arranged into <p class=MsoNormal style='margin-left:36.0pt'>Modules have been arranged into
different groups in the configuration menus and tool tip texts have been added different groups in the configuration menus and tool tip texts have been added
@ -3445,8 +3475,8 @@ inter-detection interval.</p>
margin-left:36.0pt'>&nbsp;</p> margin-left:36.0pt'>&nbsp;</p>
<p class=MsoNormal style='margin-top:0cm;margin-right:0cm;margin-bottom:0cm; <p class=MsoNormal style='margin-top:0cm;margin-right:0cm;margin-bottom:0cm;
margin-left:36.0pt'>Target Motion Analysis: Updated target motion analysis margin-left:36.0pt'>Target Motion Analysis: Updated target motion analysis module
module so that it works in three (as opposed to two) dimensions.</p> so that it works in three (as opposed to two) dimensions.</p>
<p class=MsoNormal style='margin-top:0cm;margin-right:0cm;margin-bottom:0cm; <p class=MsoNormal style='margin-top:0cm;margin-right:0cm;margin-bottom:0cm;
margin-left:36.0pt'>&nbsp;</p> margin-left:36.0pt'>&nbsp;</p>
@ -3475,9 +3505,9 @@ have implemented database storage for output of these modules. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Radar Display: A bug which stopped the radar display from correctly displaying </span>Radar Display: A bug which stopped the radar display from correctly
bearings to whistles from arrays containing more than two hydrophone elements displaying bearings to whistles from arrays containing more than two hydrophone
has been fixed. </p> elements has been fixed. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -3683,8 +3713,8 @@ the correct data stream. This has been fixed. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Whistle classifier has some new features in the classifier training </span>Whistle classifier has some new features in the classifier training
panel. It is also now possible to export training data files directly from panel. It is also now possible to export training data files directly from binary
binary data files. </p> data files. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -3746,8 +3776,8 @@ frequency division (i.e. previous versions would convert well from 96kHz to
<p class=MsoNormal><b>Bug fixes</b></p> <p class=MsoNormal><b>Bug fixes</b></p>
<p class=MsoNormal>1. Placement of axes on some displays (array manager and depth <p class=MsoNormal>1. Placement of axes on some displays (array manager and
side panel). Problem in 1.9.01 Beta now fixed. </p> depth side panel). Problem in 1.9.01 Beta now fixed. </p>
<p class=MsoNormal>2. Fixed problems of NMEA read out not restarting after a <p class=MsoNormal>2. Fixed problems of NMEA read out not restarting after a
serial drop out. NMEA now restarts correctly. </p> serial drop out. NMEA now restarts correctly. </p>
@ -3935,12 +3965,12 @@ port is closed. Might prevent a few problems when using a GPS. </p>
<p class=MsoNormal><b>Bug Fixes</b></p> <p class=MsoNormal><b>Bug Fixes</b></p>
<p class=MsoNormal>Crashes caused in real time or Mixed Mode if the number of <p class=MsoNormal>Crashes caused in real time or Mixed Mode if the number of
software channels exceeds the number of hydrophones configured in the array software channels exceeds the number of hydrophones configured in the array manager.
manager. It is of course illogical to have software channels which are not It is of course illogical to have software channels which are not assigned to a
assigned to a hydrophone, so rather than entirely prevent PAMGUARD from hydrophone, so rather than entirely prevent PAMGUARD from crashing I have
crashing I have inserted additional checks into the hydrophone array dialog inserted additional checks into the hydrophone array dialog which will prevent
which will prevent the user from closing that dialog unless all software the user from closing that dialog unless all software channels are assigned to
channels are assigned to a hydrophone. </p> a hydrophone. </p>
<h2><span style='font-weight:normal'>Version 1.8.01 Beta February 2010</span></h2> <h2><span style='font-weight:normal'>Version 1.8.01 Beta February 2010</span></h2>
@ -3990,9 +4020,9 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>False buffer overflows at low sample rates stopped (size of data in </span>False buffer overflows at low sample rates stopped (size of data in individual
individual data blocks had been increased at low sample rates, but when this data blocks had been increased at low sample rates, but when this exceeded 3s a
exceeded 3s a false buffer overflow would occur).</p> false buffer overflow would occur).</p>
<p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>&nbsp;</p>
@ -4022,10 +4052,10 @@ synchronisation.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Wigner time-frequency plot for the click detector. Clicks are NOT automatically </span>Wigner time-frequency plot for the click detector. Clicks are NOT
displayed in the Winger window as they are for the waveform and spectrum automatically displayed in the Winger window as they are for the waveform and
windows since the Wigner transformation is very time consuming. Clicks will be spectrum windows since the Wigner transformation is very time consuming. Clicks
displayed if you select them with the mouse.</p> will be displayed if you select them with the mouse.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -4042,8 +4072,8 @@ arrays to give two polar angle coordinates. this can be used to resolve left
right ambiguity and is implemented for both the click and the whistle/moan right ambiguity and is implemented for both the click and the whistle/moan
detectors. As a result, the click detector bearing time display can now be set detectors. As a result, the click detector bearing time display can now be set
to go from -180 to 180 degrees rather than 0 - 180 degrees. In this case, to go from -180 to 180 degrees rather than 0 - 180 degrees. In this case,
clicks in the upper half of the bearing display will be to port and clicks in clicks in the upper half of the bearing display will be to port and clicks in the
the right half will be to starboard. As you pass a whale which is to port, the right half will be to starboard. As you pass a whale which is to port, the
clicks will move UP the display. In the long term, I hope to turn this display clicks will move UP the display. In the long term, I hope to turn this display
around so that time is up the screen rather than across.&nbsp; </p> around so that time is up the screen rather than across.&nbsp; </p>
@ -4120,9 +4150,9 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Channel lists in output data streams of Decimator and other modules fixed, </span>Channel lists in output data streams of Decimator and other modules
so that when channel numbers change, downstream modules configurations get the fixed, so that when channel numbers change, downstream modules configurations
correct list of available channels. </p> get the correct list of available channels. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -4334,8 +4364,8 @@ acquisition.&nbsp; </p>
<p class=MsoNormal><b>Bug fixes</b></p> <p class=MsoNormal><b>Bug fixes</b></p>
<p class=MsoNormal>Speed up of graphics, particularly regarding large <p class=MsoNormal>Speed up of graphics, particularly regarding large quantities
quantities of gps track &nbsp;data</p> of gps track &nbsp;data</p>
<p class=MsoNormal>National Instruments cards with names &gt; 20 characters <p class=MsoNormal>National Instruments cards with names &gt; 20 characters
long are now correctly &nbsp;recognised. </p> long are now correctly &nbsp;recognised. </p>
@ -4701,7 +4731,8 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
<h2>0.5b&nbsp;&nbsp;&nbsp; 31 August 2007 </h2> <h2>0.5b&nbsp;&nbsp;&nbsp; 31 August 2007 </h2>
<p class=MsoNormal>Requires Java 6 Update 2 (http://java.com/en/download/manual.jsp)</p> <p class=MsoNormal>Requires Java 6 Update 2
(http://java.com/en/download/manual.jsp)</p>
<p class=MsoNormal>Major new features include:</p> <p class=MsoNormal>Major new features include:</p>
@ -4744,8 +4775,8 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
<p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>&nbsp;</p>
<p class=MsoNormal><a name="_Toc312065304"></a><a name="_Toc312063949"></a><span <p class=MsoNormal><a name="_Toc312065304"></a><a name="_Toc312063949"></a><span
class=Heading2Char><span style='font-size:13.0pt'>1.0Beta 22 Jan 2008 - Pamguard class=Heading2Char><span style='font-size:13.0pt'>1.0Beta 22 Jan 2008 -
starts two releases, core and beta release</span></span>, </p> Pamguard starts two releases, core and beta release</span></span>, </p>
<p class=MsoNormal>this is the beta release</p> <p class=MsoNormal>this is the beta release</p>
@ -4763,8 +4794,8 @@ Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>Multi animal click tracking with least squares fit calculation of position </span>Multi animal click tracking with least squares fit calculation of
on map</p> position on map</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family: <p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -4817,12 +4848,12 @@ and Ishmael-type detectors and localisers. </p>
<p class=MsoNormal>Information from above modules can be displayed on <p class=MsoNormal>Information from above modules can be displayed on
configurable user displays which support real time scrolling spectrograms and configurable user displays which support real time scrolling spectrograms and
radar displays. Detection and localisation information can be optionally radar displays. Detection and localisation information can be optionally
displayed on the map display.Map enhancements include improved scrolling displayed on the map display.Map enhancements include improved scrolling whereby
whereby the user can click and drag to pan the area. PamGuard can now interface the user can click and drag to pan the area. PamGuard can now interface with
with MySQL database servers and users can easily select which information is MySQL database servers and users can easily select which information is logged.
logged. (This replaces the previous 'flat-file' logging feature). A simulation (This replaces the previous 'flat-file' logging feature). A simulation module
module allows virtual vocalising animals to be placed on the map to assist in allows virtual vocalising animals to be placed on the map to assist in training
training and development. Extensive online user help has been added to PamGuard and development. Extensive online user help has been added to PamGuard
Application</p> Application</p>
<h2>0.03b - first version used in a real 'at sea' environment.18/08/06</h2> <h2>0.03b - first version used in a real 'at sea' environment.18/08/06</h2>

View File

@ -4,7 +4,7 @@
<groupId>org.pamguard</groupId> <groupId>org.pamguard</groupId>
<artifactId>Pamguard</artifactId> <artifactId>Pamguard</artifactId>
<name>Pamguard Java12+</name> <name>Pamguard Java12+</name>
<version>2.02.08</version> <version>2.02.09</version>
<description>Pamguard for Java 12+, using Maven to control dependcies</description> <description>Pamguard for Java 12+, using Maven to control dependcies</description>
<url>www.pamguard.org</url> <url>www.pamguard.org</url>
<organization> <organization>

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.pamguard</groupId> <groupId>org.pamguard</groupId>
<artifactId>Pamguard</artifactId> <artifactId>Pamguard</artifactId>
<version>2.02.08</version> <version>2.02.09a</version>
<name>Pamguard Java12+</name> <name>Pamguard Java12+</name>
<description>Pamguard for Java 12+, using Maven to control dependcies</description> <description>Pamguard for Java 12+, using Maven to control dependcies</description>
<url>www.pamguard.org</url> <url>www.pamguard.org</url>

View File

@ -104,9 +104,13 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
boolean ans = super.prepareInputFile(); boolean ans = super.prepareInputFile();
if (ans == false && ++currentFile < allFiles.size()) { if (ans == false && ++currentFile < allFiles.size()) {
System.out.println("Failed to open sound file. Try again with file " + allFiles.get(currentFile).getName()); System.out.println("Failed to open sound file. Try again with file " + allFiles.get(currentFile).getName());
/*
* jumping striaght to the next file messes it up if it thinks the files
* are continuous, so we HAVE to stop and restart.
*/
// return prepareInputFile();
PamController.getInstance().pamStop(); PamController.getInstance().pamStop();
PamController.getInstance().startLater(); PamController.getInstance().startLater(false);
} }
return ans; return ans;
} }
@ -614,16 +618,16 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
long currFileEnd = 0; long currFileEnd = 0;
if (currentFile >= 0) { if (currentFile >= 0) {
try { try {
WavFileType currentWav = allFiles.get(currentFile); WavFileType currentWav = allFiles.get(currentFile);
currFileStart = getFileStartTime(currentWav.getAbsoluteFile()); currFileStart = getFileStartTime(currentWav.getAbsoluteFile());
if (audioStream != null) { if (audioStream != null) {
fileSamples = audioStream.getFrameLength(); fileSamples = audioStream.getFrameLength();
currFileLength = (long) (fileSamples * 1000 / audioStream.getFormat().getFrameRate()); currFileLength = (long) (fileSamples * 1000 / audioStream.getFormat().getFrameRate());
currFileEnd = currFileStart + currFileLength; currFileEnd = currFileStart + currFileLength;
} }
} }
catch (Exception e) { catch (Exception e) {
} }
} }
if (currFileEnd == 0) { if (currFileEnd == 0) {
@ -648,7 +652,17 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings, D
} }
setFolderProgress(); setFolderProgress();
// sayEta(); // sayEta();
ans = prepareInputFile(); /*
* I think that here, we just need a check of the file. the prepareInputFile in
* this class will (on failure) move straight to the next file and also issue a
* stop/start, which is not good if it's trying a continuous file, where this is
* being called, if false is returned it should manage moving onto the next file by
* itself if we use the super.prep ....
*/
ans = super.prepareInputFile();
if (ans == false) {
return false;
}
currentFileStart = System.currentTimeMillis(); currentFileStart = System.currentTimeMillis();
// if (ans && audioFormat.getSampleRate() != currentSampleRate && currentFile > 0) { // if (ans && audioFormat.getSampleRate() != currentSampleRate && currentFile > 0) {
// acquisitionControl.getDaqProcess().setSampleRate(currentSampleRate = audioFormat.getSampleRate(), true); // acquisitionControl.getDaqProcess().setSampleRate(currentSampleRate = audioFormat.getSampleRate(), true);

View File

@ -22,7 +22,7 @@ public class SUDFileType extends SoundFileType {
if (isShown) { if (isShown) {
return; return;
} }
WarnOnce.showWarning("SoundTrap SUD Files", sudInfoText, WarnOnce.OK_OPTION); // WarnOnce.showWarning("SoundTrap SUD Files", sudInfoText, WarnOnce.OK_OPTION);
isShown = true; isShown = true;
} }

View File

@ -48,9 +48,9 @@ public class SudAudioFile extends WavAudioFile {
} }
// don't do anything and it will try the built in Audiosystem // don't do anything and it will try the built in Audiosystem
catch (UnsupportedAudioFileException e) { catch (UnsupportedAudioFileException e) {
System.err.println("Could not open sud file: not a supported file " + soundFile.getName()); System.err.println("UnsupportedAudioFileException: Could not open sud file: not a supported file " + soundFile.getName());
System.err.println(e.getMessage());
e.printStackTrace(); // e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
System.err.println("Could not open sud file: IO Exception: " + soundFile.getName()); System.err.println("Could not open sud file: IO Exception: " + soundFile.getName());

View File

@ -46,7 +46,8 @@ public class SudAudioFileReader {
try { try {
sudAudioInputStream = SudAudioInputStream.openInputStream(file, sudParams, false); sudAudioInputStream = SudAudioInputStream.openInputStream(file, sudParams, false);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); String msg = String.format("Corrupt sud file %s: %s", file.getName(), e.getMessage());
throw new UnsupportedAudioFileException(msg);
} }
return sudAudioInputStream; return sudAudioInputStream;
} }

View File

@ -245,6 +245,31 @@ public class GPSControl extends PamControlledUnit implements PamSettings, Positi
public GpsDataUnit getShipPosition(long timeMilliseconds) { public GpsDataUnit getShipPosition(long timeMilliseconds) {
return getGpsDataBlock().getClosestUnitMillis(timeMilliseconds); return getGpsDataBlock().getClosestUnitMillis(timeMilliseconds);
} }
/**
* Do we want this string ? It will be either RMC or GGA and may want wildcarding
* @param stringId
* @return
*/
public boolean wantString(String stringId) {
if (stringId == null || stringId.length() < 6) {
return false;
}
if (gpsControl.gpsParameters.allowWildcard) {
String lastBit = stringId.substring(3, 6);
switch (gpsControl.gpsParameters.mainString) {
case GPSParameters.READ_RMC:
return lastBit.equals("RMC");
case GPSParameters.READ_GGA:
return lastBit.equals("GGA");
default:
return false;
}
}
else {
String wantedString = gpsControl.getWantedString();
return stringId.equals(wantedString);
}
}
/** /**
* Get the name of the string we're wanting. * Get the name of the string we're wanting.

View File

@ -59,6 +59,8 @@ public class GPSParameters implements Serializable, Cloneable, ManagedParameters
public String rmcInitials = "GP"; public String rmcInitials = "GP";
public String ggaInitials = "GP"; public String ggaInitials = "GP";
public boolean allowWildcard = true;
/** /**
* Attempt to read true heading information * Attempt to read true heading information
*/ */

View File

@ -149,9 +149,9 @@ public class GPSParametersDialog extends PamDialog {
} }
} }
public static GPSParameters showDialog(Frame parentFrame, GPSParameters gpsParameters) { public static GPSParameters showDialog(Frame parentFrame, GPSParameters gpsParameters) {
if (parentFrame != lastFrame || gpsParametersDialog == null) { // if (parentFrame != lastFrame || gpsParametersDialog == null) {
gpsParametersDialog = new GPSParametersDialog(parentFrame); gpsParametersDialog = new GPSParametersDialog(parentFrame);
} // }
gpsParametersDialog.gpsParameters = gpsParameters.clone(); gpsParametersDialog.gpsParameters = gpsParameters.clone();
gpsParametersDialog.setParams(); gpsParametersDialog.setParams();
gpsParametersDialog.setVisible(true); gpsParametersDialog.setVisible(true);
@ -335,6 +335,7 @@ public class GPSParametersDialog extends PamDialog {
JRadioButton ggaString; JRadioButton ggaString;
JTextField rmcInitials; JTextField rmcInitials;
JTextField ggaInitials; JTextField ggaInitials;
JCheckBox allowWildcard;
public MainStringPanel() { public MainStringPanel() {
super(); super();
setBorder(new TitledBorder("Main Nav' data string")); setBorder(new TitledBorder("Main Nav' data string"));
@ -344,9 +345,17 @@ public class GPSParametersDialog extends PamDialog {
c.fill = GridBagConstraints.HORIZONTAL; c.fill = GridBagConstraints.HORIZONTAL;
ButtonGroup buttonGroup = new ButtonGroup(); ButtonGroup buttonGroup = new ButtonGroup();
c.gridx = 0;
c.gridy++;
c.gridwidth = 5;
this.add(allowWildcard = new JCheckBox("Allow any string initials"), c);
allowWildcard.setToolTipText("Use RMC or GGA data from any source independent of the string initials (e.g. GP, GN, etc.)");
c.gridy ++;
c.gridwidth = 1;
c.gridx=0;
addComponent(this, new JLabel("RMC String"), c); addComponent(this, new JLabel("RMC String"), c);
c.gridx++; c.gridx ++;
addComponent(this, rmcString = new JRadioButton(""), c); addComponent(this, rmcString = new JRadioButton(""), c);
c.gridx++; c.gridx++;
addComponent(this, rmcInitials = new JTextField(2), c); addComponent(this, rmcInitials = new JTextField(2), c);
@ -355,6 +364,7 @@ public class GPSParametersDialog extends PamDialog {
c.gridx = 0; c.gridx = 0;
c.gridy ++; c.gridy ++;
c.gridwidth = 1;
addComponent(this, new JLabel("GGA String"), c); addComponent(this, new JLabel("GGA String"), c);
c.gridx++; c.gridx++;
addComponent(this, ggaString = new JRadioButton(""), c); addComponent(this, ggaString = new JRadioButton(""), c);
@ -363,6 +373,7 @@ public class GPSParametersDialog extends PamDialog {
c.gridx++; c.gridx++;
addComponent(this, new JLabel(" GGA"), c); addComponent(this, new JLabel(" GGA"), c);
allowWildcard.addActionListener(this);
rmcString.addActionListener(this); rmcString.addActionListener(this);
ggaString.addActionListener(this); ggaString.addActionListener(this);
buttonGroup.add(rmcString); buttonGroup.add(rmcString);
@ -374,10 +385,12 @@ public class GPSParametersDialog extends PamDialog {
ggaString.setSelected(gpsParameters.mainString == GPSParameters.READ_GGA); ggaString.setSelected(gpsParameters.mainString == GPSParameters.READ_GGA);
rmcInitials.setText(gpsParameters.rmcInitials); rmcInitials.setText(gpsParameters.rmcInitials);
ggaInitials.setText(gpsParameters.ggaInitials); ggaInitials.setText(gpsParameters.ggaInitials);
allowWildcard.setSelected(gpsParameters.allowWildcard);
enableControls(); enableControls();
} }
public boolean getParams() { public boolean getParams() {
gpsParameters.allowWildcard = allowWildcard.isSelected();
if (ggaString.isSelected()) { if (ggaString.isSelected()) {
gpsParameters.mainString = GPSParameters.READ_GGA; gpsParameters.mainString = GPSParameters.READ_GGA;
} }
@ -385,12 +398,12 @@ public class GPSParametersDialog extends PamDialog {
gpsParameters.mainString = GPSParameters.READ_RMC; gpsParameters.mainString = GPSParameters.READ_RMC;
} }
gpsParameters.rmcInitials = rmcInitials.getText(); gpsParameters.rmcInitials = rmcInitials.getText();
if (gpsParameters.rmcInitials.length() != 2) { if (gpsParameters.rmcInitials.length() != 2 && !gpsParameters.allowWildcard) {
return false; return showWarning("Expecting a two character identifier for RMC strings");
} }
gpsParameters.ggaInitials = ggaInitials.getText(); gpsParameters.ggaInitials = ggaInitials.getText();
if (gpsParameters.ggaInitials.length() != 2) { if (gpsParameters.ggaInitials.length() != 2 && !gpsParameters.allowWildcard) {
return false; return showWarning("Expecting a two character identifier for GGA strings");
} }
return true; return true;
} }
@ -400,8 +413,9 @@ public class GPSParametersDialog extends PamDialog {
} }
private void enableControls() { private void enableControls() {
rmcInitials.setEnabled(rmcString.isSelected()); boolean wild = allowWildcard.isSelected();
ggaInitials.setEnabled(ggaString.isSelected()); rmcInitials.setEnabled(rmcString.isSelected() & !wild);
ggaInitials.setEnabled(ggaString.isSelected() & !wild);
} }

View File

@ -57,7 +57,7 @@ public class ProcessNmeaData extends PamProcess {
private GpsLogger gpsLogger; private GpsLogger gpsLogger;
private String wantedString = "$GPRMC"; // private String wantedString = "$GPRMC";
private GpsDataUnit previousUnit = null; private GpsDataUnit previousUnit = null;
@ -161,7 +161,7 @@ public class ProcessNmeaData extends PamProcess {
@Override @Override
public void noteNewSettings() { public void noteNewSettings() {
findNMEADataBlock(); findNMEADataBlock();
setWantedString(); // setWantedString();
double minRate = Math.max(.2, 1./gpsController.gpsParameters.readInterval); double minRate = Math.max(.2, 1./gpsController.gpsParameters.readInterval);
processCheck.getOutputCounter().setMinRate(minRate); processCheck.getOutputCounter().setMinRate(minRate);
} }
@ -179,7 +179,8 @@ public class ProcessNmeaData extends PamProcess {
StringBuffer nmeaString = nmeaData.getCharData(); StringBuffer nmeaString = nmeaData.getCharData();
String stringId = NMEADataBlock.getSubString(nmeaString, 0); String stringId = NMEADataBlock.getSubString(nmeaString, 0);
if (stringId.equalsIgnoreCase(wantedString)) { // if (stringId.equalsIgnoreCase(wantedString)) {
if (gpsController.wantString(stringId)) {
gpsData = new GpsData(nmeaString, gpsController.gpsParameters.mainString); // GpsData constructor which gpsData = new GpsData(nmeaString, gpsController.gpsParameters.mainString); // GpsData constructor which
// unpacks the string. // unpacks the string.
if (gpsData.isDataOk()) { if (gpsData.isDataOk()) {
@ -316,13 +317,13 @@ public class ProcessNmeaData extends PamProcess {
super.clearOldData(); super.clearOldData();
} }
public String getWantedString() { // public String getWantedString() {
return wantedString; // return wantedString;
} // }
//
public void setWantedString() { // public void setWantedString() {
wantedString = gpsController.getWantedString(); // wantedString = gpsController.getWantedString();
} // }
public GPSControl getGpsController() { public GPSControl getGpsController() {
return gpsController; return gpsController;

View File

@ -221,9 +221,8 @@ public class UpdateClockDialog extends JDialog implements ActionListener, PamObs
// NMEADataBlock nmeaDataBlock = (NMEADataBlock) o; // NMEADataBlock nmeaDataBlock = (NMEADataBlock) o;
NMEADataUnit nmeaDataUnit = (NMEADataUnit) arg; NMEADataUnit nmeaDataUnit = (NMEADataUnit) arg;
StringBuffer nmeaData = nmeaDataUnit.getCharData(); StringBuffer nmeaData = nmeaDataUnit.getCharData();
String wantedString = gpsControl.getWantedString();
String stringId = NMEADataBlock.getSubString(nmeaData, 0); String stringId = NMEADataBlock.getSubString(nmeaData, 0);
if (wantedString.equals(stringId) == false) { if (gpsControl.wantString(stringId) == false) {
return; return;
} }
if (gpsControl.gpsParameters.mainString == GPSParameters.READ_GGA) { if (gpsControl.gpsParameters.mainString == GPSParameters.READ_GGA) {
@ -232,6 +231,8 @@ public class UpdateClockDialog extends JDialog implements ActionListener, PamObs
newRMCData(nmeaData); newRMCData(nmeaData);
} }
} }
@Override @Override
public void updateData(PamObservable observable, PamDataUnit pamDataUnit) { public void updateData(PamObservable observable, PamDataUnit pamDataUnit) {
// TODO Auto-generated method stub // TODO Auto-generated method stub

View File

@ -810,6 +810,9 @@ public class TMGroupLocInfo implements GroupLocInfo {
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
localisation = getParentDetection().getSubDetection(i).getLocalisation(); localisation = getParentDetection().getSubDetection(i).getLocalisation();
if (localisation == null) {
continue;
}
angles = localisation.getAngles(); angles = localisation.getAngles();
angleErrors = localisation.getAngleErrors(); angleErrors = localisation.getAngleErrors();
@ -879,6 +882,10 @@ public class TMGroupLocInfo implements GroupLocInfo {
totalVectors += nVectors; totalVectors += nVectors;
} }
if (totalVectors == 0) {
return;
}
//now create the separate arrays for different ambiguities. //now create the separate arrays for different ambiguities.
/** /**
* *

View File

@ -31,12 +31,12 @@ public class PamguardVersionInfo {
* Version number, major version.minorversion.sub-release. * Version number, major version.minorversion.sub-release.
* Note: can't go higher than sub-release 'f' * Note: can't go higher than sub-release 'f'
*/ */
static public final String version = "2.02.08"; static public final String version = "2.02.09a";
/** /**
* Release date * Release date
*/ */
static public final String date = "9 May 2023"; static public final String date = "29 June 2023";
// /** // /**
// * Release type - Beta or Core // * Release type - Beta or Core

View File

@ -42,6 +42,7 @@ public abstract class CommandManager extends PamControlledUnit {
commandsList.add(new SetXMLSettings()); commandsList.add(new SetXMLSettings());
commandsList.add(new BatchStatusCommand()); commandsList.add(new BatchStatusCommand());
commandsList.add(new BatchCommand(this)); commandsList.add(new BatchCommand(this));
commandsList.add(new FindGUICommand());
} }

View File

@ -0,0 +1,27 @@
package PamController.command;
import PamController.PamController;
import PamView.GuiFrameManager;
public class FindGUICommand extends ExtCommand {
public FindGUICommand() {
super("findgui", true);
}
@Override
public String execute(String command) {
GuiFrameManager frameManager = PamController.getInstance().getGuiFrameManager();
if (frameManager == null) {
return "No GUI to move";
}
frameManager.findGUI();
return "GUI Moved";
}
@Override
public String getHint() {
return "Move GUI components to the main monitor";
}
}

View File

@ -1,5 +1,6 @@
package PamController.settings; package PamController.settings;
import java.io.ByteArrayInputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -14,6 +15,7 @@ import PamController.PamController;
import PamController.PamSettingManager; import PamController.PamSettingManager;
import PamController.PamSettings; import PamController.PamSettings;
import PamController.PamSettingsGroup; import PamController.PamSettingsGroup;
import PamModel.PamModel;
import PamModel.PamModuleInfo; import PamModel.PamModuleInfo;
import PamModel.SMRUEnable; import PamModel.SMRUEnable;
import PamView.dialog.PamFileBrowser; import PamView.dialog.PamFileBrowser;
@ -226,7 +228,13 @@ public class SettingsImport {
ownerClass = Class.forName(aSet.getOwnerClassName()); ownerClass = Class.forName(aSet.getOwnerClassName());
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); // e.printStackTrace();
// this is happening since the ownerclassname is not set correctly in psfx files
// so we have to deserialise the data to find the class.
// ownerClass = getClassFromData(aSet.getSerialisedByteArray());
// ownerClass = PamModuleInfo.findModuleClass(aSet.getUnitType());
}
if (ownerClass == null) {
continue; continue;
} }
if (PamControlledUnit.class.isAssignableFrom(ownerClass)) { if (PamControlledUnit.class.isAssignableFrom(ownerClass)) {
@ -263,6 +271,17 @@ public class SettingsImport {
return groupedSettings; return groupedSettings;
} }
private Class getClassFromData(byte[] data) {
try {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
Object obj = ois.readObject();
return obj.getClass();
} catch (Exception e) {
return null;
}
}
private SettingsImportGroup findGroup(ArrayList<SettingsImportGroup> groupedSettings, String unitName) { private SettingsImportGroup findGroup(ArrayList<SettingsImportGroup> groupedSettings, String unitName) {
for (SettingsImportGroup iG:groupedSettings) { for (SettingsImportGroup iG:groupedSettings) {

View File

@ -45,14 +45,10 @@ import fftManager.FFTDataUnit;
import fftManager.PamFFTControl; import fftManager.PamFFTControl;
import group3dlocaliser.Group3DLocaliserControl; import group3dlocaliser.Group3DLocaliserControl;
import meygenturbine.MeygenTurbine; import meygenturbine.MeygenTurbine;
import networkTransfer.receive.BuoyStatusDataUnit;
import networkTransfer.receive.NetworkReceiver;
import printscreen.PrintScreenControl; import printscreen.PrintScreenControl;
import rockBlock.RockBlockControl; import rockBlock.RockBlockControl;
import turbineops.TurbineOperationControl; import turbineops.TurbineOperationControl;
import GPS.GpsDataUnit; import GPS.GpsDataUnit;
import Map.MapController;
import Map.gridbaselayer.GridbaseControl;
import NMEA.NMEADataUnit; import NMEA.NMEADataUnit;
import PamController.PamControlledUnitSettings; import PamController.PamControlledUnitSettings;
import PamController.PamController; import PamController.PamController;
@ -66,7 +62,6 @@ import PamguardMVC.PamDataBlock;
import analogarraysensor.ArraySensorControl; import analogarraysensor.ArraySensorControl;
import backupmanager.BackupManager; import backupmanager.BackupManager;
import beamformer.continuous.BeamFormerControl; import beamformer.continuous.BeamFormerControl;
import beamformer.localiser.BeamFormLocaliserControl;
import bearinglocaliser.BearingLocaliserControl; import bearinglocaliser.BearingLocaliserControl;
import binaryFileStorage.SecondaryBinaryStore; import binaryFileStorage.SecondaryBinaryStore;
import cepstrum.CepstrumControl; import cepstrum.CepstrumControl;
@ -1067,7 +1062,7 @@ final public class PamModel implements PamModelInterface, PamSettings {
// clear the current list // clear the current list
pluginList.clear(); pluginList.clear();
daqList.clear(); daqList.clear();
/* /*
* If developing a new PAMPlugin in eclipse, the easiest way to do it is to make a new * If developing a new PAMPlugin in eclipse, the easiest way to do it is to make a new
* Eclipse project for your plugin code. Within that project, copy this PamModel class * Eclipse project for your plugin code. Within that project, copy this PamModel class
@ -1082,7 +1077,6 @@ final public class PamModel implements PamModelInterface, PamSettings {
* When you export the code for your plugin to a jar file, remember to NOT inlcude the copy of * When you export the code for your plugin to a jar file, remember to NOT inlcude the copy of
* PamModel ! * PamModel !
*/ */
// Load up whatever default classloader was used to create this class. Must use the same classloader // Load up whatever default classloader was used to create this class. Must use the same classloader
// for all plugins, or else we will not be able to create proper dependencies between them or be able // for all plugins, or else we will not be able to create proper dependencies between them or be able
@ -1150,30 +1144,11 @@ final public class PamModel implements PamModelInterface, PamSettings {
// to add that URL to the default classloader path. // to add that URL to the default classloader path.
URL newURL = jarList.get(i).toURI().toURL(); URL newURL = jarList.get(i).toURI().toURL();
// original method
// Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
// method.setAccessible(true);
// method.invoke(cl, newURL);
// first fix attempt - create a brand new URLClassLoader. As expected, we get a ClassCastException when trying
// to load the parameters so we can't save params using this method
// URL[] newURLArray = new URL[1];
// newURLArray[0] = newURL;
// cl = new URLClassLoader(newURLArray);
// second attempt - custom class loader with the system app loader specified as the parent. Loads controlled unit, but // second attempt - custom class loader with the system app loader specified as the parent. Loads controlled unit, but
// as before it doesn't load the parameters // as before it doesn't load the parameters
classLoader.addURL(newURL); classLoader.addURL(newURL);
// third attempt
// Class<?> genericClass = cl.getClass();
// Method method = genericClass.getSuperclass().getDeclaredMethod("addURL", new Class[] {URL.class});
// method.setAccessible(true);
// method.invoke(cl, new Object[] {newURL});
// Save the name of the class to the global pluginBeingLoaded variable, and load the class. // Save the name of the class to the global pluginBeingLoaded variable, and load the class.
this.setPluginBeingLoaded(className); this.setPluginBeingLoaded(className);
// Class c = cl.loadClass(className); // Class c = cl.loadClass(className);
@ -1254,9 +1229,8 @@ final public class PamModel implements PamModelInterface, PamSettings {
"for help.<p>" + "for help.<p>" +
"This plug-in will not be available for loading"; "This plug-in will not be available for loading";
String help = null; String help = null;
int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, e1);
System.err.println("Exception while loading " + className); System.err.println("Exception while loading " + className);
System.err.println(e1.getMessage());
continue; continue;
} }
} }
@ -1269,7 +1243,7 @@ final public class PamModel implements PamModelInterface, PamSettings {
"for help.<p>" + "for help.<p>" +
"This plug-in will not be available for loading"; "This plug-in will not be available for loading";
String help = null; String help = null;
int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, ex); int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, ex);
System.err.println("Exception while loading " + jarList.get(i).getName()); System.err.println("Exception while loading " + jarList.get(i).getName());
continue; continue;
} }
@ -1294,7 +1268,7 @@ final public class PamModel implements PamModelInterface, PamSettings {
// instantiate the plugin control class using the custom class loader // instantiate the plugin control class using the custom class loader
try { try {
File classFile = new File(pf.getJarFile()); // File classFile = new File(pf.getJarFile());
//URLClassLoader cl = new URLClassLoader(new URL[]{classFile.toURI().toURL()}); //URLClassLoader cl = new URLClassLoader(new URL[]{classFile.toURI().toURL()});
// mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),cl); // mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),cl);
mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),classLoader); mi = PamModuleInfo.registerControlledUnit(pf.getClassName(), pf.getDescription(),classLoader);
@ -1360,7 +1334,7 @@ final public class PamModel implements PamModelInterface, PamSettings {
"for help.<p>" + "for help.<p>" +
"This plug-in will not be available for loading"; "This plug-in will not be available for loading";
String help = null; String help = null;
int ans = WarnOnce.showWarning(PamController.getMainFrame(), title, msg, WarnOnce.WARNING_MESSAGE, help, e1); int ans = WarnOnce.showWarning(PamController.getInstance().getGuiFrameManager().getFrame(0), title, msg, WarnOnce.WARNING_MESSAGE, help, e1);
System.err.println("Exception while loading " + pf.getDefaultName()); System.err.println("Exception while loading " + pf.getDefaultName());
pluginList.remove(pf); pluginList.remove(pf);
continue; continue;

View File

@ -282,6 +282,7 @@ public class PamModuleInfo implements PamDependent{
return moduleClass; return moduleClass;
} }
public static JMenu getModulesMenu(Frame parentFrame) { public static JMenu getModulesMenu(Frame parentFrame) {

View File

@ -47,7 +47,10 @@ public class PamCalendar {
public static TimeZone defaultTimeZone = TimeZone.getTimeZone("UTC"); public static TimeZone defaultTimeZone = TimeZone.getTimeZone("UTC");
private static TimeZone localTimeZone = TimeZone.getDefault(); /*
* Not used: all now handled in PamCalendar.
*/
// private static TimeZone localTimeZone = defaultTimeZone;// TimeZone.getDefault();
public static final long millisPerDay = 1000L*24L*3600L; public static final long millisPerDay = 1000L*24L*3600L;
@ -60,7 +63,7 @@ public class PamCalendar {
private static boolean soundFile; private static boolean soundFile;
/** /**
* time from the start of the file to the currentmoment. * time from the start of the file to the current moment.
* This is updated every time data re read from the file, so is * This is updated every time data re read from the file, so is
* accurate to about 1/10 second. * accurate to about 1/10 second.
* For accurate timing within detectors, always try to use sample number * For accurate timing within detectors, always try to use sample number
@ -177,8 +180,44 @@ public class PamCalendar {
public static TimeZone getDisplayTimeZone(boolean useLocal) { public static TimeZone getDisplayTimeZone(boolean useLocal) {
// return TimeZone.getTimeZone("UTC"); // return TimeZone.getTimeZone("UTC");
// return useLocal ? CalendarControl.getInstance().getChosenTimeZone() : defaultTimeZone; return useLocal ? CalendarControl.getInstance().getChosenTimeZone() : defaultTimeZone;
return useLocal ? localTimeZone : defaultTimeZone; // return useLocal ? localTimeZone : defaultTimeZone;
}
/**
* Get the display time zone offset in milliseconds.
* @param useLocal
* @return
*/
public static long getDisplayTimeZoneOffest(boolean useLocal) {
TimeZone tz = getDisplayTimeZone(useLocal);
return tz.getOffset(getTimeInMillis());
}
/**
* Get a short string describing the time zone. This should be less than
* 10 characters. So if the full name of the TZ is long, then write it
* in the format "UTC+..."
* @param useLocal
* @return
*/
public static String getShortDisplayTimeZoneString(boolean useLocal) {
TimeZone tz = getDisplayTimeZone(useLocal);
String str = tz.getDisplayName();
str = CalendarControl.getInstance().getTZCode(true);
if (str.length() <= 10) {
return str;
}
// otherwise make up a string.
long offset = getDisplayTimeZoneOffest(useLocal) / 1000;
boolean isInt = offset % 3600 == 0;
if (isInt) {
str = String.format("UTC%+d", offset/3600);
}
else {
str = String.format("UTC%+3.1f", (double) offset/3600.);
}
return str;
} }
public static String formatDateTime(Date date) { public static String formatDateTime(Date date) {
@ -391,8 +430,13 @@ public class PamCalendar {
public static String formatDBStyleTime(long timeInMillis, boolean showMillis, boolean useLocal) { public static String formatDBStyleTime(long timeInMillis, boolean showMillis, boolean useLocal) {
Calendar c = Calendar.getInstance(); Calendar c = Calendar.getInstance();
TimeZone tz = getDisplayTimeZone(useLocal);
// if (tz != null) {
// long offs = tz.getOffset(timeInMillis);
// timeInMillis += tz.getOffset(timeInMillis);
// }
c.setTimeInMillis(timeInMillis); c.setTimeInMillis(timeInMillis);
c.setTimeZone(getDisplayTimeZone(useLocal)); c.setTimeZone(tz);
DateFormat df; DateFormat df;
if (showMillis) { if (showMillis) {
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
@ -400,7 +444,7 @@ public class PamCalendar {
else { else {
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} }
df.setTimeZone(getDisplayTimeZone(useLocal)); df.setTimeZone(tz);
Date d = c.getTime(); Date d = c.getTime();
// return String.format("%tY-%<tm-%<td %<tH:%<tM:%<tS", d); // return String.format("%tY-%<tm-%<td %<tH:%<tM:%<tS", d);
@ -732,6 +776,7 @@ public class PamCalendar {
public static long msFromDateString(String dateString) { public static long msFromDateString(String dateString) {
return msFromDateString(dateString, false); return msFromDateString(dateString, false);
} }
/** /**
* Read a date string and turn it into a millisecond time. * Read a date string and turn it into a millisecond time.
* @param dateString * @param dateString

View File

@ -83,7 +83,7 @@ public class CalendarControl implements PamSettings{
@Override @Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
timeDisplayParameters = ((TimeDisplayParameters) pamControlledUnitSettings.getSettings()).clone(); timeDisplayParameters = ((TimeDisplayParameters) pamControlledUnitSettings.getSettings()).clone();
return false; return true;
} }
public String getTZCode(boolean daylight) { public String getTZCode(boolean daylight) {

View File

@ -11,13 +11,17 @@ public class TimeDisplayParameters implements Serializable, Cloneable, ManagedPa
public static final long serialVersionUID = 1L; public static final long serialVersionUID = 1L;
public static final int TIME_ZONE_UTC = 0; public static final int TIME_ZONE_UTC = 0;
public static final int TIME_ZONE_PC = 1;
public static final int TIME_ZONE_OTHER = 1; public static final int TIME_ZONE_OTHER = 1;
public static final int TIME_ZONE_PC = 2;
public int zoneType = TIME_ZONE_UTC; public int zoneType = TIME_ZONE_UTC;
public TimeZone timeZone; public TimeZone timeZone;
public TimeDisplayParameters() {
super();
}
@Override @Override
protected TimeDisplayParameters clone() { protected TimeDisplayParameters clone() {
try { try {

View File

@ -29,7 +29,7 @@ public class TimeZoneDisplayDialog extends PamDialog {
private JLabel pcTimeZone; private JLabel pcTimeZone;
private String[] timeZoneIds; private String[] timeZoneIds;
private TimeDisplayParameters timeDisplayParameters; private TimeDisplayParameters timeDisplayParameters;
private TimeZone thisTimeZone; // private TimeZone thisTimeZone;
private int utcTZIndex, pcTZIndex; private int utcTZIndex, pcTZIndex;
private static TimeZoneDisplayDialog singleInstance; private static TimeZoneDisplayDialog singleInstance;
@ -57,8 +57,8 @@ public class TimeZoneDisplayDialog extends PamDialog {
c.gridy++; c.gridy++;
c.gridx = 0; c.gridx = 0;
JLabel ta = new JLabel(); JLabel ta = new JLabel();
ta.setText("<html>Note that all processing and data storage will continue to <p>use UTC, the selection " + ta.setText("<html>Note that all processing and data storage will continue to use UTC. <p>The selection " +
"you make here \nwill only affect what is displayed on the screen"); "you make here will only affect what is displayed on the screen.");
tzPanel.add(ta, c); tzPanel.add(ta, c);
ButtonGroup bg = new ButtonGroup(); ButtonGroup bg = new ButtonGroup();
@ -66,7 +66,7 @@ public class TimeZoneDisplayDialog extends PamDialog {
bg.add(usePC); bg.add(usePC);
bg.add(useOther); bg.add(useOther);
thisTimeZone = Calendar.getInstance().getTimeZone(); TimeZone pcTimeZone = TimeZone.getDefault();
timeZoneIds = TimeZone.getAvailableIDs(); timeZoneIds = TimeZone.getAvailableIDs();
Arrays.sort(timeZoneIds, new TimeZoneComparator()); Arrays.sort(timeZoneIds, new TimeZoneComparator());
TimeZone tz; TimeZone tz;
@ -76,7 +76,7 @@ public class TimeZoneDisplayDialog extends PamDialog {
if (timeZoneIds[i].equals(PamCalendar.defaultTimeZone.getID())) { if (timeZoneIds[i].equals(PamCalendar.defaultTimeZone.getID())) {
utcTZIndex = i; utcTZIndex = i;
} }
if (timeZoneIds[i].equals(thisTimeZone.getID())) { if (timeZoneIds[i].equals(pcTimeZone.getID())) {
pcTZIndex = i; pcTZIndex = i;
} }
if (tz.getRawOffset() < 0) { if (tz.getRawOffset() < 0) {
@ -118,7 +118,8 @@ public class TimeZoneDisplayDialog extends PamDialog {
useUTC.setSelected(timeDisplayParameters.zoneType == TimeDisplayParameters.TIME_ZONE_UTC); useUTC.setSelected(timeDisplayParameters.zoneType == TimeDisplayParameters.TIME_ZONE_UTC);
usePC.setSelected(timeDisplayParameters.zoneType == TimeDisplayParameters.TIME_ZONE_PC); usePC.setSelected(timeDisplayParameters.zoneType == TimeDisplayParameters.TIME_ZONE_PC);
useOther.setSelected(timeDisplayParameters.zoneType == TimeDisplayParameters.TIME_ZONE_OTHER); useOther.setSelected(timeDisplayParameters.zoneType == TimeDisplayParameters.TIME_ZONE_OTHER);
pcTimeZone.setText(String.format("(%s / %s)", thisTimeZone.getID(), thisTimeZone.getDisplayName())); TimeZone defaultTimeZone = TimeZone.getDefault();
pcTimeZone.setText(String.format("(%s / %s)", defaultTimeZone.getID(), defaultTimeZone.getDisplayName()));
enableControls(); enableControls();
showSelection(); showSelection();
} }
@ -165,7 +166,7 @@ public class TimeZoneDisplayDialog extends PamDialog {
} }
else if (usePC.isSelected()) { else if (usePC.isSelected()) {
timeDisplayParameters.zoneType = TimeDisplayParameters.TIME_ZONE_PC; timeDisplayParameters.zoneType = TimeDisplayParameters.TIME_ZONE_PC;
timeDisplayParameters.timeZone = thisTimeZone; timeDisplayParameters.timeZone = TimeZone.getDefault();
} }
else if (useOther.isSelected()) { else if (useOther.isSelected()) {
timeDisplayParameters.zoneType = TimeDisplayParameters.TIME_ZONE_OTHER; timeDisplayParameters.zoneType = TimeDisplayParameters.TIME_ZONE_OTHER;

View File

@ -633,5 +633,26 @@ public class GuiFrameManager implements PamSettings, PAMControllerGUI {
return frameIcon; return frameIcon;
} }
/**
* Function that can move GUI frames back onto the main window.
* Can be used to recover a GUI if it's on a monitor that is not present.
*/
public void findGUI() {
if (pamViewList == null) {
return;
}
int loc = 10;
for (PamViewInterface view : pamViewList) {
JFrame frame = view.getGuiFrame();
if (frame == null) {
continue;
}
frame.setLocation(loc, loc);
frame.setState(JFrame.NORMAL);
frame.setVisible(true);
loc += 20;
}
}
} }

View File

@ -223,31 +223,30 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
PamSettingManager.getInstance().registerSettings(this); PamSettingManager.getInstance().registerSettings(this);
if (guiParameters.bounds != null) { if (guiParameters.bounds != null) {
/* // /*
* now need to check that the frame is visible on the // * now need to check that the frame is visible on the
* current screen - a pain when psf files are sent between // * current screen - a pain when psf files are sent between
* users, or when I work on two screens at work and then one // * users, or when I work on two screens at work and then one
* at home ! // * at home !
*/ // */
// Rectangle screenRect = ScreenSize.getScreenBounds(20000);
Rectangle screenRect = ScreenSize.getScreenBounds(); Point topCorner = guiParameters.bounds.getLocation();
// Rectangle intercept = screenRect.intersection(frame.getBounds()); boolean posOK = true;
if (screenRect == null) { try {
System.out.println("Unable to get screen dimensions from system"); posOK = ScreenSize.isPointOnScreen(topCorner);
// some weird stuff going down whereby the screen position is
// given as -8 from the corner where it really it. this can return
// false and then push the display onto a different monitor, so alow for this.
if (posOK == false) {
topCorner.x += 10;
topCorner.y += 10;
posOK = ScreenSize.isPointOnScreen(topCorner);
}
} catch (Exception e) {
} }
else { if (!posOK) {
while (guiParameters.bounds.x + guiParameters.bounds.width < screenRect.x + 200) { // put it in the top corner of the main screen.
guiParameters.bounds.x += screenRect.width; guiParameters.bounds.x = guiParameters.bounds.y = 10;
}
while (guiParameters.bounds.x > screenRect.x+screenRect.width) {
guiParameters.bounds.x -= screenRect.width;
}
while (guiParameters.bounds.y + guiParameters.bounds.height < screenRect.y + 200) {
guiParameters.bounds.y += screenRect.height;
}
while (guiParameters.bounds.y > screenRect.y+screenRect.height) {
guiParameters.bounds.y -= screenRect.height;
}
} }
frame.setBounds(guiParameters.bounds); frame.setBounds(guiParameters.bounds);

View File

@ -3,6 +3,7 @@ package PamView;
import java.awt.GraphicsConfiguration; import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.List; import java.util.List;
@ -15,7 +16,7 @@ import javafx.scene.layout.Pane;
/** /**
* Class to launch a thread which will get the screen size * Class to launch a thread which will get the screen size
* (inlcuding the bounds of multiple monitors) * (including the bounds of multiple monitors)
* <p> * <p>
* The process of getting the dimensions is launched in a * The process of getting the dimensions is launched in a
* different thread and can be going on while other PAMGAURD * different thread and can be going on while other PAMGAURD
@ -32,40 +33,6 @@ public class ScreenSize {
private static Rectangle[] screenDimensions; private static Rectangle[] screenDimensions;
// private volatile static boolean hasRun = false;
//
// private ScreenSize() {
// //Problems with startup on Mac that
// //seem to have been caused by the
// //GetBounds not being invoked from within
// //the Event Display Thread
// //CJB 2009-06-15
//// SwingUtilities.invokeLater(new GetBounds());
// //old version
// //Thread thread = new Thread(new GetBounds());
// //thread.start();
// long m1 = System.currentTimeMillis();
// findScreenBounds();
// long m2 = System.currentTimeMillis();
// System.out.println("screen bounds took ms: " + (m2-m1));
// }
//
// /**
// * Only needs to be called once to
// * start the background process which gets
// * the virtual screen size.
// * <p>
// * Is called from PAMGUARD Main to get it
// * going asap.
// */
// public static void startScreenSizeProcess() {
// if (hasRun == false) {
// hasRun = true;
// new ScreenSize();
// }
//
// }
//
/** /**
* Gets the screen bounds, sum / union of all screens. * Gets the screen bounds, sum / union of all screens.
* @return Virtual screen size, or null. * @return Virtual screen size, or null.
@ -103,40 +70,6 @@ public class ScreenSize {
return screenDimensions[iScreen]; return screenDimensions[iScreen];
} }
// /**
// * Gets the virtual screen size. Will wait for them to be
// * extracted from the background thread up to some set timeout
// * @param maxWaitMillis Max time to wait.
// * @return virtual screen dimension, or null if unavailable
// * after the set wait period.
// */
// public static Rectangle getScreenBounds(int maxWaitMillis) {
//
// startScreenSizeProcess();
//
// long endTime = System.currentTimeMillis() + maxWaitMillis;
// while (System.currentTimeMillis() <= endTime) {
// if (screenDimension != null) {
// return screenDimension;
// }
// try {
// Thread.sleep(100);
// }
// catch (InterruptedException e) {
// return screenDimension;
// }
// }
// return screenDimension;
// }
//
// /**
// *
// * @return true if screen bounds are available.
// */
// public boolean haveScreenBounds() {
// return (screenDimension != null);
// }
private static Rectangle findScreenBounds() { private static Rectangle findScreenBounds() {
Rectangle virtualBounds = new Rectangle(); Rectangle virtualBounds = new Rectangle();
if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) { if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) {
@ -160,40 +93,50 @@ public class ScreenSize {
//let PAMGUARD start up a little quicker //let PAMGUARD start up a little quicker
//CJB 2009-06-15 //CJB 2009-06-15
GraphicsConfiguration dgc = gd.getDefaultConfiguration(); GraphicsConfiguration dgc = gd.getDefaultConfiguration();
// System.out.printf("", dgc.getBufferCapabilities().)
// System.out.println(dgc);
screenDimensions[j] = dgc.getBounds(); screenDimensions[j] = dgc.getBounds();
virtualBounds = virtualBounds.union(dgc.getBounds()); virtualBounds = virtualBounds.union(dgc.getBounds());
} }
} }
// new Pane();
// List<Screen> screens = Screen.getScreens();
// if (screens != null) {
// for (Screen aScreen : screens) {
// System.out.printf("Screen resX %d, resY %d\n",
// aScreen.getResolutionX(),
// aScreen.getResolutionY());
// }
// }
//System.out.println("virtualBounds="+virtualBounds);
return virtualBounds; return virtualBounds;
} }
/**
* Pushes a rectangle so that it's visible on the screen.
* @param bounds - will get modified in place.
* @return true if the position was changed.
*/
public static boolean forceBoundToScreen(Rectangle bounds) {
try {
if (isPointOnScreen(bounds.getLocation()) == false) {
bounds.x = bounds.y = 0;
return true;
}
} catch (Exception e) {
return false;
}
return false;
}
/**
* Test to see if the point is within the bounds of any available monitor
* @param point point
* @return true if it's within the bounds of any montor
* @throws Exception Thrown if there are no monitors.
*/
public static boolean isPointOnScreen(Point point) throws Exception {
if (screenDimensions == null || screenDimensions.length == 0) {
throw new Exception("No attached screens. Can't test point");
}
for (int i = 0; i < screenDimensions.length; i++) {
if (screenDimensions[i].contains(point)) {
return true;
}
}
return false;
}
// /**
// * Thread to obtain the screen bounds.
// * @author Doug
// *
// */
// public class GetBounds implements Runnable {
//
// @Override
// public void run() {
//
// screenDimension = findScreenBounds();
//
// }
//
// }
} }

View File

@ -49,7 +49,7 @@ public class OverlayMarkProviders {
continue; continue;
} }
String existingName = marker.getMarkerName(); String existingName = marker.getMarkerName();
if (existingName.equals(nameToAdd)) { if (existingName!=null && existingName.equals(nameToAdd)) {
markProviders.remove(i); markProviders.remove(i);
break; break;
} }

View File

@ -125,7 +125,7 @@ abstract public class PamSymbolManager<T extends PamSymbolChooser> implements Pa
* This doesn't work since different displays will still need different options based on * This doesn't work since different displays will still need different options based on
* their projector - so it can work, but need to set the projector. * their projector - so it can work, but need to set the projector.
*/ */
if (managedSymbolData.useGeneric) { if (managedSymbolData.useGeneric || displayName==null) {
displayName = GENERICNAME; displayName = GENERICNAME;
} }

View File

@ -34,7 +34,7 @@ public class DataSelectDialog extends PamDialog {
private static final String helpPoint = "displays.dataselect.docs.selectandsymbol"; private static final String helpPoint = "displays.dataselect.docs.selectandsymbol";
public DataSelectDialog(Window parentFrame, PamDataBlock pamDataBlock, DataSelector dataSelector, PamSymbolChooser symbolChooser) { public DataSelectDialog(Window parentFrame, PamDataBlock pamDataBlock, DataSelector dataSelector, PamSymbolChooser symbolChooser) {
super(parentFrame, pamDataBlock.getDataName(), false); super(parentFrame, (pamDataBlock==null) ? "Data Selection":pamDataBlock.getDataName(), false);
this.dataSelector = dataSelector; this.dataSelector = dataSelector;
this.symbolChooser = symbolChooser; this.symbolChooser = symbolChooser;
tabPane = new JTabbedPane(); tabPane = new JTabbedPane();

View File

@ -23,7 +23,9 @@ public class DataSelectorSettings implements Serializable, ManagedParameters {
if (selectorParams == null) { if (selectorParams == null) {
selectorParams = new Hashtable<>(); selectorParams = new Hashtable<>();
} }
if (name != null) {
selectorParams.put(name, params); selectorParams.put(name, params);
}
} }
/** /**

View File

@ -28,6 +28,7 @@ public class UserFormSQLAddon implements SQLLoggingAddon {
} }
ArrayList<PamTableItem> loggerTableItems = new ArrayList<>(); ArrayList<PamTableItem> loggerTableItems = new ArrayList<>();
private ArrayList<InputControlDescription> controlDescriptions;
@Override @Override
@ -38,7 +39,13 @@ public class UserFormSQLAddon implements SQLLoggingAddon {
return; return;
} }
UDFTableDefinition formTableDef = formDescription.getUdfTableDefinition(); UDFTableDefinition formTableDef = formDescription.getUdfTableDefinition();
ArrayList<InputControlDescription> controlDescriptions = formDescription.getInputControlDescriptions(); controlDescriptions = formDescription.getInputControlDescriptions();
/*
* It's possible the controlDescriptions get rewritten, so hold references to
* the actual items buy copying the list.
*/
controlDescriptions = new ArrayList<>(controlDescriptions);
for (ControlDescription cd:controlDescriptions) { for (ControlDescription cd:controlDescriptions) {
FormsTableItem[] ctrlTableItems = cd.getFormsTableItems(); FormsTableItem[] ctrlTableItems = cd.getFormsTableItems();
if (ctrlTableItems != null) { if (ctrlTableItems != null) {
@ -73,15 +80,25 @@ public class UserFormSQLAddon implements SQLLoggingAddon {
// is created. So the inputControls list in FormDescription will only point to the last set of controls created, // is created. So the inputControls list in FormDescription will only point to the last set of controls created,
// which isn't necessarily the ones that this table is pointing to. Instead, load the loggerTableItems with // which isn't necessarily the ones that this table is pointing to. Instead, load the loggerTableItems with
// the data because loggerTableItems and pamTableDefinition both point to the same thing // the data because loggerTableItems and pamTableDefinition both point to the same thing
/*
* That doesn't work though since some controls have > 1 field, so it all gets out of synch. HAVE to
* use the moveDataToTableItems fields for it to work.
*/
// ArrayList<ControlDescription> inputCtrls = formDescription.getInputControlDescriptions(); // ArrayList<ControlDescription> inputCtrls = formDescription.getInputControlDescriptions();
// ControlDescription cd; // ControlDescription cd;
// for (int i = 0; i < inputCtrls.size(); i++) { // for (int i = 0; i < inputCtrls.size(); i++) {
// cd = inputCtrls.get(i); // cd = inputCtrls.get(i);
// cd.moveDataToTableItems(datas[i]); // cd.moveDataToTableItems(datas[i]);
// } // }
for (int i = 0; i < loggerTableItems.size(); i++) { for (int i = 0; i < controlDescriptions.size(); i++) {
loggerTableItems.get(i).setValue(datas[i]); controlDescriptions.get(i).moveDataToTableItems(datas[i]);
} }
// below doesn't work since some controls have > 1 field (e.g. latlong,
// int n = Math.min(loggerTableItems.size(), datas.length);
// for (int i = 0; i < n; i++) {
// loggerTableItems.get(i).setValue(datas[i]);
// }
return true; return true;
} }

View File

@ -10,6 +10,7 @@ import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
@ -31,10 +32,12 @@ import PamUtils.PamCalendar;
import PamView.PamColors; import PamView.PamColors;
import PamView.PamSymbol; import PamView.PamSymbol;
import PamView.PamSymbolType; import PamView.PamSymbolType;
import PamView.component.DataBlockTableView;
import PamView.dialog.PamGridBagContraints; import PamView.dialog.PamGridBagContraints;
import PamView.dialog.warn.WarnOnce; import PamView.dialog.warn.WarnOnce;
import PamView.tables.SwingTableColumnWidths; import PamView.tables.SwingTableColumnWidths;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.dataSelector.DataSelector;
import annotation.DataAnnotation; import annotation.DataAnnotation;
import annotation.DataAnnotationType; import annotation.DataAnnotationType;
import detectiongrouplocaliser.DetectionGroupControl; import detectiongrouplocaliser.DetectionGroupControl;
@ -44,12 +47,11 @@ import detectiongrouplocaliser.DetectionGroupObserver;
import detectiongrouplocaliser.DetectionGroupProcess; import detectiongrouplocaliser.DetectionGroupProcess;
import detectiongrouplocaliser.GroupAnnotationHandler; import detectiongrouplocaliser.GroupAnnotationHandler;
import pamScrollSystem.AbstractScrollManager; import pamScrollSystem.AbstractScrollManager;
import pamScrollSystem.PamScroller;
import userDisplay.UserDisplayComponentAdapter; import userDisplay.UserDisplayComponentAdapter;
import warnings.PamWarning;
/** /**
* Panel to show a table of data on all DetectionGroup data units. * Panel to show a table of data on all DetectionGroup data units.
*
* @author dg50 * @author dg50
* *
*/ */
@ -75,12 +77,17 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
private JButton checkIntegrity; private JButton checkIntegrity;
private JButton dataSelection;
private boolean isViewer; private boolean isViewer;
private DisplayOptionsHandler displayOptionsHandler; private DisplayOptionsHandler displayOptionsHandler;
private SwingTableColumnWidths widthManager; private SwingTableColumnWidths widthManager;
// private DataBlockTableView<DetectionGroupDataUnit> groupTableView;
private ArrayList<DetectionGroupDataUnit> dataCopy;
public DetectionGroupTable(DetectionGroupProcess detectionGroupProcess) { public DetectionGroupTable(DetectionGroupProcess detectionGroupProcess) {
super(); super();
this.detectionGroupProcess = detectionGroupProcess; this.detectionGroupProcess = detectionGroupProcess;
@ -104,14 +111,20 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
JPanel lControlPanel = new JPanel(new GridBagLayout()); JPanel lControlPanel = new JPanel(new GridBagLayout());
controlPanel.add(BorderLayout.WEST, lControlPanel); controlPanel.add(BorderLayout.WEST, lControlPanel);
GridBagConstraints c = new PamGridBagContraints(); GridBagConstraints c = new PamGridBagContraints();
lControlPanel.add(showAll = displayOptionsHandler.createButton(DisplayOptionsHandler.SHOW_ALL, "Show all groups in database", false), c); lControlPanel.add(showAll = displayOptionsHandler.createButton(DisplayOptionsHandler.SHOW_ALL,
"Show all groups in database", false), c);
c.gridx++; c.gridx++;
lControlPanel.add(showCurrent = displayOptionsHandler.createButton(DisplayOptionsHandler.SHOW_CURRENT, "Show only data currently loaded", false), c); lControlPanel.add(showCurrent = displayOptionsHandler.createButton(DisplayOptionsHandler.SHOW_CURRENT,
"Show only data currently loaded", false), c);
c.gridx++; c.gridx++;
checkIntegrity = new JButton("Check Data Integrity"); checkIntegrity = new JButton("Check Data Integrity");
checkIntegrity.setToolTipText("Check and fix start and end times of events against the database data"); checkIntegrity.setToolTipText("Check and fix start and end times of events against the database data");
dataSelection = new JButton("Data Selection");
dataSelection.setToolTipText("Select data to list");
lControlPanel.add(checkIntegrity, c); lControlPanel.add(checkIntegrity, c);
checkIntegrity.setVisible(detectionGroupControl.isViewer()); checkIntegrity.setVisible(detectionGroupControl.isViewer());
c.gridx++;
lControlPanel.add(dataSelection, c);
showAll.addActionListener(new ActionListener() { showAll.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@ -133,19 +146,39 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
detectionGroupProcess.checkDataIntegrity(); detectionGroupProcess.checkDataIntegrity();
} }
}); });
dataSelection.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dataSelectionButton(e);
}
});
} }
// sortColumnWidths();
// sortColumnWidths();
} }
protected void dataSelectionButton(ActionEvent e) {
DataSelector dataSelector = getDataSelector();
if (dataSelector != null) {
boolean changed = dataSelector.showSelectDialog(null);
if (changed) {
dataChanged();
}
}
}
private DataSelector getDataSelector() {
return detectionGroupDataBlock.getDataSelector(getUniqueName(), isViewer);
}
@Override @Override
public Component getComponent() { public Component getComponent() {
return mainPanel; return mainPanel;
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see userDisplay.UserDisplayComponentAdapter#openComponent() * @see userDisplay.UserDisplayComponentAdapter#openComponent()
*/ */
@Override @Override
@ -154,8 +187,9 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
super.openComponent(); super.openComponent();
} }
/*
/* (non-Javadoc) * (non-Javadoc)
*
* @see userDisplay.UserDisplayComponentAdapter#closeComponent() * @see userDisplay.UserDisplayComponentAdapter#closeComponent()
*/ */
@Override @Override
@ -166,7 +200,9 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
private class TableMouseHandler extends MouseAdapter { private class TableMouseHandler extends MouseAdapter {
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent) * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
*/ */
@Override @Override
@ -176,7 +212,9 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent) * @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)
*/ */
@Override @Override
@ -186,7 +224,9 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent) * @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)
*/ */
@Override @Override
@ -197,9 +237,17 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
} }
} }
@Override @Override
public void dataChanged() { public void dataChanged() {
long t1 = 0;
long t2 = Long.MAX_VALUE;
if (showCurrent.isSelected()) {
t1 = detectionGroupDataBlock.getCurrentViewDataStart();
t2 = detectionGroupDataBlock.getCurrentViewDataEnd();
}
dataCopy = detectionGroupDataBlock.getDataCopy(t1, t2, false, getDataSelector());
Collections.sort(dataCopy);
tableModel.fireTableDataChanged(); tableModel.fireTableDataChanged();
} }
@ -208,17 +256,17 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
} }
public void editSelectedEvent() { public void editSelectedEvent() {
DetectionGroupDataUnit dgdu = getSelectedDataRow(); DetectionGroupDataUnit dgdu = getSelectedDataRow();
if (dgdu == null) return; if (dgdu == null)
return;
editGroup(dgdu); editGroup(dgdu);
} }
public void showPopupMenu(MouseEvent e) { public void showPopupMenu(MouseEvent e) {
DetectionGroupDataUnit dgdu = getSelectedDataRow(); DetectionGroupDataUnit dgdu = getSelectedDataRow();
if (dgdu == null) return; if (dgdu == null)
return;
PamSymbol menuIcon = new PamSymbol(detectionGroupControl.getSymbolforMenuItems(dgdu)); PamSymbol menuIcon = new PamSymbol(detectionGroupControl.getSymbolforMenuItems(dgdu));
JPopupMenu pMenu = new JPopupMenu("Detection Group UID " + dgdu.getUID()); JPopupMenu pMenu = new JPopupMenu("Detection Group UID " + dgdu.getUID());
JMenuItem menuItem; JMenuItem menuItem;
@ -235,23 +283,23 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
menuItem.setIcon(menuIcon); menuItem.setIcon(menuIcon);
pMenu.add(menuItem); pMenu.add(menuItem);
int[] beforeTimesSecs = {0, 10, 60}; int[] beforeTimesSecs = { 0, 10, 60 };
pMenu.addSeparator(); pMenu.addSeparator();
for (int i = 0; i < beforeTimesSecs.length; i++) { for (int i = 0; i < beforeTimesSecs.length; i++) {
int before = beforeTimesSecs[i]; int before = beforeTimesSecs[i];
String title; String title;
if (before == 0) { if (before == 0) {
title = "Scroll to Group UID " + dgdu.getUID() + " at " + PamCalendar.formatDBDateTime(dgdu.getTimeMilliseconds()); title = "Scroll to Group UID " + dgdu.getUID() + " at "
} + PamCalendar.formatDBDateTime(dgdu.getTimeMilliseconds());
else { } else {
title = String.format("Scroll to %ds before Group UID %d", before, dgdu.getUID()); title = String.format("Scroll to %ds before Group UID %d", before, dgdu.getUID());
} }
menuItem = new JMenuItem(title); menuItem = new JMenuItem(title);
// menuItem.setIcon(menuIcon); // menuItem.setIcon(menuIcon);
menuItem.addActionListener(new ActionListener() { menuItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
scrollToEvent(dgdu.getTimeMilliseconds()-before*1000); scrollToEvent(dgdu.getTimeMilliseconds() - before * 1000);
} }
}); });
pMenu.add(menuItem); pMenu.add(menuItem);
@ -261,24 +309,22 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
} }
protected void scrollToEvent(long timeMilliseconds) { protected void scrollToEvent(long timeMilliseconds) {
// start a it earlier. // start a it earlier.
// timeMilliseconds -= 5000; // timeMilliseconds -= 5000;
// now WTF - how do I tell every scroller to go to this point in time ? // now WTF - how do I tell every scroller to go to this point in time ?
AbstractScrollManager scrollManager = AbstractScrollManager.getScrollManager(); AbstractScrollManager scrollManager = AbstractScrollManager.getScrollManager();
scrollManager.startDataAt(detectionGroupDataBlock, timeMilliseconds); scrollManager.startDataAt(detectionGroupDataBlock, timeMilliseconds);
} }
protected void editGroup(DetectionGroupDataUnit dgdu) { protected void editGroup(DetectionGroupDataUnit dgdu) {
detectionGroupProcess.editDetectionGroup(dgdu); detectionGroupProcess.editDetectionGroup(dgdu);
dataChanged(); dataChanged();
} }
protected void deleteGroup(DetectionGroupDataUnit dgdu, boolean askFirst) { protected void deleteGroup(DetectionGroupDataUnit dgdu, boolean askFirst) {
if (askFirst) { if (askFirst) {
int ans = WarnOnce.showWarning(PamController.getMainFrame(), "Delete Group Detection", int ans = WarnOnce.showWarning(PamController.getMainFrame(), "Delete Group Detection",
"Are you sure you want to permanently delete this group detection ?", WarnOnce.OK_CANCEL_OPTION); "Are you sure you want to permanently delete this group detection ?", WarnOnce.OK_CANCEL_OPTION);
if (ans == WarnOnce.CANCEL_OPTION) { if (ans == WarnOnce.CANCEL_OPTION) {
return; return;
@ -288,17 +334,17 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
dataChanged(); dataChanged();
} }
/** /**
* *
* @return which data row is selected, or null. * @return which data row is selected, or null.
*/ */
private DetectionGroupDataUnit getSelectedDataRow() { private DetectionGroupDataUnit getSelectedDataRow() {
int row = table.getSelectedRow(); int row = table.getSelectedRow();
if (row < 0) { if (row < 0 || dataCopy == null || row >= dataCopy.size()) {
return null; return null;
} }
return (DetectionGroupDataUnit) detectionGroupDataBlock.getDataUnit(row, PamDataBlock.REFERENCE_ABSOLUTE); return dataCopy.get(row);
// return (DetectionGroupDataUnit) detectionGroupDataBlock.getDataUnit(row, PamDataBlock.REFERENCE_ABSOLUTE);
} }
@Override @Override
@ -311,7 +357,7 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
private void sortColumnWidths() { private void sortColumnWidths() {
for (int i = 0; i < tableModel.getColumnCount(); i++) { for (int i = 0; i < tableModel.getColumnCount(); i++) {
TableColumn tableCol = table.getColumnModel().getColumn(i); TableColumn tableCol = table.getColumnModel().getColumn(i);
tableCol.setPreferredWidth(tableModel.getRelativeWidth(i)*50); tableCol.setPreferredWidth(tableModel.getRelativeWidth(i) * 50);
} }
} }
@ -319,8 +365,7 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
private int getViewOption() { private int getViewOption() {
if (!isViewer) { if (!isViewer) {
return DisplayOptionsHandler.SHOW_ALL; return DisplayOptionsHandler.SHOW_ALL;
} } else if (showCurrent != null) {
else if (showCurrent != null) {
if (showCurrent.isSelected()) { if (showCurrent.isSelected()) {
return displayOptionsHandler.SHOW_CURRENT; return displayOptionsHandler.SHOW_CURRENT;
} }
@ -334,7 +379,7 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
private List<DataAnnotationType<?>> usedAnnotations; private List<DataAnnotationType<?>> usedAnnotations;
private ArrayList<String> columnNames = new ArrayList<>(); private ArrayList<String> columnNames = new ArrayList<>();
private int nBaseColumns = 4; private int nBaseColumns = 4;
PamSymbol symbol = new PamSymbol(PamSymbolType.SYMBOL_SQUARE,48,12,true,Color.BLACK,Color.BLUE); PamSymbol symbol = new PamSymbol(PamSymbolType.SYMBOL_SQUARE, 48, 12, true, Color.BLACK, Color.BLUE);
private int firstRowToShow; private int firstRowToShow;
private int numRowsToShow; private int numRowsToShow;
@ -351,7 +396,9 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
return columnNames.size(); return columnNames.size();
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#getColumnName(int) * @see javax.swing.table.AbstractTableModel#getColumnName(int)
*/ */
@Override @Override
@ -361,37 +408,47 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
@Override @Override
public int getRowCount() { public int getRowCount() {
// System.out.println("getRowCount()"); // System.out.println("getRowCount()");
if (getViewOption() == DisplayOptionsHandler.SHOW_ALL) { if (dataCopy == null) {
firstRowToShow = 0; return 0;
return numRowsToShow = detectionGroupDataBlock.getUnitsCount();
}
else {
// work through datablock and work out the first and n indexes to show.
firstRowToShow = -1;
int lastRowToShow = -1;
int i = 0;
synchronized (detectionGroupDataBlock.getSynchLock()) {
ListIterator it = detectionGroupDataBlock.getListIterator(0);
while (it.hasNext()) {
DetectionGroupDataUnit nextData = (DetectionGroupDataUnit) it.next();
if (nextData.getSubDetectionsCount() > 0) {
if (firstRowToShow < 0) {
firstRowToShow = i;
}
lastRowToShow = i+1;
}
i++;
}
}
return lastRowToShow - firstRowToShow;
} }
return dataCopy.size();
// if (getViewOption() == DisplayOptionsHandler.SHOW_ALL) {
// firstRowToShow = 0;
// return numRowsToShow = dataCopy.size();
//// return numRowsToShow = detectionGroupDataBlock.getUnitsCount();
// }
// else {
// // work through datablock and work out the first and n indexes to show.
// firstRowToShow = -1;
// int lastRowToShow = -1;
// int i = 0;
// synchronized (detectionGroupDataBlock.getSynchLock()) {
// ListIterator it = detectionGroupDataBlock.getListIterator(0);
// while (it.hasNext()) {
// DetectionGroupDataUnit nextData = (DetectionGroupDataUnit) it.next();
// if (nextData.getSubDetectionsCount() > 0) {
// if (firstRowToShow < 0) {
// firstRowToShow = i;
// }
// lastRowToShow = i+1;
// }
// i++;
// }
// }
// return lastRowToShow - firstRowToShow;
// }
} }
@Override @Override
public Object getValueAt(int iRow, int iCol) { public Object getValueAt(int iRow, int iCol) {
if (dataCopy == null) {
return null;
}
try { try {
DetectionGroupDataUnit dgdu = (DetectionGroupDataUnit) detectionGroupDataBlock.getDataUnit(iRow+firstRowToShow, PamDataBlock.REFERENCE_ABSOLUTE); // DetectionGroupDataUnit dgdu = (DetectionGroupDataUnit) detectionGroupDataBlock.getDataUnit(iRow+firstRowToShow, PamDataBlock.REFERENCE_ABSOLUTE);
DetectionGroupDataUnit dgdu = dataCopy.get(iRow);
if (dgdu == null) { if (dgdu == null) {
return null; return null;
} }
@ -403,15 +460,14 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
return symbol; return symbol;
case 1: case 1:
if (dgdu.getUpdateCount() > 0) { if (dgdu.getUpdateCount() > 0) {
return "*"+dgdu.getUpdateCount(); return "*" + dgdu.getUpdateCount();
} } else {
else {
return null; return null;
} }
case 2: case 2:
// if (iRow == 0) { // if (iRow == 0) {
// System.out.println("getValueAt(0,0)"); // System.out.println("getValueAt(0,0)");
// } // }
return dgdu.getUID(); return dgdu.getUID();
case 3: case 3:
return PamCalendar.formatDateTime(dgdu.getTimeMilliseconds()); return PamCalendar.formatDateTime(dgdu.getTimeMilliseconds());
@ -432,8 +488,7 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
} }
} } catch (Exception e) {
catch (Exception e) {
return null; return null;
} }
return null; return null;
@ -447,7 +502,9 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
return super.getColumnClass(col); return super.getColumnClass(col);
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see javax.swing.table.AbstractTableModel#fireTableStructureChanged() * @see javax.swing.table.AbstractTableModel#fireTableStructureChanged()
*/ */
@Override @Override
@ -463,25 +520,25 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
// count columns in each annotation ... // count columns in each annotation ...
annotationHandler = detectionGroupProcess.getAnnotationHandler(); annotationHandler = detectionGroupProcess.getAnnotationHandler();
usedAnnotations = annotationHandler.getUsedAnnotationTypes(); usedAnnotations = annotationHandler.getUsedAnnotationTypes();
for (DataAnnotationType annotation:usedAnnotations) { for (DataAnnotationType annotation : usedAnnotations) {
columnNames.add(annotation.getAnnotationName()); columnNames.add(annotation.getAnnotationName());
} }
super.fireTableStructureChanged(); super.fireTableStructureChanged();
} }
/** /**
* Attempt to set column widths. * Attempt to set column widths.
*
* @param colIndex * @param colIndex
* @return relative column widths. * @return relative column widths.
*/ */
public int getRelativeWidth(int colIndex) { public int getRelativeWidth(int colIndex) {
switch(colIndex) { switch (colIndex) {
case 0: case 0:
return 1; return 1;
case 1: case 1:
return 1; return 1;
case 2: case 2:
return 5; return 5;
case 3: case 3:
return 5; return 5;
@ -491,7 +548,9 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
} }
} }
/* (non-Javadoc) /*
* (non-Javadoc)
*
* @see userDisplay.UserDisplayComponentAdapter#setUniqueName(java.lang.String) * @see userDisplay.UserDisplayComponentAdapter#setUniqueName(java.lang.String)
*/ */
@Override @Override
@ -500,6 +559,4 @@ public class DetectionGroupTable extends UserDisplayComponentAdapter implements
super.setUniqueName(uniqueName); super.setUniqueName(uniqueName);
} }
} }

View File

@ -316,11 +316,19 @@ public class DifarProcess extends PamProcess {
sP = difarControl.getDifarParameters().findSpeciesParams(difarDataUnit); sP = difarControl.getDifarParameters().findSpeciesParams(difarDataUnit);
} }
difarDataUnit.setDisplaySampleRate(sP.sampleRate); difarDataUnit.setDisplaySampleRate(sP.sampleRate);
if (!sP.useMarkedBandsForSpectrogramClips){ if (difarDataUnit.triggerName.equals(difarControl.getUnitName())) { // User detection
double[] frequency = {sP.processFreqMin, sP.processFreqMax}; if (!sP.useMarkedBandsForSpectrogramClips ){
difarDataUnit.setFrequency(frequency); double[] frequency = {sP.processFreqMin, sP.processFreqMax};
difarDataUnit.setFrequency(frequency);
}
} else { //Check whether to override auto detection freq limits with DIFAR limits
if (!sP.useDetectionLimitsForTriggeredDetections ){ // Auto-detection
double[] frequency = {sP.processFreqMin, sP.processFreqMax};
difarDataUnit.setFrequency(frequency);
}
} }
demuxDataUnit(difarDataUnit, demuxWorker, startTime); demuxDataUnit(difarDataUnit, demuxWorker, startTime);
calculateDifarGram(difarDataUnit, demuxWorker, startTime); calculateDifarGram(difarDataUnit, demuxWorker, startTime);

View File

@ -173,6 +173,9 @@ public class GroupLocSettingPaneFX extends SettingsPane<Group3DParams>{
algoOptsButton.setDisable(true); algoOptsButton.setDisable(true);
return; return;
} }
// also enable / disable the more options button ...
algoOptsButton.setDisable(localiserAlgorithm.hasParams() == false);
/** /**
* Need to immediately tell the algorithm which input we're using so that it can * Need to immediately tell the algorithm which input we're using so that it can
* show the correct settings... * show the correct settings...
@ -208,10 +211,7 @@ public class GroupLocSettingPaneFX extends SettingsPane<Group3DParams>{
// newPane.setDetectionSource(sourcePanel.getSource()); // newPane.setDetectionSource(sourcePanel.getSource());
} }
algorithmSourcePane = newPane; algorithmSourcePane = newPane;
// also enable / disable the more options button ...
algoOptsButton.setDisable(localiserAlgorithm.hasParams() == false);
repackDialog(); repackDialog();
} }

View File

@ -36,7 +36,10 @@ From the Detection Menu, select <strong><em>GPS>GPS Options</em></strong>
<p> <p>
On very rare occasions, if the GPS data have been multiplexed through some other instruments, the first On very rare occasions, if the GPS data have been multiplexed through some other instruments, the first
two characters of the string identifier are changed. If this is the case, it may also be necessary to set these two characters of the string identifier are changed. If this is the case, it may also be necessary to set these
so that the GPS module can identify the appropriate data. so that the GPS module can identify the appropriate data. As an alternative, select the "Allow and string initials" option
which will use any valid RMC or GGA string. Note however, that with a complex NMEA system there may be more than one GPS and
it is better to select only strings from the most accurate</p>
<h3>Read Options</h3> <h3>Read Options</h3>
<p>Three options for reading and storing GPS data are available.</p> <p>Three options for reading and storing GPS data are available.</p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -107,7 +107,8 @@ public class DLClassifyProcess extends PamInstantProcess {
addOutputDataBlock(dlDetectionDataBlock); addOutputDataBlock(dlDetectionDataBlock);
dlDetectionDataBlock.setNaturalLifetimeMillis(600*1000); //keep this data for a while. dlDetectionDataBlock.setNaturalLifetimeMillis(600*1000); //keep this data for a while.
dlDetectionDataBlock.addDataAnnotationType(dlAnnotationType); dlDetectionDataBlock.addDataAnnotationType(dlAnnotationType);
//ClipGeneration allows processing of detections by DIFAR module (and possibly others)
dlDetectionDataBlock.setCanClipGenerate(true);
//add custom graphics //add custom graphics
PamDetectionOverlayGraphics overlayGraphics = new DLGraphics(dlModelResultDataBlock); PamDetectionOverlayGraphics overlayGraphics = new DLGraphics(dlModelResultDataBlock);
overlayGraphics.setDetectionData(true); overlayGraphics.setDetectionData(true);
@ -483,7 +484,7 @@ public class DLClassifyProcess extends PamInstantProcess {
DataUnitBaseData basicData = groupDataBuffer.get(0).getBasicData().clone(); DataUnitBaseData basicData = groupDataBuffer.get(0).getBasicData().clone();
basicData.setMillisecondDuration(1000.*rawdata[0].length/this.sampleRate); basicData.setMillisecondDuration(1000.*rawdata[0].length/this.sampleRate);
basicData.setSampleDuration((long) (groupDataBuffer.size()*dlControl.getDLParams().sampleHop)); basicData.setSampleDuration((long) (groupDataBuffer.size()*dlControl.getDLParams().rawSampleSize));
// System.out.println("Model result: " + modelResult.size()); // System.out.println("Model result: " + modelResult.size());
DLDetection dlDetection = new DLDetection(basicData, rawdata); DLDetection dlDetection = new DLDetection(basicData, rawdata);