Merge pull request #36 from PAMGuard/main

Merging from PM Main
This commit is contained in:
Douglas Gillespie 2023-01-25 16:32:11 +00:00 committed by GitHub
commit 738c9ab6dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 2034 additions and 908 deletions

View File

@ -386,9 +386,12 @@ PamguardBeta_ViewerMode.exe):</p>
<p class=MsoNormal><em><span style='font-family:"Calibri",sans-serif'>&nbsp;</span></em></p> <p class=MsoNormal><em><span style='font-family:"Calibri",sans-serif'>&nbsp;</span></em></p>
<h1><a name="_LATEST_VERSION_2.02.03"></a><em><span style='font-size:12.0pt; <h1><a name="_LATEST_VERSION_2.02.03"></a><a name="_VERSION_2.02.07_January"></a><em><span
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.06">LATEST VERSION 2.02.06 November 2022</a></span></em></h1> href="#_Latest_Version_2.02.07">LATEST VERSION 2.02.07 January 2023</a></span></em></h1>
<h1><em><span style='font-size:12.0pt;font-family:"Cambria",serif;font-style:
normal'><a href="#_Latest_Version_2.02.06">Version 2.02.06 November 2022</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.05">Version 2.02.05 October 2022</a></span></em></h1> normal'><a href="#_Latest_Version_2.02.05">Version 2.02.05 October 2022</a></span></em></h1>
@ -447,8 +450,47 @@ Version 2.00.10 June 2017</a></span></h1>
<h1><span style='font-size:12.0pt'><a href="#_Older_Versions">Older Versions</a></span></h1> <h1><span style='font-size:12.0pt'><a href="#_Older_Versions">Older Versions</a></span></h1>
<h1><a name="_Latest_Version_2.02.03_1"></a><a name="_Latest_Version_2.02.05"></a><a <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><span lang=EN-US>Latest Version 2.02.06 name="_Latest_Version_2.02.06"></a><a name="_Latest_Version_2.02.07"></a><span
November 2022</span></h1> lang=EN-US>Latest Version 2.02.07 January 2023</span></h1>
<h2><span lang=EN-US>Bug Fixes</span></h2>
<p class=MsoNormal><span lang=EN-US>Use of localization sensor and orientation data
for static hydrophones had a bug whereby it would continually forget angle
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
selection options even if no species classification options are in place. </span></p>
<p class=MsoNormal><span lang=EN-US>Fixed Landmarks: Earlier versions were
losing these every time PAMGuard started or new data were loaded in viewer
mode. Now fixed. </span></p>
<p class=MsoNormal><span lang=EN-US>ROCCA: Fixed (another) memory leak which
caused PAMGuard to crash when processing large data sets with the ROCCA
classifier. </span></p>
<p class=MsoNormal><span lang=EN-US>Ishmael Modules: Fixed bug which
occasionally caused crashes when processing many files offline. </span></p>
<p class=MsoNormal><span lang=EN-US>PAMDog: Fixed bug in watchdog program which
was trying to start PAMGuard before modules were fully loaded. The watchdog now
correctly waits until modules are loaded before attempting to start PAMGuard
processing.</span></p>
<h2><span lang=EN-US>New Features</span></h2>
<p class=MsoNormal><span lang=EN-US>New sound type for simulated sounds which
generates random chirps between around 200 and 800Hz, roughly the frequency
youd expect sound from higher frequency baleen whales, such as humpbacks, to
vocalise at. &nbsp;&nbsp;</span></p>
<p class=MsoNormal><span lang=EN-US>Hiding tool tips. A menu item to
permanently turn off all tool tips, or tap the Esc key to turn them off for 6
seconds if they are getting in the way, particularly when trying to interact
with displays using the mouse. </span></p>
<h1><span lang=EN-US>Version 2.02.06 November 2022</span></h1>
<h2><span lang=EN-US>Bug Fixes</span></h2> <h2><span lang=EN-US>Bug Fixes</span></h2>
@ -488,10 +530,10 @@ system to have nested classifiers which can be enabled or disabled. </span></p>
<p class=MsoNormal><span lang=EN-US>Changes to classification GUI to <p class=MsoNormal><span lang=EN-US>Changes to classification GUI to
accommodate the new classification system.</span></p> accommodate the new classification system.</span></p>
<p class=MsoNormal><span lang=EN-US>Addition of data selectors to the minimum number <p class=MsoNormal><span lang=EN-US>Addition of data selectors to the minimum
of clicks accepted by the classifier. This allows the click-by-click classifier number of clicks accepted by the classifier. This allows the click-by-click
and the click train detector to be used to together to improve classification classifier and the click train detector to be used to together to improve
accuracy. </span></p> classification accuracy. </span></p>
<p class=MsoNormal><b><span lang=EN-US>Bug fixes</span></b></p> <p class=MsoNormal><b><span lang=EN-US>Bug fixes</span></b></p>
@ -710,8 +752,9 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nb
lang=EN-US> </span>Extended XML-output support to all of the modules </p> lang=EN-US> </span>Extended XML-output support to all of the modules </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>8. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>8. </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
Updates to the simulated sounds in the Sound Acquisition module </p> lang=EN-US> </span>Updates to the simulated sounds in the Sound Acquisition
module </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>9. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>9. </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
@ -749,9 +792,9 @@ 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 (currently the GPL, Click Detector and Whistle and Moan Detector) are outputting
outputting additional noise metrics to their binary output files. These can be additional noise metrics to their binary output files. These can be read with
read with the <a href="https://sourceforge.net/projects/pamguard/files/Matlab/">PAMGuard 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. Improved displays within PAMGuard for these noise metrics will be conditions. Improved displays within PAMGuard for these noise metrics will be
included in a future release. </p> included in a future release. </p>
@ -759,10 +802,10 @@ included in a 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>
An implementation of the Generalized Power Law Detector, developed by Tyler An implementation of the Generalized Power Law Detector, developed by Tyler
Helble ([Helble et al., ‘A generalized power-law detection algorithm for Helble ([Helble et al., ÃÂA generalized power-law detection algorithm for humpback
humpback whale vocalizations’, The Journal of the Acoustical Society of whale vocalizationsÃÂ, The Journal of the Acoustical Society of America, vol.
America, vol. 131, no. 4, pp. 2682–2699, 2012) is now available. For 131, no. 4, pp. 2682ÃÂ2699, 2012) is now available. For details, see the
details, see the online help </p> 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>
@ -1021,17 +1064,18 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nb
Add 3D map for target motion module. </p> Add 3D map for target motion module. </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><span
Add option to alarm module to attach screenshots of all frames to email alerts. lang=EN-US> </span>Add option to alarm module to attach screenshots of all
</p> frames to email alerts. </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>
Add Beamformer and Bearing Localiser modules </p> Add Beamformer and Bearing Localiser modules </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>8. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>8. </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 Global Medium Manager, to switch between air and water mediums </p> lang=EN-US> </span>Added Global Medium Manager, to switch between air and water
mediums </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>9. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>9. </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>
@ -1055,9 +1099,10 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nb
lang=EN-US> </span>Added ctrl-p hotkey to print-screen button. </p> lang=EN-US> </span>Added ctrl-p hotkey to print-screen button. </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><span
Update simulated daq so that it generates new random noise correctly on each lang=EN-US> </span>Update simulated daq so that it generates new random noise
call rather then recycling old data. Makes the output more spectrally flat. </p> correctly on each call rather then recycling old data. Makes the output more
spectrally flat. </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>
@ -1069,10 +1114,11 @@ placement, etc.</p>
<h1><a name="_Latest_Beta_Version_2.01.03"></a><span lang=EN-US>Version 2.01.03 <h1><a name="_Latest_Beta_Version_2.01.03"></a><span lang=EN-US>Version 2.01.03
February 2020</span></h1> February 2020</span></h1>
<p class=MsoNormal><b>If you are upgrading from a PAMGuard core release (1.15.xx), <p class=MsoNormal><b>If you are upgrading from a PAMGuard core release
PAMGuard Version 2 contains major updates. You should read and understand the (1.15.xx), PAMGuard Version 2 contains major updates. You should read and
notes listed for <a href="#_Latest_Beta_Version_2.00.10">Beta Version 2.00.10</a> understand the notes listed for <a href="#_Latest_Beta_Version_2.00.10">Beta
before proceeding with installation and use of this version.</b></p> Version 2.00.10</a> before proceeding with installation and use of this
version.</b></p>
<p class=MsoNormal>This version of PAMGuard has been bundled with Java 13 <p class=MsoNormal>This version of PAMGuard has been bundled with Java 13
(release 13.0.1). PSFX files generated in previous beta releases (2.xx.xx) (release 13.0.1). PSFX files generated in previous beta releases (2.xx.xx)
@ -1123,8 +1169,8 @@ Bug 441. Plot coordinate calculations incorrect in PamAxis.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>10. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>10. </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>Bug 442. BT Display does not change click symbol color when lang=EN-US> </span>Bug 442. BT Display does not change click symbol color when Colour
Colour By Superdetection is selected.</p> By Superdetection is selected.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>11. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>11. </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
@ -1137,9 +1183,9 @@ Bug 444. Bug in data selector which caused it to mess up history of recent psf
files.</p> files.</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
Bug 445. Overlay data in FX spectrogram display gets out of sync with underlying lang=EN-US> </span>Bug 445. Overlay data in FX spectrogram display gets out of
spectrogram image.</p> sync with underlying spectrogram image.</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>
@ -1148,8 +1194,7 @@ Spectrogram display.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>15. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>15. </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>
Bug 447. Viewer mode throws exception when trying to load beamformer Bug 447. Viewer mode throws exception when trying to load beamformer localisations</p>
localisations</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><span lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
@ -1162,8 +1207,8 @@ Bug 449. Rocca Encounter Stats output file calculating incorrect values.</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><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>Bug 450. Ishmael Detectors subscribing to FFTDataBlock lang=EN-US> </span>Bug 450. Ishmael Detectors subscribing to FFTDataBlock twice,
twice, meaning they process each data unit 2x doubling the output.</p> meaning they process each data unit 2x doubling the output.</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>
@ -1173,9 +1218,9 @@ lang=EN-US> </span>Added functionality to TD display to allow users to manually
classify clicks. </p> classify clicks. </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 option in Sound Acquisition settings dialog to override filename time lang=EN-US> </span>Added option in Sound Acquisition settings dialog to
stamp and use PC local time instead. </p> override filename time stamp and use PC local time instead. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3. </span><span <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
@ -1251,9 +1296,9 @@ with installation and use of this version.</span></p>
<p class=MsoNormal><b><span lang=EN-US>Bug Fixes</span></b></p> <p class=MsoNormal><b><span lang=EN-US>Bug Fixes</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
Bug 427. Soundtrap import not closing binary files properly if BCL files do not lang=EN-US> </span>Bug 427. Soundtrap import not closing binary files properly
contain off-effort 'E' line</p> if BCL files do not contain off-effort 'E' line</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>
@ -1393,9 +1438,9 @@ lang=EN-US> </span>Added adaptive noise filter to Ishmael Detectors.</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><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>Many upgrades to the Sound Playback module, including a lang=EN-US> </span>Many upgrades to the Sound Playback module, including a
high-pass filter, gain control, and the ability to mix wavefrom and envelope data high-pass filter, gain control, and the ability to mix wavefrom and envelope
together to listen to high-frequency clicks and dolphin whistles at the same data together to listen to high-frequency clicks and dolphin whistles at the
time.</p> same time.</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>
@ -1498,9 +1543,9 @@ Improvements to Difar module graphics - easier reading, better visibility at
night.</p> night.</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
Added print screen button to capture/save all PAMGuard screens to file and log lang=EN-US> </span>Added print screen button to capture/save all PAMGuard
the information to the database.</p> screens to file and log the information to the database.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>8. </span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>8. </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>
@ -1551,17 +1596,17 @@ lang=EN-US> </span>Added decimal degrees option to latitude/longitude dialog.</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>Added option in the Click Delay parameters to restrict the lang=EN-US> </span>Added option in the Click Delay parameters to restrict the number
number of initial samples used in the calculation. This can be useful for of initial samples used in the calculation. This can be useful for cleaning up
cleaning up delays in the presence of echoes and small time delays.</p> delays in the presence of echoes and small time delays.</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>
Increased upsampling to 2, 3 or 4 times.</p> Increased upsampling to 2, 3 or 4 times.</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> lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span
Can now change units and scale type in level meter display.</p> lang=EN-US> </span>Can now change units and scale type in level meter display.</p>
<!-- ************************************************************************************************************************** --><!-- ************************************************************************************************************************** --> <!-- ************************************************************************************************************************** --><!-- ************************************************************************************************************************** -->
@ -1926,8 +1971,8 @@ User is now able to specify Soundtrap date/time format</p>
<h1><a name="_Latest_Beta_Version_2.00.11"></a><span lang=EN-US>Beta Version <h1><a name="_Latest_Beta_Version_2.00.11"></a><span lang=EN-US>Beta Version
2.00.11 October 2017</span></h1> 2.00.11 October 2017</span></h1>
<p class=MsoNormal><span lang=EN-US>PAMGuard Version 2 contains major updates. <p class=MsoNormal><span lang=EN-US>PAMGuard Version 2 contains major updates. You
You should read and understand the notes listed for <a should read and understand the notes listed for <a
href="#_Latest_Beta_Version_2.00.10">Beta Version 2.00.10</a> before proceeding href="#_Latest_Beta_Version_2.00.10">Beta Version 2.00.10</a> before proceeding
with installation and use of this version.</span></p> with installation and use of this version.</span></p>
@ -1998,9 +2043,9 @@ lang=EN-US> </span>Added 3D rotation to map display. Hold down the shift key
while clicking and dragging on the map to see this in action. </p> while clicking and dragging on the map to see this in action. </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><span
Added database logging and other updates to the Click Detector trigger function lang=EN-US> </span>Added database logging and other updates to the Click
</p> Detector trigger function </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>
@ -2081,8 +2126,8 @@ to colour them by the colour assigned to the group. </span></p>
<h3><span lang=EN-US>Using Old PAMGuard Configurations</span></h3> <h3><span lang=EN-US>Using Old PAMGuard Configurations</span></h3>
<p class=MsoNormal><span lang=EN-US>Old PAMGuard configurations will work with <p class=MsoNormal><span lang=EN-US>Old PAMGuard configurations will work with the
the new version. However please note the following:</span></p> new version. However please note the following:</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>1.</span><span lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lang=EN-US>1.</span><span lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -2091,10 +2136,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 </span><span lang=EN-US>Display colour options will be lost and most data displayed
displayed on the map may default to black. This is due to the above changes to on the map may default to black. This is due to the above changes to how
how colours are managed. Changing back to the colours of your choice is colours are managed. Changing back to the colours of your choice is relatively
relatively simple through the PAMGuard GUI. </span></p> 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>
@ -2108,8 +2153,8 @@ lang=EN-US>&nbsp;</span></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 317. Rocca Module Data Purging. </span>The ROCCA module </span><span lang=EN-US>Bug 317. Rocca Module Data Purging. </span>The ROCCA
was not performing data purging when using classifiers developed for module was not performing data purging when using classifiers developed for
Hawaii/Temperate Pacific/North Atlantic datasets. This has been corrected.</p> Hawaii/Temperate Pacific/North Atlantic datasets. This has been corrected.</p>
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2.</span><span <p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2.</span><span
@ -2156,8 +2201,8 @@ list grew to a ridiculous size. Code has been put in place to a) stop it
happening again and b) to repair any configuration files which are corrupted. happening again and b) to repair any configuration files which are corrupted.
Corrupted files will be slow to load, slow to save and will be &gt; several Corrupted files will be slow to load, slow to save and will be &gt; several
megabytes in size. It may be necessary to delete the PamguardSettings table in megabytes in size. It may be necessary to delete the PamguardSettings table in
any databases since these too may have become oversized which will slow down viewer any databases since these too may have become oversized which will slow down
mode PAMGuard start-up.</p> viewer mode PAMGuard start-up.</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;
@ -2418,8 +2463,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 analysis. This means than when reviewing data offline, the tracks created in real
real time are now available for review and further analysis. </span></p> 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;
@ -2462,15 +2507,15 @@ memory that needed to be cleaned up). In some circumstances, these pauses were
making data acquisition systems unstable. We have therefore entirely rewritten making data acquisition systems unstable. We have therefore entirely rewritten
the way in which PAMGuard handles arrays of spectrogram data (complex numbers) the way in which PAMGuard handles arrays of spectrogram data (complex numbers)
so that instead of large numbers of small Java objects there are now fewer, so that instead of large numbers of small Java objects there are now fewer,
larger, simpler java objects. These reduce processing delays for garbage collection larger, simpler java objects. These reduce processing delays for garbage
and give an overall speed improvement, but will otherwise not be noticed by collection and give an overall speed improvement, but will otherwise not be
users. </span></p> noticed by users. </span></p>
<p class=MsoNormal><i><span lang=EN-US>Click Detector RainbowClick file output</span></i></p> <p class=MsoNormal><i><span lang=EN-US>Click Detector RainbowClick file output</span></i></p>
<p class=MsoNormal><span lang=EN-US>This feature has been removed since it has <p class=MsoNormal><span lang=EN-US>This feature has been removed since it has
been obsolete for several years. Users should use the PAMGuard binary storage system been obsolete for several years. Users should use the PAMGuard binary storage
for Click Detector data. </span></p> system for Click Detector data. </span></p>
<h1><a name="_Latest_Version_1.15.04"></a><span lang=EN-US>Version 1.15.04 July <h1><a name="_Latest_Version_1.15.04"></a><span lang=EN-US>Version 1.15.04 July
2016</span></h1> 2016</span></h1>
@ -2605,8 +2650,8 @@ and datagram creation.</p>
<h1><a name="_Toc444450394"></a><span lang=EN-US>Version 1.15.00 February 2016</span></h1> <h1><a name="_Toc444450394"></a><span lang=EN-US>Version 1.15.00 February 2016</span></h1>
<p class=MsoNormal><span lang=EN-US>Beta Version 1.15.00 64 bit and Core version <p class=MsoNormal><span lang=EN-US>Beta Version 1.15.00 64 bit and Core
1.15.00 32 bit. Both using identical Java core software but linking to version 1.15.00 32 bit. Both using identical Java core software but linking to
different libraries for control of sound input devices. </span></p> different libraries for control of sound input devices. </span></p>
<p class=MsoNormal><span lang=EN-US>This is the first release of a 64 bit <p class=MsoNormal><span lang=EN-US>This is the first release of a 64 bit
@ -2688,8 +2733,8 @@ name="_Toc312065299"></a><a name="_Toc312063944"></a><a name="_Toc312065300"></a
name="_Toc312063945"></a>Version 1.14.00 Beta, September 2015</h1> name="_Toc312063945"></a>Version 1.14.00 Beta, September 2015</h1>
<p class=MsoNormal>The format of configuration files has changed for version <p class=MsoNormal>The format of configuration files has changed for version
1.14.00. Older configurations will load with this new version, but configurations 1.14.00. Older configurations will load with this new version, but
saved with 1.14.00 may not open correctly with earlier versions.</p> configurations saved with 1.14.00 may not open correctly with earlier versions.</p>
<p class=MsoNormal>PAMGuard Versions 1.14.00 and above will work with Java 8. <p class=MsoNormal>PAMGuard Versions 1.14.00 and above will work with Java 8.
PAMGuard will continue to work with Java 7, but support for Java 7 will be PAMGuard will continue to work with Java 7, but support for Java 7 will be
@ -2767,8 +2812,8 @@ events. </span></p>
<p class=MsoListParagraph style='margin-left:38.25pt;text-indent:-20.25pt'><span <p class=MsoListParagraph style='margin-left:38.25pt;text-indent:-20.25pt'><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;&nbsp; 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;&nbsp;
</span><span lang=EN-US>Bug 250. DIFAR module was crashing if it attempted to triangulate </span><span lang=EN-US>Bug 250. DIFAR module was crashing if it attempted to
between more than two simultaneous bearings. Fixed. </span></p> triangulate between more than two simultaneous bearings. Fixed. </span></p>
<p class=MsoListParagraph style='margin-left:38.25pt;text-indent:-20.25pt'><span <p class=MsoListParagraph style='margin-left:38.25pt;text-indent:-20.25pt'><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;&nbsp; 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;&nbsp;
@ -2869,11 +2914,11 @@ which is useful when using PAMGuard for demonstration purposes. </p>
<p class=MsoListParagraph style='margin-left:47.25pt;text-indent:-29.25pt'><span <p class=MsoListParagraph style='margin-left:47.25pt;text-indent:-29.25pt'><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span>The sound File and Folder audio input systems now have an optional time zone </span>The sound File and Folder audio input systems now have an optional time
setting. Note that PAMGuard analysis should still all be taking place in UTC zone setting. Note that PAMGuard analysis should still all be taking place in
and that this option is intended to allow the conversion of file times which UTC and that this option is intended to allow the conversion of file times
were not recorded as UTC into UTC and not the other way around. Use the option which were not recorded as UTC into UTC and not the other way around. Use the
with caution !</p> option with caution !</p>
<p class=MsoListParagraph style='margin-left:47.25pt;text-indent:-29.25pt'><span <p class=MsoListParagraph style='margin-left:47.25pt;text-indent:-29.25pt'><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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -2988,8 +3033,9 @@ total loss of the PAMGuard configuration in viewer mode and has been rectified.
7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>Bug 7.0pt;font-family:"Times New Roman",serif'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>Bug
218. SAIL Acquisition card would hang the system. This has also been fixed. </p> 218. SAIL Acquisition card would hang the system. This has also been fixed. </p>
<p class=MsoListParagraph style='text-indent:-18.0pt'>7.&nbsp;&nbsp;&nbsp; Bug 219. <p class=MsoListParagraph style='text-indent:-18.0pt'>7.&nbsp;&nbsp;&nbsp; Bug
Problems displaying Offline Click Events in the Viewer map have been fixed. </p> 219. Problems displaying Offline Click Events in the Viewer map have been
fixed. </p>
<p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>&nbsp;</p>
@ -3028,9 +3074,8 @@ 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 <p class=MsoNormal>The PAMGuard menus have been rearranged into a more intuitive
intuitive grouping which we believe will help users find functionality more grouping which we believe will help users find functionality more easily. </p>
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>
@ -3087,9 +3132,9 @@ sonobuoys. See online help for details.&nbsp; </p>
<p class=MsoNormal>This module, developed by Jamie Macaulay of St Andrews <p class=MsoNormal>This module, developed by Jamie Macaulay of St Andrews
University estimates the 3D localisation of clicks using a variety of University estimates the 3D localisation of clicks using a variety of
algorithms. It's primarily been developed to track harbour porpoise in three algorithms. It's primarily been developed to track harbour porpoise in three
dimensions over scales of 10's of metres. While currently only working with output dimensions over scales of 10's of metres. While currently only working with
from the click detector, we hope eventually to extend its use to whistles as output from the click detector, we hope eventually to extend its use to
well. </p> whistles as well. </p>
<p class=MsoNormal><i>Accelerometer Readout</i> (Sensors group)</p> <p class=MsoNormal><i>Accelerometer Readout</i> (Sensors group)</p>
@ -3159,10 +3204,11 @@ different. Details are available in the online help. </p>
<p class=MsoNormal><i>FLAC File Support</i></p> <p class=MsoNormal><i>FLAC File Support</i></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 algorithm href="http://en.wikipedia.org/wiki/FLAC">FLAC</a> is a lossless compression
for audio data. Files, or folders of files are accessed in the same way as WAV algorithm for audio data. Files, or folders of files are accessed in the same
and AIFF files in the Sound Acquisition module. In a future release we also way as WAV and AIFF files in the Sound Acquisition module. In a future release
hope to provide support for writing FLAC files from the sound recorder module. </p> we also hope to provide support for writing FLAC files from the sound recorder
module. </p>
<p class=MsoNormal><i>Sound Recorder Module</i></p> <p class=MsoNormal><i>Sound Recorder Module</i></p>
@ -3175,8 +3221,8 @@ Millisecond time is also now included in the output file names. </p>
<p class=MsoNormal>Datagram options in Viewer have been improved so that the <p class=MsoNormal>Datagram options in Viewer have been improved so that the
user has to verify the time binning for datagrams the first time the viewer is user has to verify the time binning for datagrams the first time the viewer is
run and can also change the time bins from the File menu (See the File/BinaryStore/Datagram run and can also change the time bins from the File menu (See the
options menu. </p> File/BinaryStore/Datagram options menu. </p>
<p class=MsoNormal><i>Viewer Configuration</i></p> <p class=MsoNormal><i>Viewer Configuration</i></p>
@ -3228,8 +3274,8 @@ whistle.</p>
longer possible to change configurations once PAMGuard has been launched longer possible to change configurations once PAMGuard has been launched
and pressing 'Cancel' on the select dialog causes PAMGuard to exit. </li> and pressing 'Cancel' on the select dialog causes PAMGuard to exit. </li>
<li class=MsoNormal style='margin-bottom:0cm'>Airgun display. If this was <li class=MsoNormal style='margin-bottom:0cm'>Airgun display. If this was
included in the PAMGuard model before the GPS module it would hang PAMGuard. included in the PAMGuard model before the GPS module it would hang
This has been rectified. </li> PAMGuard. This has been rectified. </li>
<li class=MsoNormal style='margin-bottom:0cm'>Fixed occasional exceptions in <li class=MsoNormal style='margin-bottom:0cm'>Fixed occasional exceptions in
the sound output modules when playing back from files. </li> the sound output modules when playing back from files. </li>
<li class=MsoNormal style='margin-bottom:0cm'>Fixed exceptions in spectrogram <li class=MsoNormal style='margin-bottom:0cm'>Fixed exceptions in spectrogram
@ -3242,8 +3288,8 @@ whistle.</p>
forms which did not display correctly in 'night' mode. </li> forms which did not display correctly in 'night' mode. </li>
<li class=MsoNormal style='margin-bottom:0cm'>Bug fix in simulator. No longer <li class=MsoNormal style='margin-bottom:0cm'>Bug fix in simulator. No longer
stops or fails to start generating sounds. </li> stops or fails to start generating sounds. </li>
<li class=MsoNormal style='margin-bottom:0cm'>Bug in calculated spectrum <li class=MsoNormal style='margin-bottom:0cm'>Bug in calculated spectrum levels
levels if data were decimated (<a if data were decimated (<a
href="http://sourceforge.net/p/pamguard/bugs/187/">http://sourceforge.net/p/pamguard/bugs/187/</a>) href="http://sourceforge.net/p/pamguard/bugs/187/">http://sourceforge.net/p/pamguard/bugs/187/</a>)
. Did not affect band level calculations. </li> . Did not affect band level calculations. </li>
<li class=MsoNormal style='margin-bottom:0cm'>Bug in noise band monitor. <li class=MsoNormal style='margin-bottom:0cm'>Bug in noise band monitor.
@ -3327,9 +3373,9 @@ databases.</p>
<p class=MsoNormal style='margin-left:36.0pt'>National Instruments cards: Added <p class=MsoNormal style='margin-left:36.0pt'>National Instruments cards: Added
code in support of the new x-series devices. </p> code in support of the new x-series devices. </p>
<p class=MsoNormal style='margin-left:36.0pt'>ASIO sound cards: Added support <p class=MsoNormal style='margin-left:36.0pt'>ASIO sound cards: Added support for
for a new open source ASIO driver system (jasiohost). The old system has been a new open source ASIO driver system (jasiohost). The old system has been left
left in place for now while we assess users response to the newer system. </p> in place for now while we assess users response to the newer system. </p>
<p class=MsoNormal style='margin-left:36.0pt'><i>AIS</i></p> <p class=MsoNormal style='margin-left:36.0pt'><i>AIS</i></p>
@ -3633,10 +3679,10 @@ source, even if that data source is loaded after the FFT module is created.</p>
<p class=MsoNormal>1. Binary storage module. </p> <p class=MsoNormal>1. Binary storage module. </p>
<p class=MsoNormal>Performs a parallel role to the PAMGAURD database but uses binary <p class=MsoNormal>Performs a parallel role to the PAMGAURD database but uses
files in a proprietary format which is considerably more efficient for data of binary files in a proprietary format which is considerably more efficient for
unknown length such as whistle contours or small clips of click waveform. This data of unknown length such as whistle contours or small clips of click
feature is currently implemented in the following modules:</p> waveform. This feature is currently implemented in the following 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;
@ -3757,8 +3803,8 @@ channels 0 and 1. Similarly if you switched sound cards, you may have to reconfi
every detector and several of the displays to handle the changes in channel every detector and several of the displays to handle the changes in channel
numbering. </p> numbering. </p>
<p class=MsoNormal>I have spent a considerable amount of time trying to work <p class=MsoNormal>I have spent a considerable amount of time trying to work out
out a better system for handling channel numbering in PAMGUARD and have decided a better system for handling channel numbering in PAMGUARD and have decided
that the only practical thing to do is to force all software channel numbering that the only practical thing to do is to force all software channel numbering
back to a zero indexed system. i.e. even if you read out hardware channels back to a zero indexed system. i.e. even if you read out hardware channels
3,4,5 and 6, within PAMGUARD, everywhere apart from the Sound acquisition 3,4,5 and 6, within PAMGUARD, everywhere apart from the Sound acquisition
@ -3887,8 +3933,8 @@ frequency versions of the click detector.</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>Note that this does not (yet) permit simultaneous acquisition and playback </span>Note that this does not (yet) permit simultaneous acquisition and
through</p> playback through</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;
@ -4049,9 +4095,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 </span>Channel lists in output data streams of Decimator and other modules fixed,
fixed, so that when channel numbers change, downstream modules configurations so that when channel numbers change, downstream modules configurations get the
get the correct list of available channels. </p> 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;
@ -4083,10 +4129,10 @@ 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>New menu functionality by right clicking on any of the tabs of the main </span>New menu functionality by right clicking on any of the tabs of the main
tab control will allow the user to copy the tab contents to the system clipboard tab control will allow the user to copy the tab contents to the system
from where it can be copied into other programs (e.g. Word, Powerpoint, clipboard from where it can be copied into other programs (e.g. Word,
etc.).Some modules, such as the map, have this implemented in other menus Powerpoint, etc.).Some modules, such as the map, have this implemented in other
(right click) and also allow printing.&nbsp; </p> menus (right click) and also allow printing.&nbsp; </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;
@ -4346,9 +4392,9 @@ a serial port </p>
<p class=MsoNormal>New Likelihood detector. </p> <p class=MsoNormal>New Likelihood detector. </p>
<p class=MsoNormal>The likelihood detector module is an implementation of a <p class=MsoNormal>The likelihood detector module is an implementation of a likelihood
likelihood ratio test with flexible algorithms and configuration to estimate ratio test with flexible algorithms and configuration to estimate likelihood.
likelihood. It is </p> It is </p>
<p class=MsoNormal>suitable for detecting both short duration Odontocete clicks <p class=MsoNormal>suitable for detecting both short duration Odontocete clicks
(Sperm, Beaked, etc.) as well as moderate duration Mysticete calls (Humpback, (Sperm, Beaked, etc.) as well as moderate duration Mysticete calls (Humpback,

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.06</version> <version>2.02.07b</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.06a</version> <version>2.02.07b</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

@ -950,15 +950,22 @@ public class AcquisitionProcess extends PamProcess {
/** /**
* Check it's a single channel and not a channel map. * Check it's a single channel and not a channel map.
* This fundamentally messed up the amplitude calculations when the
* channels were > 2 since it was only taking the number of the lowest set
* bit. So if a genuine channel was sent, rather than a channel map with a
* single set channel, it messed up. Have made this function redundant
* and we need to be 100% sure that all amplitude calculations are sent a
* channel number not a bitmap with a single set channel.
* @param channel * @param channel
* @return single channel if it seemed to be a bitmap. * @return single channel if it seemed to be a bitmap.
*/ */
private int checkSingleChannel(int channel) { private int checkSingleChannel(int channel) {
int bitCount = PamUtils.getNumChannels(channel);
if (bitCount > 1 || channel > 32) {
channel = PamUtils.getLowestChannel(channel);
}
return channel; return channel;
// int bitCount = PamUtils.getNumChannels(channel);
// if (bitCount > 1 || channel > 32) {
// channel = PamUtils.getLowestChannel(channel);
// }
// return channel;
} }
/** /**
@ -1022,7 +1029,7 @@ public class AcquisitionProcess extends PamProcess {
/** /**
* Prepares for fast amplitude calculations * Prepares for fast amplitude calculations
* @param channel * @param channel number i.e. 0 - 31, NOT a bitmap.
*/ */
public double prepareFastAmplitudeCalculation(int channel) { public double prepareFastAmplitudeCalculation(int channel) {
channel = checkSingleChannel(channel); channel = checkSingleChannel(channel);
@ -1035,7 +1042,7 @@ public class AcquisitionProcess extends PamProcess {
* for an array of double data * for an array of double data
* *
* @param rawAmplitude raw amplitude (should be -1 < rawAmplitude < 1) * @param rawAmplitude raw amplitude (should be -1 < rawAmplitude < 1)
* @param channel channel number (MUST be a channel, not a sequence number) * @param channel channel number (MUST be a channel 0 - 31, not a sequence number)
* @return amplitude in dB re 1 uPa. * @return amplitude in dB re 1 uPa.
*/ */
public double[] rawAmplitude2dB(double[] rawAmplitude, int channel){ public double[] rawAmplitude2dB(double[] rawAmplitude, int channel){
@ -1122,7 +1129,7 @@ public class AcquisitionProcess extends PamProcess {
/** /**
* Converts dB in micropascal to ADC counts on a 0 - 1 scale. * Converts dB in micropascal to ADC counts on a 0 - 1 scale.
* @param channel channel number. * @param channel channel number, i.e. channel index 0 - 31 NOT a bitmap.
* @param dBMuPascal db in micropascal * @param dBMuPascal db in micropascal
* @return ADC counts on a 0-1 scale. * @return ADC counts on a 0-1 scale.
*/ */

View File

@ -14,7 +14,7 @@ import org.codehaus.plexus.util.FileUtils;
* <p> * <p>
* PamAudioFieManager holds a list of PamAudioFile classes. Each PamAudioFile * PamAudioFieManager holds a list of PamAudioFile classes. Each PamAudioFile
* can open a certain type of sound file e.g. flac or raw wav files. * can open a certain type of sound file e.g. flac or raw wav files.
* PamAudioFieManager provides fucntions around the list to open files, provide * PamAudioFieManager provides functions around the list to open files, provide
* file filters etc. * file filters etc.
* *
* @author Jamie Macaulay * @author Jamie Macaulay
@ -81,8 +81,16 @@ public class PamAudioFileManager {
} }
public boolean isSoundFile(File soundFile, String soundExtension) { public boolean isSoundFile(File soundFile, String soundExtension) {
if (soundFile == null) {
return false;
}
String extension = FileUtils.getExtension(soundFile.getName()); String extension = FileUtils.getExtension(soundFile.getName());
if (extension == null) {
return false;
}
extension = extension.toLowerCase();
soundExtension = soundExtension.toLowerCase();
//System.out.println("Sound Extension: " + soundExtension + " File extension: " + extension); //System.out.println("Sound Extension: " + soundExtension + " File extension: " + extension);
return (soundExtension.equals(extension) || soundExtension.equals("." + extension)); return (soundExtension.equals(extension) || soundExtension.equals("." + extension));
} }

View File

@ -4,6 +4,8 @@ import GPS.NavDataSynchronisation;
import PamController.PamController; import PamController.PamController;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
import pamScrollSystem.ViewLoadObserver;
public class StreamerDataBlock extends PamDataBlock<StreamerDataUnit>{ public class StreamerDataBlock extends PamDataBlock<StreamerDataUnit>{
@ -92,4 +94,8 @@ public class StreamerDataBlock extends PamDataBlock<StreamerDataUnit>{
} }
} }
public boolean loadViewerData(OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) {
return super.loadViewerData(offlineDataLoadInfo, loadObserver);
}
} }

View File

@ -3,6 +3,8 @@ package Array;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Types; import java.sql.Types;
import Array.sensors.ArrayParameterType;
import Array.sensors.ArraySensorFieldType;
import Array.streamerOrigin.HydrophoneOriginMethod; import Array.streamerOrigin.HydrophoneOriginMethod;
import Array.streamerOrigin.HydrophoneOriginMethods; import Array.streamerOrigin.HydrophoneOriginMethods;
import Array.streamerOrigin.HydrophoneOriginSystem; import Array.streamerOrigin.HydrophoneOriginSystem;
@ -147,9 +149,16 @@ public class StreamerLogging extends SQLLogging {
* Enable orientation is not saved in the database. It is handy to switch between enabling and disabling orientation for all streamers. Therefore we use the default streamer * Enable orientation is not saved in the database. It is handy to switch between enabling and disabling orientation for all streamers. Therefore we use the default streamer
* in the array manager to determine if our saved streamers will use their orientation data or not. * in the array manager to determine if our saved streamers will use their orientation data or not.
*/ */
Streamer defualtStreamer=ArrayManager.getArrayManager().getCurrentArray().getStreamer(streamer.getStreamerIndex()); Streamer defaultStreamer=ArrayManager.getArrayManager().getCurrentArray().getStreamer(streamer.getStreamerIndex());
// if (defualtStreamer!=null) streamer.setEnableOrientation(ArrayManager.getArrayManager().getCurrentArray().getStreamer(streamer.getStreamerIndex()).isEnableOrientation()); // if (defualtStreamer!=null) streamer.setEnableOrientation(ArrayManager.getArrayManager().getCurrentArray().getStreamer(streamer.getStreamerIndex()).isEnableOrientation());
// else streamer.setEnableOrientation(true); // else streamer.setEnableOrientation(true);
if (defaultStreamer != null) {
ArraySensorFieldType[] fieldTypes = ArraySensorFieldType.values();
for (int i = 0; i < fieldTypes.length; i++) {
ArrayParameterType aType = defaultStreamer.getOrientationTypes(fieldTypes[i]);
streamer.setOrientationTypes(fieldTypes[i], aType);
}
}
StreamerDataUnit sdu = new StreamerDataUnit(timeMilliseconds, streamer); StreamerDataUnit sdu = new StreamerDataUnit(timeMilliseconds, streamer);
sdu.setDatabaseIndex(databaseIndex); sdu.setDatabaseIndex(databaseIndex);

View File

@ -159,22 +159,21 @@ public class TMGroupLocInfo implements GroupLocInfo {
private void copySubDetections(SuperDetection parentDataUnit, DetectionGroupOptions detectionGroupOptions) { private void copySubDetections(SuperDetection parentDataUnit, DetectionGroupOptions detectionGroupOptions) {
synchronized (parentDataUnit.getSubDetectionSyncronisation()) { ArrayList<PamDataUnit> subDets = parentDataUnit.getSubDetections();
int totalUnits = parentDataUnit.getSubDetectionsCount(); int totalUnits = subDets.size();
int keptUnits = totalUnits; int keptUnits = totalUnits;
if (detectionGroupOptions != null) { if (detectionGroupOptions != null) {
if (detectionGroupOptions.getMaxLocalisationPoints() == 0 || if (detectionGroupOptions.getMaxLocalisationPoints() == 0 ||
detectionGroupOptions.getMaxLocalisationPoints() < parentDataUnit.getSubDetectionsCount()) { detectionGroupOptions.getMaxLocalisationPoints() < parentDataUnit.getSubDetectionsCount()) {
keptUnits = detectionGroupOptions.getMaxLocalisationPoints(); keptUnits = detectionGroupOptions.getMaxLocalisationPoints();
}
}
subDetectionList = new Vector<>(keptUnits);
float keepRat = (float) (totalUnits-1) / (float) (keptUnits-1);
for (int i = 0; i < keptUnits; i++) {
int unitIndex = Math.round(i*keepRat);
subDetectionList.add(parentDataUnit.getSubDetection(unitIndex));
} }
} }
subDetectionList = new Vector<>(keptUnits);
float keepRat = (float) (totalUnits-1) / (float) (keptUnits-1);
for (int i = 0; i < keptUnits; i++) {
int unitIndex = Math.round(i*keepRat);
subDetectionList.add(subDets.get(unitIndex));
}
} }
@ -454,7 +453,7 @@ public class TMGroupLocInfo implements GroupLocInfo {
* The real word vectors are relative to the earth surface. Thus they are the bearings vectors * The real word vectors are relative to the earth surface. Thus they are the bearings vectors
* from an array, rotated by the true heading, pitch and roll of the array. * from an array, rotated by the true heading, pitch and roll of the array.
*/ */
protected void calculateWorldVectors() { protected void calculateWorldVectors() {
int nSubDetections=getDetectionCount(); int nSubDetections=getDetectionCount();
rawRealWorldVectors = new PamVector[nSubDetections][]; rawRealWorldVectors = new PamVector[nSubDetections][];
PamVector[] v; PamVector[] v;

View File

@ -111,15 +111,15 @@ public class GebcoNETCDF {
* @param bin * @param bin
* @return * @return
*/ */
double binToValue(double[] valueRange, int nBin, int bin) { double binToValue(double[] valueRange, int nBin, double bin) {
return valueRange[0] + (valueRange[1]-valueRange[0])*(double) bin / (double) (nBin-1); return valueRange[0] + (valueRange[1]-valueRange[0])*(double) bin / (double) (nBin);
} }
double latBinToValue(int latBin) { double latBinToValue(double latBin) {
return binToValue(latRange, nLat, latBin); return binToValue(latRange, nLat, latBin);
} }
double lonBinToValue(int lonBin) { double lonBinToValue(double lonBin) {
return binToValue(lonRange, nLon, lonBin); return binToValue(lonRange, nLon, lonBin);
} }
@ -131,9 +131,9 @@ public class GebcoNETCDF {
public MapRasterImage createImage(int[] latRangeBins, int[] lonRangeBins, ColourArray heightColours, ColourArray depthColours, int hop) { public MapRasterImage createImage(int[] latRangeBins, int[] lonRangeBins, ColourArray heightColours, ColourArray depthColours, int hop) {
latRangeBins[0] = Math.max(latRangeBins[0], 0); latRangeBins[0] = Math.max(latRangeBins[0], 0);
latRangeBins[1] = Math.min(latRangeBins[1], nLat-1); latRangeBins[1] = Math.min(latRangeBins[1], nLat);
lonRangeBins[0] = Math.max(lonRangeBins[0], 0); lonRangeBins[0] = Math.max(lonRangeBins[0], 0);
lonRangeBins[1] = Math.min(lonRangeBins[1], nLon-1); lonRangeBins[1] = Math.min(lonRangeBins[1], nLon);
hop = Math.max(1, hop); hop = Math.max(1, hop);
int nLatBins = (latRangeBins[1]-latRangeBins[0])/hop; int nLatBins = (latRangeBins[1]-latRangeBins[0])/hop;
int nLonBins = (lonRangeBins[1]-lonRangeBins[0])/hop; int nLonBins = (lonRangeBins[1]-lonRangeBins[0])/hop;
@ -184,9 +184,10 @@ public class GebcoNETCDF {
double[] latRange = new double[2]; double[] latRange = new double[2];
double[] lonRange = new double[2]; double[] lonRange = new double[2];
double[] edges = {-.5, +.5};
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
latRange[i] = latBinToValue(latRangeBins[i]); latRange[i] = latBinToValue(latRangeBins[i]+edges[i]);
lonRange[i] = lonBinToValue(lonRangeBins[i]); lonRange[i] = lonBinToValue(lonRangeBins[i]+edges[i]);
} }
return new MapRasterImage(latRange, lonRange, image); return new MapRasterImage(latRange, lonRange, image);
@ -233,11 +234,14 @@ public class GebcoNETCDF {
public static GebcoNETCDF makeGebcoNCDFFile(File ncFile) { public static GebcoNETCDF makeGebcoNCDFFile(File ncFile) {
if (ncFile.exists() == false) { if (ncFile.exists() == false) {
System.out.println("Bathymetry file " + ncFile.getAbsolutePath() + " cannot be found"); System.out.println("Bathymetry file " + ncFile.getAbsolutePath() + " cannot be found");
return null;
} }
NetcdfFile ncf; NetcdfFile ncf;
try { try {
ncf = new NetcdfFile(ncFile, true); ncf = new NetcdfFile(ncFile, true);
return new GebcoNETCDF(ncf); GebcoNETCDF gebcoRaster = new GebcoNETCDF(ncf);
// ncf.close();
return gebcoRaster;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -67,11 +67,11 @@ public class GridSwingPainter {
* now go back and recalculate the latlongs of those pixel values since * now go back and recalculate the latlongs of those pixel values since
* we need the lat longs of those bounds to be more precise. * we need the lat longs of those bounds to be more precise.
*/ */
double pixsOffs = -.5; double pixsOffs = 0;//-.5;
pLatMin = lat[0] + (lat[1]-lat[0]) * (double) (nLat-pyMax-pixsOffs) / (nLat-1); pLatMin = lat[0] + (lat[1]-lat[0]) * (double) (nLat-pyMax-pixsOffs) / (nLat);
pLatMax = lat[0] + (lat[1]-lat[0]) * (double) (nLat-pyMin-pixsOffs) / (nLat-1); pLatMax = lat[0] + (lat[1]-lat[0]) * (double) (nLat-pyMin-pixsOffs) / (nLat);
pLonMin = lon[0] + (lon[1]-lon[0]) * (double) (pxMin+pixsOffs) / (nLon-1); pLonMin = lon[0] + (lon[1]-lon[0]) * (double) (pxMin+pixsOffs) / (nLon);
pLonMax = lon[0] + (lon[1]-lon[0]) * (double) (pxMax+pixsOffs) / (nLon-1); pLonMax = lon[0] + (lon[1]-lon[0]) * (double) (pxMax+pixsOffs) / (nLon);
// pxMin = Math.max(0, Math.min(pxMin, lon.length-1)); // pxMin = Math.max(0, Math.min(pxMin, lon.length-1));
// pxMax = Math.max(0, Math.min(pxMax, lon.length-1)); // pxMax = Math.max(0, Math.min(pxMax, lon.length-1));
// pyMin = Math.max(0, Math.min(pyMin, lat.length-1)); // pyMin = Math.max(0, Math.min(pyMin, lat.length-1));

View File

@ -260,11 +260,6 @@ public class PamController implements PamControllerInterface, PamSettings {
new MultiportController(this); new MultiportController(this);
} }
// binaryStore = new BinaryStore(this);
ToolTipManager.sharedInstance().setDismissDelay(20000);
guiFrameManager = PamGUIManager.createGUI(this, object); guiFrameManager = PamGUIManager.createGUI(this, object);
guiFrameManager.init(); //perform any start up processes for the GUI. guiFrameManager.init(); //perform any start up processes for the GUI.

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.06a"; static public final String version = "2.02.07b";
/** /**
* Release date * Release date
*/ */
static public final String date = "15 November 2022"; static public final String date = "19 January 2023";
// /** // /**
// * Release type - Beta or Core // * Release type - Beta or Core

View File

@ -247,15 +247,15 @@ public class SelectFolder {
folderName.setColumns(textLength); folderName.setColumns(textLength);
} }
// public boolean isShowSubFolderOption() { public boolean isShowSubFolderOption() {
// return showSubFolderOption; return showSubFolderOption;
// } }
//
//
// public void setShowSubFolderOption(boolean showSubFolderOption) { public void setShowSubFolderOption(boolean showSubFolderOption) {
// this.showSubFolderOption = showSubFolderOption; this.showSubFolderOption = showSubFolderOption;
// setVisibleControls(); setVisibleControls();
// } }
private void setVisibleControls() { private void setVisibleControls() {
includeSubFoldersCheckBox.setVisible(showSubFolderOption); includeSubFoldersCheckBox.setVisible(showSubFolderOption);

View File

@ -91,6 +91,7 @@ public class ColourScheme implements Serializable, Cloneable {
} }
// avoid overflows. // avoid overflows.
int nCol = whaleColors.length - 1; int nCol = whaleColors.length - 1;
// iCol = Math.abs(iCol);
iCol = ((iCol-1)%nCol) + 1; iCol = ((iCol-1)%nCol) + 1;
if (iCol < 0) { if (iCol < 0) {
return whaleColors[0]; return whaleColors[0];

View File

@ -30,6 +30,12 @@ public class GuiParameters implements Serializable, Cloneable {
private String currentSelectedTab; private String currentSelectedTab;
/**
* Flag to hide all tool tips - which are
* very annoying when they cover controls you want to use!
*/
private boolean hideAllToolTips = false;
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#clone() * @see java.lang.Object#clone()
@ -60,5 +66,21 @@ public class GuiParameters implements Serializable, Cloneable {
public void setCurrentSelectedTab(String currentSelectedTab) { public void setCurrentSelectedTab(String currentSelectedTab) {
this.currentSelectedTab = currentSelectedTab; this.currentSelectedTab = currentSelectedTab;
} }
/**
* @return the hideAllToolTips
*/
public boolean isHideAllToolTips() {
return hideAllToolTips;
}
/**
* @param hideAllToolTips the hideAllToolTips to set
*/
public void setHideAllToolTips(boolean hideAllToolTips) {
this.hideAllToolTips = hideAllToolTips;
}
} }

View File

@ -23,10 +23,13 @@ package PamView;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Desktop; import java.awt.Desktop;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Frame; import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.KeyEventDispatcher;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
@ -34,6 +37,8 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter; import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
@ -46,6 +51,7 @@ import java.net.URL;
import java.util.List; import java.util.List;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel; import javax.swing.JLabel;
@ -57,6 +63,8 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.ToolTipManager;
import javax.swing.WindowConstants; import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
@ -138,7 +146,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
removeModuleEnabler = new MenuItemEnabler(); removeModuleEnabler = new MenuItemEnabler();
orderModulesEnabler = new MenuItemEnabler(); orderModulesEnabler = new MenuItemEnabler();
frame = new JFrame(getModeName()); frame = new MainFrame(getModeName());
if (FullScreen.isGoFullScreen()) { if (FullScreen.isGoFullScreen()) {
// frame.setUndecorated(true); // frame.setUndecorated(true);
@ -176,6 +184,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
frame.setExtendedState(Frame.MAXIMIZED_BOTH); frame.setExtendedState(Frame.MAXIMIZED_BOTH);
frame.addWindowListener(this); frame.addWindowListener(this);
mainPanel = new PamBorderPanel(new BorderLayout()); mainPanel = new PamBorderPanel(new BorderLayout());
mainPanel.setOpaque(true); mainPanel.setOpaque(true);
@ -250,10 +259,52 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
frame.setExtendedState(guiParameters.extendedState); frame.setExtendedState(guiParameters.extendedState);
frame.setVisible(true); frame.setVisible(true);
hideToolTips(guiParameters.isHideAllToolTips());
ToolTipManager.sharedInstance().setDismissDelay(20000);
// ToolTipManager.sharedInstance().setReshowDelay(5000);
// System.out.println("Tool tip : getReshowDelay" + ToolTipManager.sharedInstance().getReshowDelay());
// System.out.println("Tool tip : getInitialDelay" + ToolTipManager.sharedInstance().getInitialDelay());
// System.out.println("Tool tip : getDismissDelay" + ToolTipManager.sharedInstance().getDismissDelay());
somethingShowing = true; somethingShowing = true;
} }
private class MainFrame extends JFrame implements KeyEventDispatcher {
private static final long serialVersionUID = 1L;
private Timer noTipTimer;
public MainFrame(String title) throws HeadlessException {
super(title);
DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this);
noTipTimer = new Timer(6000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hideToolTips(guiParameters.isHideAllToolTips());
noTipTimer.stop();
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
if (noTipTimer.isRunning()) {
noTipTimer.restart();
}
else {
noTipTimer.start();
}
hideToolTips(true);
}
return false;
}
}
private static volatile boolean somethingShowing = false; private static volatile boolean somethingShowing = false;
@ -819,6 +870,12 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
menuItem.setToolTipText("Warnings told \"Not to show again\" will be shown again"); menuItem.setToolTipText("Warnings told \"Not to show again\" will be shown again");
menuItem.addActionListener(new ClearHiddenWarnings()); menuItem.addActionListener(new ClearHiddenWarnings());
menu.add(menuItem); menu.add(menuItem);
JCheckBoxMenuItem hideTips = new JCheckBoxMenuItem("Hide all tool tips", guiParameters.isHideAllToolTips());
hideTips.setToolTipText("<html>Hide annoying pop-up tool tips which keep getting in the way" +
"<br>(or press the Escape key to hide them for 6 seconds)</html>");
hideTips.addActionListener(new HideToolTips(hideTips));
menu.add(hideTips);
/* /*
* Add menu item to redirect output to file or console screen * Add menu item to redirect output to file or console screen
@ -1173,6 +1230,32 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
} }
} }
private class HideToolTips implements ActionListener {
private JCheckBoxMenuItem hideTipsCheckbox;
public HideToolTips(JCheckBoxMenuItem hideTips) {
this.hideTipsCheckbox = hideTips;
}
@Override
public void actionPerformed(ActionEvent e) {
boolean shouldHide = !guiParameters.isHideAllToolTips();
hideToolTips(shouldHide);
guiParameters.setHideAllToolTips(shouldHide);
hideTipsCheckbox.setSelected(shouldHide);
}
}
/**
* hide all tool tips
* @param hide
*/
private void hideToolTips(boolean hide) {
ToolTipManager.sharedInstance().setEnabled(!hide);
}
class ClearHiddenWarnings implements ActionListener { class ClearHiddenWarnings implements ActionListener {
public void actionPerformed(ActionEvent ev){ public void actionPerformed(ActionEvent ev){
WarnOnce.clearHiddenList(getGuiFrame()); WarnOnce.clearHiddenList(getGuiFrame());
@ -1250,11 +1333,11 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
/** /**
* Rewrote the menu enablers for the Logging menu (and made it more general * Rewrote the menu enablers for the Logging menu (and made it more general
* to extend to other menus shoule they ever need to be anabled. * to extend to other menus should they ever need to be enabled).
* *
* This arises now that we have multiple main menus on the frame depending on * This arises now that we have multiple main menus on the frame depending on
* which tab is being viewed. Since each menu bar has references to different * which tab is being viewed. Since each menu bar has references to different
* menus and menu items, we can no lnger use the ones set in the constuctors for * menus and menu items, we can no longer use the ones set in the constructors for
* the menu. Each item is therefore found by name before it's enabled. For now * the menu. Each item is therefore found by name before it's enabled. For now
* I'm taking the names out of the reference to the last menu item. * I'm taking the names out of the reference to the last menu item.
* *
@ -1778,7 +1861,6 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
*/ */
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
guiParameters = ((GuiParameters) pamControlledUnitSettings.getSettings()).clone(); guiParameters = ((GuiParameters) pamControlledUnitSettings.getSettings()).clone();
return true; return true;
} }
public PamTabbedPane getMainTab() { public PamTabbedPane getMainTab() {

View File

@ -1237,7 +1237,7 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
if (offlineDataLoading.isCurrentOfflineLoadKeep()) { if (offlineDataLoading.isCurrentOfflineLoadKeep()) {
pamDataUnits.add(pamDataUnit); pamDataUnits.add(pamDataUnit);
} }
if (shouldBinary && getBinaryDataSource() != null && !isOffline) { if (shouldBinary && getBinaryDataSource() != null && !isOffline && pamDataUnit.isEmbryonic() == false) {
getBinaryDataSource().saveData(pamDataUnit); getBinaryDataSource().saveData(pamDataUnit);
} }
} }
@ -1311,8 +1311,14 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
public void updatePamData(Tunit pamDataUnit, long updateTimeMillis) { public void updatePamData(Tunit pamDataUnit, long updateTimeMillis) {
pamDataUnit.updateDataUnit(updateTimeMillis); pamDataUnit.updateDataUnit(updateTimeMillis);
setChanged(); setChanged();
if (!isOffline) { if (!isOffline && pamDataUnit.isEmbryonic() == false) {
if (getBinaryDataSource() != null && getBinaryDataSource().isSaveUpdates()) { /*
* Save it if it't not been saved already or we're saving updates.
* Detectors can keep a dataunit in an embryonic state and add them to the
* datablock so they get displayed, but they will still save when the embryonic
* flag is set false and an update is sent.
*/
if (getBinaryDataSource() != null && (getBinaryDataSource().isSaveUpdates() || pamDataUnit.getDataUnitFileInformation() == null)) {
getBinaryDataSource().saveData(pamDataUnit); getBinaryDataSource().saveData(pamDataUnit);
} }
} }

View File

@ -150,6 +150,13 @@ abstract public class PamDataUnit<T extends PamDataUnit, U extends PamDataUnit>
*/ */
private boolean forceAmpRecalc = false; private boolean forceAmpRecalc = false;
/**
* Flag to say that this is data under development. If this is set true
* then when the data are added to the datablock, they will not get saved
* to the binary store. They will get saved on the first update AFTER the
* embryonic flag is set false.
*/
private boolean embryonic = false;
/** /**
@ -1689,6 +1696,27 @@ abstract public class PamDataUnit<T extends PamDataUnit, U extends PamDataUnit>
* @return any integer. * @return any integer.
*/ */
public int getColourIndex() { public int getColourIndex() {
return (int) getUID(); /*
* This can go wrong when UID > 2^31 since the colour chooser takes
* a mod WRT number of whale colours and it doesn't like negative numbers.
* So need to keep the value going in positive.
*/
long uid = getUID();
uid &= 0x7FFFFFFF; // avoid anything in top bit of an int32 or higher
return (int) uid;
}
/**
* @return the embryonic
*/
public boolean isEmbryonic() {
return embryonic;
}
/**
* @param embryonic the embryonic to set
*/
public void setEmbryonic(boolean embryonic) {
this.embryonic = embryonic;
} }
} }

View File

@ -368,7 +368,7 @@ public class SuperDetDataBlock<Tunit extends SuperDetection, TSubDet extends Pam
} }
if (!found) { if (!found) {
superDet = null; superDet = null;
System.out.printf("Can't find data unit id %d, UID %d in %s\n", superID, superUID, getDataName()); Debug.out.printf("Can't find data unit id %d, UID %d in %s\n", superID, superUID, getDataName());
} }
} }
if (superDet == null) { if (superDet == null) {
@ -448,6 +448,9 @@ public class SuperDetDataBlock<Tunit extends SuperDetection, TSubDet extends Pam
int iDone = 0; int iDone = 0;
while (duIt.hasNext()) { while (duIt.hasNext()) {
Tunit aData = duIt.next(); // looping through superdetections. Tunit aData = duIt.next(); // looping through superdetections.
// if (aData.getDatabaseIndex() == 131) {
// System.out.println("On event 131");
// }
if (viewLoadObserver != null) { if (viewLoadObserver != null) {
viewLoadObserver.sayProgress(1, aData.getTimeMilliseconds(), firstTime, lastTime, iDone++); viewLoadObserver.sayProgress(1, aData.getTimeMilliseconds(), firstTime, lastTime, iDone++);
} }
@ -479,6 +482,7 @@ public class SuperDetDataBlock<Tunit extends SuperDetection, TSubDet extends Pam
sdInfo.setSubDetection(null); sdInfo.setSubDetection(null);
} }
} }
// aData.weedMissingSubDetections();
} }
} }
return true; return true;

View File

@ -278,23 +278,28 @@ public class SuperDetection<T extends PamDataUnit> extends PamDataUnit<T, SuperD
* @return an array list of sub detection data units * @return an array list of sub detection data units
*/ */
public ArrayList<PamDataUnit<?,?>> getSubDetections() { public ArrayList<PamDataUnit<?,?>> getSubDetections() {
if (subDetections == null) { synchronized (getSubDetectionSyncronisation()) {
return null; if (subDetections == null) {
} return null;
ArrayList<PamDataUnit<?,?>> subDets = new ArrayList<>(getSubDetectionsCount());
for (SubdetectionInfo<T> subInfo:subDetections) {
T subDet = subInfo.getSubDetection();
if (subDet == null) {
continue;
} }
subDets.add(subDet); ArrayList<PamDataUnit<?,?>> subDets = new ArrayList<>(getSubDetectionsCount());
for (SubdetectionInfo<T> subInfo:subDetections) {
T subDet = subInfo.getSubDetection();
if (subDet == null) {
continue;
}
subDets.add(subDet);
}
return subDets;
} }
return subDets;
} }
public T getSubDetection(int ind) { public T getSubDetection(int ind) {
synchronized (subDetectionSyncronisation) { synchronized (subDetectionSyncronisation) {
if (subDetections == null) return null; if (subDetections == null) return null;
if (ind >= subDetections.size()) {
return null;
}
return subDetections.get(ind).getSubDetection(); return subDetections.get(ind).getSubDetection();
} }
} }
@ -351,10 +356,15 @@ public class SuperDetection<T extends PamDataUnit> extends PamDataUnit<T, SuperD
if (subDetections == null) { if (subDetections == null) {
return null; return null;
} }
for (int i=0; i<subDetections.size(); i++) { synchronized (subDetectionSyncronisation) {
T aSub = subDetections.get(i).getSubDetection(); for (int i=0; i<subDetections.size(); i++) {
if (aSub.getUID() == UID) { T aSub = subDetections.get(i).getSubDetection();
return aSub; if (aSub == null) {
continue;
}
if (aSub.getUID() == UID) {
return aSub;
}
} }
} }
return null; return null;
@ -479,6 +489,24 @@ public class SuperDetection<T extends PamDataUnit> extends PamDataUnit<T, SuperD
// } // }
} }
/**
* Get a list of sub detections which are actually present.
* @return list of sub detections which have a non-null sub data unit.
*/
public List<SubdetectionInfo<T>> getPresentSubDetections() {
ArrayList<SubdetectionInfo<T>> exList = new ArrayList<>(getSubDetectionsCount());
synchronized (getSubDetectionSyncronisation()) {
for (SubdetectionInfo<T> subInf : subDetections) {
if (subInf.getSubDetection() == null) {
continue;
}
exList.add(subInf);
}
exList.trimToSize();
}
return exList;
}
/** /**
* Get the full list of subdetection info's (which may not all * Get the full list of subdetection info's (which may not all
@ -545,4 +573,21 @@ public class SuperDetection<T extends PamDataUnit> extends PamDataUnit<T, SuperD
} }
} }
/**
* Remove sub detection infos which have no actual sub detection
* loaded. Don't use since super dets are supposed to keep the full
* list even if they don't have loaded subdets.
*/
// public void weedMissingSubDetections() {
// synchronized (getSubDetectionSyncronisation()) {
// ListIterator<SubdetectionInfo<T>> subInfIter = subDetections.listIterator();
// while (subInfIter.hasNext()) {
// SubdetectionInfo<T> subDetInfo = subInfIter.next();
// if (subDetInfo.getSubDetection() == null) {
// subInfIter.remove();
// }
// }
// }
// }
} }

View File

@ -1422,6 +1422,7 @@ Text {
-color-cell-bg-odd: -color-bg-subtle; -color-cell-bg-odd: -color-bg-subtle;
-color-cell-border: -color-border-default; -color-cell-border: -color-border-default;
-fx-border-color: -color-cell-border; -fx-border-color: -color-cell-border;
-fx-control-inner-background: -color-bg-default;
-fx-border-width: 1px; -fx-border-width: 1px;
-fx-border-radius: 0; -fx-border-radius: 0;
-color-header-bg: -color-bg-subtle; -color-header-bg: -color-bg-subtle;
@ -3703,4 +3704,20 @@ Text {
#label-title2 { #label-title2 {
-fx-font: bold 13pt -fx-font-family; -fx-font: bold 13pt -fx-font-family;
}
/*******************************************************************************
* *
* Label *
* *
******************************************************************************/
.validatorfx-error {
-fx-text-fill: rgb(164, 0, 0);
}
.validatorfx-warning {
-fx-text-fill: rgb(196, 160, 0);
}
} }

View File

@ -27,7 +27,11 @@ public class SimpleAlarmCounter extends AlarmCounter {
@Override @Override
public double getValue(int countType, PamDataUnit dataUnit) { public double getValue(int countType, PamDataUnit dataUnit) {
return 1; if (dataSelector == null) {
return 1;
}
double val = dataSelector.scoreData(dataUnit);
return val;
} }
@Override @Override

File diff suppressed because it is too large Load Diff

View File

@ -412,7 +412,7 @@ public class SweepClassifier implements ClickIdentifier , PamSettings {
} }
@Override @Override
public ClassifyPaneFX getClassifierPane() { public SweepClassifierPaneFX getClassifierPane() {
if (fxPane==null) fxPane = new SweepClassifierPaneFX(this, clickControl); if (fxPane==null) fxPane = new SweepClassifierPaneFX(this, clickControl);
return fxPane; return fxPane;
} }

View File

@ -1511,7 +1511,7 @@ public class ClickDetection extends PamDataUnit<PamDataUnit, PamDataUnit> implem
* @param iCI the iCI to set * @param iCI the iCI to set
*/ */
public void setICI(double iCI) { public void setICI(double iCI) {
ICI = iCI; this.ICI = iCI;
} }
protected void setChannelGroupDetector(ChannelGroupDetector channelGroupDetector) { protected void setChannelGroupDetector(ChannelGroupDetector channelGroupDetector) {

View File

@ -40,6 +40,7 @@ import pamViewFX.fxNodes.PamVBox;
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX; import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
import pamViewFX.fxNodes.utilityPanes.FilterPaneFX; import pamViewFX.fxNodes.utilityPanes.FilterPaneFX;
import pamViewFX.fxNodes.utilityPanes.GroupedSourcePaneFX; import pamViewFX.fxNodes.utilityPanes.GroupedSourcePaneFX;
import pamViewFX.validator.PamValidator;
/** /**
* A pane to change click detector settings. * A pane to change click detector settings.
@ -175,7 +176,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
/** /**
* The default pane width * The default pane width
*/ */
public static double PREF_PANE_WIDTH=550; public static double PREF_PANE_WIDTH=560;
/** /**
@ -190,7 +191,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
this.clickControl=clickControl; this.clickControl=clickControl;
mainPane= new PamBorderPane(); mainPane= new PamBorderPane();
clickValidator = new Validator(); clickValidator = new PamValidator();
pamTabbedPane=new PamTabPane(); pamTabbedPane=new PamTabPane();
pamTabbedPane.setAddTabButton(false); pamTabbedPane.setAddTabButton(false);

View File

@ -284,5 +284,17 @@ public class OfflineEventDataBlock extends SuperDetDataBlock<OfflineEventDataUni
return (clickDetector.getClickDataBlock() == subDataBlock || clickDetector.getTrackedClicks() == subDataBlock); return (clickDetector.getClickDataBlock() == subDataBlock || clickDetector.getTrackedClicks() == subDataBlock);
} }
// int nName = 0;
// @Override
// public String getDataName() {
// // TODO Auto-generated method stub
// System.out.println("Call into getDataName " + ++nName);
// if (nName == 58) {
//
// System.out.println("Call into getDataName " + ++nName);
// }
// return super.getDataName();
// }
} }

View File

@ -164,15 +164,14 @@ public class OfflineToolbar {
return; return;
} }
String[] speciesList = clickId.getSpeciesList(); String[] speciesList = clickId.getSpeciesList();
if (speciesList == null || speciesList.length == 0) { if (speciesList != null) {
return; speciesButtons = new JCheckBox[speciesList.length];
} for (int i = 0; i < speciesList.length; i++) {
speciesButtons = new JCheckBox[speciesList.length]; speciesButtons[i] = new SpeciesCheckBox(speciesList[i] + space);
for (int i = 0; i < speciesList.length; i++) { c.gridx++;
speciesButtons[i] = new SpeciesCheckBox(speciesList[i] + space); speciesBar.add(speciesButtons[i]);
c.gridx++; speciesButtons[i].addActionListener(showClicks);
speciesBar.add(speciesButtons[i]); }
speciesButtons[i].addActionListener(showClicks);
} }
c.gridx++; c.gridx++;
speciesBar.add(andOrSelection = new JComboBox<String>()); speciesBar.add(andOrSelection = new JComboBox<String>());

View File

@ -619,9 +619,11 @@ public class ModuleConnectionNode extends StandardConnectionNode implements PAMC
//add tool tip //add tool tip
if (pamControlledUnit!=null){ if (pamControlledUnit!=null){
Tooltip tp = new Tooltip(pamControlledUnit.getUnitType());
tp.getStyleClass().removeAll(tp.getStyleClass()); //sometimes seems to cause an issue woith dialogs disappearing.
Tooltip.install(this, tp); // Tooltip tp = new Tooltip(pamControlledUnit.getUnitType());
// tp.getStyleClass().removeAll(tp.getStyleClass());
// Tooltip.install(this, tp);
//if no way for input then remove socket. //if no way for input then remove socket.
if (!hasInput(pamControlledUnit)){ if (!hasInput(pamControlledUnit)){

View File

@ -25,6 +25,9 @@ import pamViewFX.symbol.StandardSymbolOptionsPane;
*/ */
public class GenericSettingsPane extends PamBorderPane implements TDSettingsPane { public class GenericSettingsPane extends PamBorderPane implements TDSettingsPane {
/**
*
*/
private static final double PREF_WIDTH = 300; private static final double PREF_WIDTH = 300;
/* /*

View File

@ -61,6 +61,7 @@ public class LandmarkControl extends PamControlledUnit implements PamSettings {
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) { public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
landmarkDatas = ((LandmarkDatas) pamControlledUnitSettings.getSettings()).clone(); landmarkDatas = ((LandmarkDatas) pamControlledUnitSettings.getSettings()).clone();
landmarkDataBlock.createDataUnits(landmarkDatas);
return true; return true;
} }

View File

@ -4,7 +4,9 @@ import PamUtils.PamCalendar;
import PamView.symbol.StandardSymbolManager; import PamView.symbol.StandardSymbolManager;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess; import PamguardMVC.PamProcess;
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
import autecPhones.AutecGraphics; import autecPhones.AutecGraphics;
import pamScrollSystem.ViewLoadObserver;
public class LandmarkDataBlock extends PamDataBlock<LandmarkDataUnit> { public class LandmarkDataBlock extends PamDataBlock<LandmarkDataUnit> {
@ -31,4 +33,14 @@ public class LandmarkDataBlock extends PamDataBlock<LandmarkDataUnit> {
} }
} }
@Override
public boolean loadViewerData(long dataStart, long dataEnd, ViewLoadObserver loadObserver) {
return true;
}
@Override
public boolean loadViewerData(OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) {
return true;
}
} }

View File

@ -128,22 +128,27 @@ public class LevelMeterSidePanel extends PamObserverAdapter implements PamSidePa
levelDisplays[i].setLimits(levelMeterControl.levelMeterParams.minLevel, 0); levelDisplays[i].setLimits(levelMeterControl.levelMeterParams.minLevel, 0);
} }
checkConstants();
}
private void checkConstants() {
// now find the source acquisition module and any gain that's in between them. // now find the source acquisition module and any gain that's in between them.
PamRawDataBlock rawBlock = (PamRawDataBlock) parentBlock; PamRawDataBlock rawBlock = (PamRawDataBlock) parentBlock;
if (rawBlock!=null) { if (rawBlock==null) {
AcquisitionProcess daqProcess = (AcquisitionProcess) rawBlock.getSourceProcess(); return;
AcquisitionControl daqControl = daqProcess.getAcquisitionControl();
voltsPeak2Peak = daqControl.acquisitionParameters.voltsPeak2Peak;
int nChan = PamUtils.getNumChannels(channelMap);
maxFullScale = Double.NEGATIVE_INFINITY;
for (int i = 0; i < nChan; i++) {
int chan = PamUtils.getNthChannel(i, channelMap);
gains[chan] = rawBlock.getDataGain(chan);
dbFullScale[chan] = daqProcess.rawAmplitude2dB(1, chan, false);
maxFullScale = Math.max(maxFullScale, dbFullScale[chan]);
}
setupLabels();
} }
int channelMap = parentBlock.getChannelMap();
AcquisitionProcess daqProcess = (AcquisitionProcess) rawBlock.getSourceProcess();
AcquisitionControl daqControl = daqProcess.getAcquisitionControl();
voltsPeak2Peak = daqControl.acquisitionParameters.voltsPeak2Peak;
int nChan = PamUtils.getNumChannels(channelMap);
maxFullScale = Double.NEGATIVE_INFINITY;
for (int i = 0; i < nChan; i++) {
int chan = PamUtils.getNthChannel(i, channelMap);
gains[chan] = rawBlock.getDataGain(chan);
dbFullScale[chan] = daqProcess.rawAmplitude2dB(1, chan, false);
maxFullScale = Math.max(maxFullScale, dbFullScale[chan]);
}
setupLabels();
} }
private void setupLabels() { private void setupLabels() {
@ -228,7 +233,7 @@ public class LevelMeterSidePanel extends PamObserverAdapter implements PamSidePa
case LevelMeterParams.DISPLAY_VOLTS: case LevelMeterParams.DISPLAY_VOLTS:
return 20.*Math.log10(level*(voltsPeak2Peak/2)); return 20.*Math.log10(level*(voltsPeak2Peak/2));
case LevelMeterParams.DISPLAY_MICROPASCAL: case LevelMeterParams.DISPLAY_MICROPASCAL:
return 20.*Math.log10(level) + maxFullScale; return 20.*Math.log10(level) + dbFullScale[channel];
} }
return 0; return 0;
} }

View File

@ -30,6 +30,7 @@ import javax.swing.text.MaskFormatter;
import Array.ArrayManager; import Array.ArrayManager;
import GPS.GPSControl; import GPS.GPSControl;
import GPS.GPSDataBlock; import GPS.GPSDataBlock;
import GPS.GpsData;
import GPS.GpsDataUnit; import GPS.GpsDataUnit;
import NMEA.NMEADataBlock; import NMEA.NMEADataBlock;
import NMEA.NMEADataUnit; import NMEA.NMEADataUnit;
@ -657,98 +658,25 @@ public class LatLongControl extends LoggerControl implements ClipboardOwner{
} }
// private class LatChangeListener implements PropertyChangeListener{
//
// /* (non-Javadoc)
// * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
// */
// @Override
// public void propertyChange(PropertyChangeEvent arg0) {
//
// System.out.println("old:"+arg0.getOldValue());
// System.out.println("new:"+arg0.getNewValue());
// try {
// textFieldLat.commitEdit();
// } catch (ParseException e) {
// // TODO Auto-generated catch block
//// e.printStackTrace();
// }
// }
//
// }
// private class LonChangeListener implements PropertyChangeListener{
//
// /* (non-Javadoc)
// * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
// */
// @Override
// public void propertyChange(PropertyChangeEvent arg0) {
//
//// System.out.println("old:"+arg0.getOldValue());
//// System.out.println("new:"+arg0.getNewValue());
// try {
// textFieldLon.commitEdit();
// } catch (ParseException e) {
// // TODO Auto-generated catch block
//// e.printStackTrace();
// }
// }
//
// }
@Override @Override
public void setData(Object latLong) { public void setData(Object latLong) {
LatLong a = (LatLong)latLong; if (latLong==null || latLong instanceof LatLong == false){
if (a==null){
// System.out.println("latLon null"); // System.out.println("latLon null");
textFieldLat.setValue(null); textFieldLat.setValue(null);
textFieldLon.setValue(null); textFieldLon.setValue(null);
return; return;
} }
LatLong a = (LatLong)latLong;
// System.out.println("a :"+a.toString()); // System.out.println("a :"+a.toString());
textFieldLat.setValue(a.getLatitude()); textFieldLat.setValue(a.getLatitude());
// textFieldLat.setText(a.formatLatitude());
// System.out.println("a latVal:"+textFieldLat.getValue());
// System.out.println("a latTxt:"+textFieldLat.getText());
textFieldLon.setValue(a.getLongitude()); textFieldLon.setValue(a.getLongitude());
// textFieldLon.setText(a.formatLongitude());
// addPropertyChangeListener("value", this);
// try {
// textFieldLat.commitEdit();
// textFieldLon.commitEdit();
// } catch (ParseException e) {
// if (dataWarning==null) dataWarning="";
// dataWarning+=" Unable to setData(...) ";
// e.printStackTrace();
// }
// if (latLong==null){
// System.out.println("LatLont null");
// textFieldLat.setText("");
// textFieldLon.setText("");
// return;
// }
//
// if (latLong.getClass().isAssignableFrom(LatLong.class)){
// System.out.println("LatLont assignable");
// LatLong latLon = (LatLong) latLong;
//
// if (latLon==null){
// System.out.println("LatLont still null");
// textFieldLat.setText("");
// textFieldLon.setText("");
// return;
// }
//
// textFieldLat.setText(LatLong.formatLatitude(latLon.getLatitude()));
// System.out.println(latLon.toString());
// textFieldLon.setText(LatLong.formatLongitude(latLon.getLongitude()));
// }
} }
@Override @Override
@ -856,6 +784,15 @@ public class LatLongControl extends LoggerControl implements ClipboardOwner{
try { try {
GpsDataUnit gpsUnit = findGpsDataBlock().getLastUnit(); GpsDataUnit gpsUnit = findGpsDataBlock().getLastUnit();
if (gpsUnit == null) {
setData(null);
return AUTO_UPDATE_FAIL;
}
GpsData gpsData = gpsUnit.getGpsData();
if (gpsData == null) {
setData(null);
return AUTO_UPDATE_FAIL;
}
latitude = gpsUnit.getGpsData().getLatitude(); latitude = gpsUnit.getGpsData().getLatitude();
longitude = gpsUnit.getGpsData().getLongitude(); longitude = gpsUnit.getGpsData().getLongitude();

View File

@ -161,7 +161,8 @@ public class NoiseBandProcess extends PamProcess {
lastOutputTime = timeMillis; lastOutputTime = timeMillis;
} }
else if (timeMillis - lastOutputTime >= noiseBandControl.noiseBandSettings.outputIntervalSeconds*1000) { else if (timeMillis - lastOutputTime >= noiseBandControl.noiseBandSettings.outputIntervalSeconds*1000) {
daqProcess.prepareFastAmplitudeCalculation(iChan); double ampTerm = daqProcess.prepareFastAmplitudeCalculation(iChan);
// System.out.printf("Amplitude term cahnnel %d is %3.1f\n", iChan, ampTerm);
double[][] measurementStats = new double[bandOutputs.length][2]; double[][] measurementStats = new double[bandOutputs.length][2];
for (int i = 0; i < bandOutputs.length; i++) { for (int i = 0; i < bandOutputs.length; i++) {
measurementStats[bandOutputs.length-i-1][0] = daqProcess.rawAmplitude2dB(bandOutputs[i].getRMS(), iChan, true); measurementStats[bandOutputs.length-i-1][0] = daqProcess.rawAmplitude2dB(bandOutputs[i].getRMS(), iChan, true);

View File

@ -167,7 +167,7 @@ abstract public class AbstractPamScrollerAWT extends AbstractPamScroller impleme
protected JPanel getButtonPanel() { protected JPanel getButtonPanel() {
return buttonPanel; return buttonPanel;
} }
class PageForwardAction implements ActionListener { class PageForwardAction implements ActionListener {
@Override @Override
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {

View File

@ -140,6 +140,7 @@ public class PamScrollSlider extends AbstractPamScrollerAWT {
valueMillis = Math.max(scrollerData.minimumMillis, Math.min(scrollerData.maximumMillis, valueMillis)); valueMillis = Math.max(scrollerData.minimumMillis, Math.min(scrollerData.maximumMillis, valueMillis));
int val = (int) ((valueMillis - scrollerData.minimumMillis) / scrollerData.getStepSizeMillis()); int val = (int) ((valueMillis - scrollerData.minimumMillis) / scrollerData.getStepSizeMillis());
if (val >= slider.getMinimum() && val <= slider.getMaximum()) { if (val >= slider.getMinimum() && val <= slider.getMaximum()) {
// System.out.printf("Set slider val %d in range %d to %d\n", val, slider.getMinimum(), slider.getMaximum());
slider.setValue(val); slider.setValue(val);
} }
} }

View File

@ -191,9 +191,9 @@ public class ViewerScrollerManager extends AbstractScrollManager implements PamS
*/ */
private void loadDataQueueItem(DataLoadQueData dataLoadQueData, int queuePosition, ViewLoadObserver loadObserver) { private void loadDataQueueItem(DataLoadQueData dataLoadQueData, int queuePosition, ViewLoadObserver loadObserver) {
PamDataBlock dataBlock = dataLoadQueData.getPamDataBlock(); PamDataBlock dataBlock = dataLoadQueData.getPamDataBlock();
if (dataBlock instanceof OfflineEventDataBlock) { // if (dataBlock instanceof OfflineEventDataBlock) {
System.out.println(dataBlock); // System.out.println("in loadDataQueueItem" + dataBlock);
} // }
// 2019-11-12 add a check of the counts to this 'if' statement as well. If the data start time is negative // 2019-11-12 add a check of the counts to this 'if' statement as well. If the data start time is negative
// (which can indicate that this is a 'special' data block and we should be loading all of it rather than just // (which can indicate that this is a 'special' data block and we should be loading all of it rather than just
@ -699,6 +699,23 @@ public class ViewerScrollerManager extends AbstractScrollManager implements PamS
if (aScroller == pamScroller) { if (aScroller == pamScroller) {
continue; continue;
} }
/*
* Can end up with some horrible feedback here if two
* coupled scrollers bring in rounding errors and start
* to oscillate each other.
*/
long currentVal = aScroller.getValueMillis();
long change = Math.abs(value-currentVal);
long range = aScroller.getMaximumMillis() - aScroller.getMinimumMillis();
if (range == 0) {
aScroller.setValueMillis(aScroller.getMinimumMillis());
continue;
}
double fracChange = (double) change / (double) range;
if (fracChange <= .0001) {
continue;
}
aScroller.setValueMillis(value); aScroller.setValueMillis(value);
} }
} }

View File

@ -14,6 +14,8 @@ import pamViewFX.fxNodes.PamSpinner;
*/ */
public class FreqBandPane extends PamGridPane { public class FreqBandPane extends PamGridPane {
private final static double FREQ_SPINNER_WIDTH= 130;
/** /**
* High pass spinner. * High pass spinner.
@ -23,7 +25,7 @@ public class FreqBandPane extends PamGridPane {
/** /**
* Low pass frequency spinner. * Low pass frequency spinner.
*/ */
private Spinner<Double> lowPassFreq; private PamSpinner<Double> lowPassFreq;
/** /**
* Layout of the pane- either horizontal or vertical * Layout of the pane- either horizontal or vertical
@ -65,14 +67,14 @@ public class FreqBandPane extends PamGridPane {
this.setHgap(5); this.setHgap(5);
this.setVgap(5); this.setVgap(5);
highPassFreq=new PamSpinner<Double>(10.,500000.,1000.,2000.); highPassFreq=new PamSpinner<Double>(0.,500000.,1000.,2000.);
highPassFreq.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL); highPassFreq.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
highPassFreq.getValueFactory().valueProperty().addListener((obs, before, after)->{ // highPassFreq.getValueFactory().valueProperty().addListener((obs, before, after)->{
if (after>=lowPassFreq.getValue()) lowPassFreq.getValueFactory().setValue(Math.min(sampleRate/2.,highPassFreq.getValue()+100)); // if (after>=lowPassFreq.getValue()) lowPassFreq.getValueFactory().setValue(Math.min(sampleRate/2.,highPassFreq.getValue()+100));
if (after>sampleRate/2.) highPassFreq.getValueFactory().setValue(sampleRate/2.); // if (after>sampleRate/2.) highPassFreq.getValueFactory().setValue(sampleRate/2.);
}); // });
highPassFreq.setEditable(true); highPassFreq.setEditable(true);
//highPassFreq.setPrefWidth(140); highPassFreq.setMinWidth(FREQ_SPINNER_WIDTH);
//highCut.setPrefColumnCount(6); //highCut.setPrefColumnCount(6);
if (orientation==Orientation.VERTICAL){ if (orientation==Orientation.VERTICAL){
@ -86,15 +88,15 @@ public class FreqBandPane extends PamGridPane {
this.add(highPassHzLabel=new Label("Hz"), 2, 0); this.add(highPassHzLabel=new Label("Hz"), 2, 0);
} }
lowPassFreq=new PamSpinner<Double>(1.,500000.,2000.,2000.); lowPassFreq=new PamSpinner<Double>(0.,500000.,2000.,2000.);
lowPassFreq.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL); lowPassFreq.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
lowPassFreq.getValueFactory().valueProperty().addListener((obs, before, after)->{ // lowPassFreq.getValueFactory().valueProperty().addListener((obs, before, after)->{
if (after<=highPassFreq.getValue()) highPassFreq.getValueFactory().setValue(Math.min(0,lowPassFreq.getValue()-100)); // if (after<=highPassFreq.getValue()) highPassFreq.getValueFactory().setValue(Math.min(0,lowPassFreq.getValue()-100));
if (after>sampleRate/2.) lowPassFreq.getValueFactory().setValue(sampleRate/2.); // if (after>sampleRate/2.) lowPassFreq.getValueFactory().setValue(sampleRate/2.);
//
}); // });
lowPassFreq.setEditable(true); lowPassFreq.setEditable(true);
//lowPassFreq.setPrefWidth(140); lowPassFreq.setMinWidth(FREQ_SPINNER_WIDTH);
if (orientation==Orientation.VERTICAL){ if (orientation==Orientation.VERTICAL){

View File

@ -17,6 +17,7 @@ import pamViewFX.PamGuiManagerFX;
import pamViewFX.fxNodes.PamGridPane; import pamViewFX.fxNodes.PamGridPane;
import pamViewFX.fxNodes.PamHBox; import pamViewFX.fxNodes.PamHBox;
import pamViewFX.fxNodes.PamVBox; import pamViewFX.fxNodes.PamVBox;
import pamViewFX.validator.PamValidator;
import PamUtils.PamUtils; import PamUtils.PamUtils;
import PamView.GroupedSourceParameters; import PamView.GroupedSourceParameters;
import PamguardMVC.PamConstants; import PamguardMVC.PamConstants;
@ -76,7 +77,7 @@ public class GroupedSourcePaneFX extends SourcePaneFX {
@Override @Override
protected void createPanel() { protected void createPanel() {
channelValidator = new Validator(); channelValidator = new PamValidator();
sourcePane=new PamGridPane(); sourcePane=new PamGridPane();
sourcePane.setVgap(5); sourcePane.setVgap(5);

View File

@ -0,0 +1,17 @@
package pamViewFX.validator;
import net.synedra.validatorfx.Validator;
/**
* Extension of the validator class to add PAMGuard specific functions.
* @author Jamie Macaulay
*
*/
public class PamValidator extends Validator {
public PamValidator() {
super();
// TODO Auto-generated constructor stub
}
}

View File

@ -22,6 +22,7 @@ import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon; import javafx.scene.shape.Polygon;
import rawDeepLearningClassifier.DLControl; import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.dlClassification.DLClassName;
import rawDeepLearningClassifier.dlClassification.DLDataUnit; import rawDeepLearningClassifier.dlClassification.DLDataUnit;
/** /**
@ -79,6 +80,16 @@ public class DLPredictionPlotInfoFX extends GenericLinePlotInfo {
probabilityScaleInfo = new GenericScaleInfo(-0.1, 1.1, ParameterType.PROBABILITY, ParameterUnits.PROBABILITY); probabilityScaleInfo = new GenericScaleInfo(-0.1, 1.1, ParameterType.PROBABILITY, ParameterUnits.PROBABILITY);
frequencyInfo = new GenericScaleInfo(0, 1, ParameterType.FREQUENCY, ParameterUnits.HZ); frequencyInfo = new GenericScaleInfo(0, 1, ParameterType.FREQUENCY, ParameterUnits.HZ);
DLClassName[] classNames = getDlControl().getDLModel().getClassNames();
//make sure this is initialised otherwise the plot won't work when first created.
if (dlPredParams.lineInfos==null ) dlPredParams.lineInfos = new LineInfo[classNames.length];
for (int i=0; i<classNames.length; i++) {
if (dlPredParams.lineInfos[i]==null) {
dlPredParams.lineInfos[i] = new LineInfo(true, Color.rgb(0, 0, 255%(i*30 + 50)));
}
}
addScaleInfo(probabilityScaleInfo); addScaleInfo(probabilityScaleInfo);
addScaleInfo(frequencyInfo); addScaleInfo(frequencyInfo);

View File

@ -36,6 +36,7 @@ import rawDeepLearningClassifier.segmenter.SegmenterProcess.GroupedRawData;
*/ */
public class DLClassifyProcess extends PamInstantProcess { public class DLClassifyProcess extends PamInstantProcess {
/** /**
* Holds all model results but no other information * Holds all model results but no other information
*/ */
@ -538,7 +539,9 @@ public class DLClassifyProcess extends PamInstantProcess {
@Override @Override
public void pamStop() { public void pamStop() {
runModel(); //make sure to run the last data in the buffer. runModel(); //make sure to run the last data in the buffer.
this.dlControl.getDLModel().closeModel();
//21/11/2022 - it seems like this causes a memory leak when models are reopened and closed every file...
//this.dlControl.getDLModel().closeModel();
} }
/** /**

View File

@ -168,7 +168,11 @@ public class GenericDLClassifier implements DLClassiferModel, PamSettings {
@Override @Override
public void closeModel() { public void closeModel() {
// TODO Auto-generated method stub //very important to prevent memory leak for long term processing.
if (genericModelWorker.getModel()!=null && genericModelWorker.getModel().getModel()!=null) {
//System.out.println("CLOSE GENERNIC MODEL");
genericModelWorker.getModel().getModel().close();
}
} }

View File

@ -283,6 +283,8 @@ public class GenericModelParser {
classNames[i]=classNames[i].trim(); //remove whitespace classNames[i]=classNames[i].trim(); //remove whitespace
} }
paramsClone.numClasses = classNames.length;
if (classNameManager!=null) { if (classNameManager!=null) {

View File

@ -1,5 +1,7 @@
package rawDeepLearningClassifier.dlClassification.genericModel; package rawDeepLearningClassifier.dlClassification.genericModel;
import java.nio.file.Paths;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.jamdev.jdl4pam.genericmodel.GenericModel; import org.jamdev.jdl4pam.genericmodel.GenericModel;
import org.jamdev.jdl4pam.transforms.DLTransform; import org.jamdev.jdl4pam.transforms.DLTransform;
@ -69,8 +71,22 @@ public class GenericModelWorker extends DLModelWorker<GenericPrediction> {
// Thread.currentThread().setContextClassLoader(newCL); // Thread.currentThread().setContextClassLoader(newCL);
// } // }
//first open the model and get the correct parameters. // if (genericModel!=null) {
genericModel = new PamGenericModel(genericParams.modelPath); // System.out.println(Paths.get(genericModel.getModel().getName()));
// System.out.println(Paths.get(genericParams.modelPath));
// System.out.println(Paths.get(genericModel.getModel().getName()).equals(Paths.get(genericParams.modelPath)));
// }
//first open the model and get the correct parameters.
//21/11/2022 - Added a null and filename check here to stop the mdoel reloading everytime PAMGuard hits a new file or
//is stopped or started - this was causing a memory leak.
if (genericModel==null || !Paths.get(genericModel.getModel().getName()).equals(Paths.get(genericParams.modelPath))) {
//System.out.println(Paths.get(genericParams.modelPath));
genericModel = new PamGenericModel(genericParams.modelPath);
//System.out.println("LOAD A NEW MODEL: ");
//System.out.println(genericModel.getModel().getModelPath().getFileName());
}
//is this a waveform or a spectrogram model? //is this a waveform or a spectrogram model?
DLTransform transform = genericParams.dlTransfroms.get(genericParams.dlTransfroms.size()-1); DLTransform transform = genericParams.dlTransfroms.get(genericParams.dlTransfroms.size()-1);

View File

@ -55,7 +55,7 @@ public class PamGenericModel {
*/ */
private Shape outShape = null; private Shape outShape = null;
private SpectrogramTranslator specTranslator; private SpectrogramTranslator specTranslator;
@ -64,6 +64,8 @@ public class PamGenericModel {
public PamGenericModel(String modelPath) throws MalformedModelException, IOException{ public PamGenericModel(String modelPath) throws MalformedModelException, IOException{
//System.out.println("NEW GENERIC MODEL:");
File file = new File(modelPath); File file = new File(modelPath);
@ -95,7 +97,6 @@ public class PamGenericModel {
if (model == null) { if (model == null) {
System.err.println("Generic Model: Could not load model: " + modelPath); System.err.println("Generic Model: Could not load model: " + modelPath);
} }
else { else {
if (model!=null && model.describeInput()!=null) { if (model!=null && model.describeInput()!=null) {
System.out.println("Generic Model: Input: " + model.describeInput().toString()); System.out.println("Generic Model: Input: " + model.describeInput().toString());
@ -117,7 +118,6 @@ public class PamGenericModel {
//predictor for the model if using //predictor for the model if using
wavePredictor = model.newPredictor(waveTranslator); wavePredictor = model.newPredictor(waveTranslator);
} }
} }
@ -201,8 +201,6 @@ public class PamGenericModel {
} }
public Model getModel() { public Model getModel() {
return model; return model;
} }

View File

@ -1,6 +1,7 @@
package rawDeepLearningClassifier.dlClassification.ketos; package rawDeepLearningClassifier.dlClassification.ketos;
import java.io.File; import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import org.jamdev.jdl4pam.ketos.KetosModel; import org.jamdev.jdl4pam.ketos.KetosModel;
@ -15,6 +16,7 @@ import PamModel.PamModel.PluginClassloader;
import rawDeepLearningClassifier.DLControl; import rawDeepLearningClassifier.DLControl;
import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams; import rawDeepLearningClassifier.dlClassification.animalSpot.StandardModelParams;
import rawDeepLearningClassifier.dlClassification.genericModel.DLModelWorker; import rawDeepLearningClassifier.dlClassification.genericModel.DLModelWorker;
import rawDeepLearningClassifier.dlClassification.genericModel.PamGenericModel;
/** /**
* *
@ -30,7 +32,12 @@ public class KetosWorker extends DLModelWorker<KetosResult> {
/** /**
* The ketos model * The ketos model
*/ */
private KetosModel ketosModel; private KetosModel ketosModel;
/**
* Thelast loaded model path.,
*/
private String currentPath;
/** /**
@ -56,7 +63,15 @@ public class KetosWorker extends DLModelWorker<KetosResult> {
Thread.currentThread().setContextClassLoader(newCL); Thread.currentThread().setContextClassLoader(newCL);
} }
//first open the model and get the correct parameters. //first open the model and get the correct parameters.
ketosModel = new KetosModel(new File(ketosDLParams.modelPath)); //21/11/2022 - Added a null and filename check here to stop the mdoel reloading everytime PAMGuard hits a new file or
//is stopped or started - this was causing a memory leak.
if (ketosModel==null || currentPath ==null || !Paths.get(currentPath).equals(Paths.get(ketosDLParams.modelPath))) {
//System.out.println(Paths.get(genericParams.modelPath));
this.currentPath = ketosDLParams.modelPath;
ketosModel = new KetosModel(new File(ketosDLParams.modelPath));
//System.out.println("LOAD A NEW MODEL: ");
//System.out.println(genericModel.getModel().getModelPath().getFileName());
}
} }
catch (Exception e) { catch (Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -91,7 +91,8 @@ public class DataTransformPaneFactory {
case SPECTROGRAM: case SPECTROGRAM:
settingsPane = new FFTTransformPane((SimpleTransform) dlTransfrom, new String[]{"FFT Length ", "FFT Hop"}, new String[]{"", ""}); settingsPane = new FFTTransformPane((SimpleTransform) dlTransfrom, new String[]{"FFT Length ", "FFT Hop"}, new String[]{"", ""});
// ((SimpleTransformPane) settingsPane).setSpinnerMinMaxValues(0, 4, Integer.MAX_VALUE, 4); // ((SimpleTransformPane) settingsPane).setSpinnerMinMaxValues(0, 4, Integer.MAX_VALUE, 4);
((SimpleTransformPane) settingsPane).setSpinnerMinMaxValues(1, 4, Integer.MAX_VALUE, 4);
((FFTTransformPane) settingsPane).setSpinnerMinMaxValues(1, 4, Integer.MAX_VALUE, 4);
// //make an FFT spinner here with doubling FFT lengths - DOES NOT WORK FOR SOME REASON... // //make an FFT spinner here with doubling FFT lengths - DOES NOT WORK FOR SOME REASON...
// ((SimpleTransformPane) settingsPane).getSpinners().get(0).setValueFactory(new SpinnerValueFactory.ListSpinnerValueFactory<>(createStepList())); // ((SimpleTransformPane) settingsPane).getSpinners().get(0).setValueFactory(new SpinnerValueFactory.ListSpinnerValueFactory<>(createStepList()));
// ((SimpleTransformPane) settingsPane).getSpinners().get(0).getValueFactory().setValue(4); // ((SimpleTransformPane) settingsPane).getSpinners().get(0).getValueFactory().setValue(4);

View File

@ -89,7 +89,7 @@ public class SimpleTransformPane extends DLTransformPane {
int row = 0; int row = 0;
int column = 0; int column = 0;
if (simpleTransfrom.getParams()!=null) { // if (simpleTransfrom.getParams()!=null) {
for (int i=0; i<paramNames.length; i++) { for (int i=0; i<paramNames.length; i++) {
if (i%nParamCol == 0 && i!=0) { if (i%nParamCol == 0 && i!=0) {
row++; row++;
@ -117,8 +117,7 @@ public class SimpleTransformPane extends DLTransformPane {
//System.out.println("New line: " + i + " " + nParamCol + " " + i%nParamCol); //System.out.println("New line: " + i + " " + nParamCol + " " + i%nParamCol);
} }
// }
}
TitledPane titledPane = new TitledPane(simpleTransfrom.getDLTransformType().toString(), gridPane); TitledPane titledPane = new TitledPane(simpleTransfrom.getDLTransformType().toString(), gridPane);
@ -190,8 +189,8 @@ public class SimpleTransformPane extends DLTransformPane {
SimpleTransform simpleTransform = (SimpleTransform) currParams; SimpleTransform simpleTransform = (SimpleTransform) currParams;
//Set the new numbers //Set the new numbers
Number[] params = new Number[simpleTransform.getParams().length]; Number[] params = new Number[spinners.size()];
for (int i=0; i<simpleTransform.getParams().length; i++) { for (int i=0; i<spinners.size(); i++) {
params[i] = spinners.get(i).getValue(); params[i] = spinners.get(i).getValue();
} }
@ -208,6 +207,11 @@ public class SimpleTransformPane extends DLTransformPane {
SimpleTransform simpleTransform = (SimpleTransform) input; SimpleTransform simpleTransform = (SimpleTransform) input;
if (simpleTransform.getParams()==null) {
System.err.println("SimpleTransformPane: params for " + simpleTransform.getDLTransformType() + " are null - maybe backwards compatibility issue ");
simpleTransform.setParams(((SimpleTransform)DLTransformsFactory.makeDLTransform(simpleTransform.getDLTransformType(), 1000)).getParams());
}
//System.out.println("Transform type: " + simpleTransform.getDLTransformType() + " " + simpleTransform.getParams().length + " " + spinners.size()); //System.out.println("Transform type: " + simpleTransform.getDLTransformType() + " " + simpleTransform.getParams().length + " " + spinners.size());
for (int i=0; i<spinners.size(); i++) { for (int i=0; i<spinners.size(); i++) {

View File

@ -451,7 +451,7 @@ public class RoccaSpecPopUp extends javax.swing.JPanel {
for(int currentFreqBin = 0; currentFreqBin < fftVals.length(); currentFreqBin++) { for(int currentFreqBin = 0; currentFreqBin < fftVals.length(); currentFreqBin++) {
rawAmp = fftVals.magsq(currentFreqBin); rawAmp = fftVals.magsq(currentFreqBin);
dB = daq.fftAmplitude2dB(rawAmp, dB = daq.fftAmplitude2dB(rawAmp,
channelMap, PamUtils.getLowestChannel(channelMap),
fftData.getSampleRate(), fftData.getSampleRate(),
fftLength, fftLength,
true, true,

View File

@ -131,7 +131,12 @@ public class GridMovement extends MovementModel implements PamSettings {
@Override @Override
public String getUnitName() { public String getUnitName() {
return getSimObject().name; if (getSimObject() != null && getSimObject().name != null) {
return getSimObject().name;
}
else {
return "Unknown";
}
} }
@Override @Override

View File

@ -0,0 +1,23 @@
package simulatedAcquisition.sounds;
public class RandomMystecete extends RandomQuadratics {
public RandomMystecete() {
super();
double slope[] = {-150, 150};
double length[] = {.4, 1};
double meanF[] = {200, 800};
double meanCurve[] = {-300, 300};
setCurveR(meanCurve);
setLengthR(length);
setMeanR(meanF);
setSlopeR(slope);
}
@Override
public String getName() {
return "Random baleen whale (humpbackish)";
}
}

View File

@ -35,6 +35,7 @@ public class SimSignals {
simSignalList.add(new RandomWhistles()); simSignalList.add(new RandomWhistles());
simSignalList.add(new BranchedChirp(5000, 12000, 8000, 3000, .6)); simSignalList.add(new BranchedChirp(5000, 12000, 8000, 3000, .6));
simSignalList.add(new RightWhales()); simSignalList.add(new RightWhales());
simSignalList.add(new RandomMystecete());
simSignalList.add(new BlueWhaleD()); simSignalList.add(new BlueWhaleD());
simSignalList.add(new WhiteNoise()); simSignalList.add(new WhiteNoise());
simSignalList.add(new PinkNoise()); simSignalList.add(new PinkNoise());

View File

@ -23,8 +23,12 @@ import Stats.LinFit;
* Step 3 is to rotate all position and angle vectors so that they correspond to * Step 3 is to rotate all position and angle vectors so that they correspond to
* a track as close as possible to the x axis. * a track as close as possible to the x axis.
* @author Doug Gillespie * @author Doug Gillespie
*
* Deprecated. Not used and will probably fall over with system whereby sub detection info
* is present, but not all sub detections are.
* *
*/ */
@Deprecated
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class EventRotator extends AbstractTargetMotionInformation{ public class EventRotator extends AbstractTargetMotionInformation{

View File

@ -1,9 +1,13 @@
package targetMotionOld; package targetMotionOld;
import pamMaths.PamVector; import pamMaths.PamVector;
import java.util.List;
import PamDetection.AbstractLocalisation; import PamDetection.AbstractLocalisation;
import PamUtils.LatLong; import PamUtils.LatLong;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import PamguardMVC.superdet.SubdetectionInfo;
import PamguardMVC.superdet.SuperDetection; import PamguardMVC.superdet.SuperDetection;
import Stats.LinFit; import Stats.LinFit;
@ -74,12 +78,18 @@ public class EventRotator {
private double[] rotatedArrayAngles; private double[] rotatedArrayAngles;
private int referenceHydrophones; private int referenceHydrophones;
/**
* List of present (actual sub detection is not null) sub detections.
*/
private List<SubdetectionInfo<PamDataUnit>> subDetections;
/** /**
* @param pamDetection * @param pamDetection
*/ */
public EventRotator(SuperDetection pamDetection) { public EventRotator(SuperDetection pamDetection) {
super(); super();
this.pamDetection = pamDetection; this.pamDetection = pamDetection;
this.subDetections = pamDetection.getPresentSubDetections();
rotatedWorldVectors = null; rotatedWorldVectors = null;
calculateMetrePoints(); calculateMetrePoints();
} }
@ -90,14 +100,14 @@ public class EventRotator {
*/ */
private void calculateMetrePoints() { private void calculateMetrePoints() {
lastUpdateTime = pamDetection.getLastUpdateTime(); lastUpdateTime = pamDetection.getLastUpdateTime();
nSubDetections = pamDetection.getSubDetectionsCount(); nSubDetections = subDetections.size();
subDetectionOrigins = new PamVector[nSubDetections]; subDetectionOrigins = new PamVector[nSubDetections];
subDetectionHeadings = new PamVector[nSubDetections]; subDetectionHeadings = new PamVector[nSubDetections];
pointTimes = new long[nSubDetections]; pointTimes = new long[nSubDetections];
if (nSubDetections == 0) { if (nSubDetections == 0) {
return; return;
} }
PamDataUnit pd = pamDetection.getSubDetection(0); PamDataUnit pd = subDetections.get(0).getSubDetection();
if (pd == null) { if (pd == null) {
return; return;
} }
@ -110,7 +120,10 @@ public class EventRotator {
LatLong detOrigin; LatLong detOrigin;
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
pd = pamDetection.getSubDetection(i); pd = subDetections.get(i).getSubDetection();
if (pd == null) {
continue;
}
localisation = pd.getLocalisation(); localisation = pd.getLocalisation();
if (localisation == null) { if (localisation == null) {
continue; continue;
@ -152,6 +165,9 @@ public class EventRotator {
rotatedOrigins = new PamVector[nSubDetections]; rotatedOrigins = new PamVector[nSubDetections];
rotatedHeadings = new PamVector[nSubDetections]; rotatedHeadings = new PamVector[nSubDetections];
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
if (subDetectionOrigins[i] == null) {
continue;
}
subDetectionHeadings[i] = new PamVector(Math.cos(Math.PI/2-rotatedArrayAngles[i]), Math.sin(Math.PI/2-rotatedArrayAngles[i]), 0); subDetectionHeadings[i] = new PamVector(Math.cos(Math.PI/2-rotatedArrayAngles[i]), Math.sin(Math.PI/2-rotatedArrayAngles[i]), 0);
rotatedOrigins[i] = subDetectionOrigins[i].rotate(-referenceAngle); rotatedOrigins[i] = subDetectionOrigins[i].rotate(-referenceAngle);
rotatedArrayAngles[i] = Math.PI/2. - rotatedArrayAngles[i]; rotatedArrayAngles[i] = Math.PI/2. - rotatedArrayAngles[i];
@ -170,7 +186,7 @@ public class EventRotator {
PamDataUnit pd; PamDataUnit pd;
AbstractLocalisation localisation; AbstractLocalisation localisation;
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
pd = pamDetection.getSubDetection(i); pd = subDetections.get(i).getSubDetection();
localisation = pd.getLocalisation(); localisation = pd.getLocalisation();
if (localisation == null) { if (localisation == null) {
continue; continue;
@ -187,7 +203,7 @@ public class EventRotator {
PamDataUnit pd; PamDataUnit pd;
AbstractLocalisation localisation; AbstractLocalisation localisation;
for (int i = 0; i < nSubDetections; i++) { for (int i = 0; i < nSubDetections; i++) {
pd = pamDetection.getSubDetection(i); pd = subDetections.get(i).getSubDetection();
localisation = pd.getLocalisation(); localisation = pd.getLocalisation();
if (localisation == null) { if (localisation == null) {
continue; continue;

View File

@ -4,6 +4,7 @@ import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel; import javax.swing.JPanel;
@ -18,6 +19,7 @@ import PamUtils.LatLong;
import PamguardMVC.PamDataBlock; import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit; import PamguardMVC.PamDataUnit;
import PamguardMVC.dataSelector.DataSelector; import PamguardMVC.dataSelector.DataSelector;
import PamguardMVC.superdet.SubdetectionInfo;
import clickDetector.ClickDataBlock; import clickDetector.ClickDataBlock;
import targetMotionOld.TargetMotionLocaliser; import targetMotionOld.TargetMotionLocaliser;
@ -66,9 +68,14 @@ public class DialogMap3DSwing<T extends GroupDetection> extends DialogMap<T> {
mapDetData.allAvailable = true; mapDetData.allAvailable = true;
mapDetData.select = true; mapDetData.select = true;
int nSub = currentEvent.getSubDetectionsCount(); List<SubdetectionInfo<PamDataUnit>> subDets = currentEvent.getPresentSubDetections();
int nSub = subDets.size();
for (int i = 0; i < nSub; i++) { for (int i = 0; i < nSub; i++) {
PamDataUnit subDet = currentEvent.getSubDetection(i); PamDataUnit subDet = subDets.get(i).getSubDetection();
if (subDet == null) {
continue;
}
MapDetectionData subDetData = mapDetectionsManager.findDetectionData(subDet.getParentDataBlock()); MapDetectionData subDetData = mapDetectionsManager.findDetectionData(subDet.getParentDataBlock());
if (subDetData != null && subDetData != mapDetData) { if (subDetData != null && subDetData != mapDetData) {
mapDetData = subDetData; mapDetData = subDetData;
@ -81,8 +88,8 @@ public class DialogMap3DSwing<T extends GroupDetection> extends DialogMap<T> {
*/ */
LatLong eventCentre = currentEvent.getOriginLatLong(true); LatLong eventCentre = currentEvent.getOriginLatLong(true);
if (nSub >= 2) { if (nSub >= 2) {
LatLong ll1 = currentEvent.getSubDetection(0).getOriginLatLong(true); LatLong ll1 = subDets.get(0).getSubDetection().getOriginLatLong(true);
LatLong ll2 = currentEvent.getSubDetection(nSub-1).getOriginLatLong(true); LatLong ll2 = subDets.get(nSub-1).getSubDetection().getOriginLatLong(true);
if (ll1 != null & ll2 != null) { if (ll1 != null & ll2 != null) {
double lat = (ll1.getLatitude() + ll2.getLatitude())/2.; double lat = (ll1.getLatitude() + ll2.getLatitude())/2.;
double lon = (ll1.getLongitude() + ll2.getLongitude())/2.; double lon = (ll1.getLongitude() + ll2.getLongitude())/2.;