Squashed commit of the following:

commit 11ba8bf91e
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:45:47 2022 +0100

    MErge from DG Branch (#47)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

    * UDP Control

    Added multiport functionality

commit 9a9f542d95
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:42:45 2022 +0100

    Merge DG to Main (#46)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

    * UDP Control

    Added multiport functionality

commit 49cd547aee
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:40:29 2022 +0100

    Merge DG branch (#45)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

    * UDP Control

    Added multiport functionality

commit 016cfd0da5
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Thu Aug 4 11:35:06 2022 +0100

    Dialog positioning

    New functions to better positions dialogs on screen

commit c9f2ab3e97
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Aug 1 11:13:24 2022 +0100

    puch to main (#44)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

    * Work on batch processing, after testing of options to autostart,
    autoexit and set wav file folder, database and binary store.

    * Update MHTClickTrainAlgorithm.java

    Fix unsynchronised access to a datablock in click train detector which was causing index errors.

    * Revamp of offline process messaging and control

    Includes some databsae logging of completed tasks

    * Offline task logging

    Bit more work, including notes and database storage of task
    reprocessing. Guess this could all become 'proper' PAMGuard data and be
    shown in a table on the display but that not priority enough.

    * Dialog packing

    Fix a couple of dialogs which don't back well on HDPI monitors

commit 55f5a3fcf1
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Mon Aug 1 10:59:36 2022 +0100

    Group detections menu

    Small changes to limit the number of menu items in "Add to existing
    group" to a maximum of 25 entries.

commit b3f6c0e665
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 29 10:50:45 2022 +0100

    Handle -nogui option in PamWorker

    PamWorker used to catalog files at startup (if a file folder input
    system is used). This creates a progress dialog. Stop it appearing in
    -nogui operations.

commit 8569b6b579
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Fri Jul 22 08:30:47 2022 +0100

    Click display fixes (#41)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

    * Click detector display fixes

    1. ICI not displaying correctly
    2. Component sizes in display dialog on hres monitors

commit 128a512ff6
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 19 16:37:57 2022 +0100

    Another attempt at stopping it crashing on a headless system

    Dealing with displays that get created for clickangle vetos and a call
    to the gui in the click train detector.

commit 6eaa6e4978
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 19 08:20:07 2022 +0100

    nogoi fix for headless systems. (#40)

    * Variable sound output level

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.

    * Code to support nogui operations when no screens present on headless
    system

    * Fix problem of nogui headless operation trying to access screen size.

commit 9fdd30556b
Author: Douglas Gillespie <50671166+douggillespie@users.noreply.github.com>
Date:   Tue Jul 12 15:53:07 2022 +0100

    Variable sound output level (#39)

    Mods to SoundPlayback module to allow additional parameters. Implemented
    system for NI cards to allow changes to selected output voltage range
    meaning output can be boosted to level higher than current default.
This commit is contained in:
Jamie Mac 2022-08-04 14:07:49 +01:00
parent 601d7b9385
commit 36fb1e0e3d
64 changed files with 1850 additions and 438 deletions

View File

@ -274,7 +274,7 @@
<url>https://artifacts.unidata.ucar.edu/repository/unidata-all/</url>
</repository>
<!-- -->
<!--
<repository>
<snapshots>
<enabled>false</enabled>
@ -282,7 +282,7 @@
<id>geomajas</id>
<name>geomajas</name>
<url>http://maven.geomajas.org/</url>
</repository>
</repository>-->
<!-- Repo for Renjin Script Engine -->
<repository>

View File

@ -61,6 +61,7 @@ import PamView.dialog.PamLabel;
import PamView.dialog.warn.WarnOnce;
import PamView.panel.PamPanel;
import PamView.panel.PamProgressBar;
import pamguard.GlobalArguments;
import warnings.PamWarning;
/**
@ -1075,8 +1076,17 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
@Override
public void daqHasEnded() {
// TODO Auto-generated method stub
fileListComplete();
}
/**
* Called when all files to be processed have been processed.
*/
protected void fileListComplete() {
if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
System.out.println("All sound files processed, PAMGuard can close on " + PamController.AUTOEXIT);
PamController.getInstance().batchProcessingComplete();
}
}
JPanel statusPanel;

View File

@ -79,7 +79,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings{
private FolderInputParameters folderInputParameters;
public static final String GlobalWavFolderArg = "wavfilefolder";
public static final String GlobalWavFolderArg = "-wavfilefolder";
/**
@ -652,6 +652,10 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings{
}
calculateETA();
setFolderProgress();
if (currentFile > 0 && currentFile >= allFiles.size()) {
fileListComplete();
}
// System.out.println("FolderinputSytem: daqHasEnded");
}

View File

@ -141,7 +141,7 @@ public abstract class PamControlledUnit implements SettingsNameProvider {
private ModuleStatusManager moduleStatusManager;
private ArrayList<OfflineTask> offlineTasks = new ArrayList<>();
// private ArrayList<OfflineTask> offlineTasks = new ArrayList<>();
/**
* Instance number of this module. This is simply a count of
@ -829,26 +829,27 @@ public abstract class PamControlledUnit implements SettingsNameProvider {
return worstStatus;
}
/**
* Get a list of available offline tasks for this module. This is mostly used for tasks that
* might apply to many different types of data such as a localiser. e.g. the click detector knows
* that it has bearing and click id tasks, but it doens't know that there is a localiser that can
* also operate on the clicks, so it's important the localiser registers it's class and has it set
* to the right input data so that the task group in the click detector can find it.
* @return the offlineTasks
*/
public ArrayList<OfflineTask> getOfflineTasks() {
return offlineTasks;
}
/**
* Add an offline task, which will become available to other modules should a
* TaskGroup request all available tasks from the system.
* @param offlineTask the offlineTask to add
*/
public void addOfflineTask(OfflineTask offlineTask) {
this.offlineTasks.add(offlineTask);
}
// /**
// * Get a list of available offline tasks for this module. This is mostly used for tasks that
// * might apply to many different types of data such as a localiser. e.g. the click detector knows
// * that it has bearing and click id tasks, but it doens't know that there is a localiser that can
// * also operate on the clicks, so it's important the localiser registers it's class and has it set
// * to the right input data so that the task group in the click detector can find it.
// * @return the offlineTasks
// */
// public ArrayList<OfflineTask> getOfflineTasks() {
// moved to Global OfflineTaskManager class which does everything !
// return offlineTasks;
// }
//
// /**
// * Add an offline task, which will become available to other modules should a
// * TaskGroup request all available tasks from the system.
// * @param offlineTask the offlineTask to add
// */
// public void addOfflineTask(OfflineTask offlineTask) {
// this.offlineTasks.add(offlineTask);
// }
public BackupInformation getBackupInformation() {
return null;

View File

@ -43,6 +43,7 @@ import Acquisition.AcquisitionProcess;
import pamScrollSystem.AbstractScrollManager;
import pamViewFX.PamGuiManagerFX;
import pamViewFX.pamTask.PamTaskUpdate;
import pamguard.GlobalArguments;
import pamguard.Pamguard;
import soundPlayback.PlaybackControl;
import warnings.PamWarning;
@ -51,8 +52,10 @@ import zipUnpacker.ZipUnpacker;
import fftManager.FFTDataBlock;
import fftManager.FFTDataUnit;
import generalDatabase.DBControlUnit;
import javafx.application.Platform;
import javafx.stage.Stage;
import Array.ArrayManager;
import PamController.command.MultiportController;
import PamController.command.NetworkController;
import PamController.command.TerminalController;
import PamController.command.WatchdogComms;
@ -128,6 +131,11 @@ public class PamController implements PamControllerInterface, PamSettings {
public static final int RUN_NETWORKRECEIVER = 5;
private int runMode = RUN_NORMAL;
// flag used in main() to indicate that processing should start immediately.
public static final String AUTOSTART = "-autostart";
// flag used in main() to indicate that pamguard should exit as soon as processing ends.
public static final String AUTOEXIT = "-autoexit";
/**
* The pam model.
@ -248,6 +256,9 @@ public class PamController implements PamControllerInterface, PamSettings {
if (pamBuoyGlobals.getNetworkControlPort() != null) {
networkController = new NetworkController(this);
}
if (pamBuoyGlobals.getMultiportAddress() != null) {
new MultiportController(this);
}
// binaryStore = new BinaryStore(this);
@ -300,10 +311,33 @@ public class PamController implements PamControllerInterface, PamSettings {
public static void create(int runMode) {
if (uniqueController == null) {
PamController pamcontroller = new PamController(runMode, null);
// I don't see any reason not have have this running with the GUI.
/*
* I don't see any reason not have have this running with the GUI.
* It launches in a new thread, so it should be fine to have
* additional commands afterwards.
*/
TerminalController tc = new TerminalController(pamcontroller);
tc.getTerminalCommands();
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
uniqueController.creationComplete();
}
});
}
/**
* Not to sound God like, but this will be called on the AWT dispatch thread shortly
* after all modules are created, PAMGuard should be fully setup and all modules will
* have recieved INITIALISATION_COMPLETE and should be good to run
*/
private void creationComplete() {
if (GlobalArguments.getParam(PamController.AUTOSTART) != null) {
startLater(); // may as well give AWT time to loop it's queue once more
}
}
/**
@ -526,6 +560,7 @@ public class PamController implements PamControllerInterface, PamSettings {
clearSelectorsAndSymbols();
/**
* Debug code for starting PG as soon as it's initialised.
*/
@ -660,11 +695,24 @@ public class PamController implements PamControllerInterface, PamSettings {
@Override
public void pamClose() {
getUidManager().runShutDownOps();
for (int i = 0; i < pamControlledUnits.size(); i++) {
pamControlledUnits.get(i).pamClose();
}
}
/**
* Shut down Pamguard
*/
public void shutDownPamguard() {
// force close the javaFX thread (because it won't close by itself - see Platform.setImplicitExit(false) in constructor
Platform.exit();
// terminate the JVM
System.exit(0);
}
/**
* Go through all data blocks in all modules and tell them to save.
* This has been built into PamProcess and PamDataBlock since we want
@ -1297,6 +1345,25 @@ public class PamController implements PamControllerInterface, PamSettings {
pamControlledUnits.get(iU).pamHasStopped();
}
guiFrameManager.pamEnded();
// no good having this here since it get's called at the end of every file.
// if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
//// can exit here, since we've auto started, can auto exit.
// if (canClose()) {
// pamClose();
// shutDownPamguard();
// }
// }
}
public void batchProcessingComplete( ) {
if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
// can exit here, since we've auto started, can auto exit.
if (canClose()) {
pamClose();
shutDownPamguard();
}
}
}

View File

@ -307,7 +307,10 @@ public interface PamControllerInterface {
public static final int REORDER_CONTROLLEDUNITS = 8;
/**
* Automatically sent when PAMGAURD has finished loading it's
* initial settings file and created the GUI
* initial settings file and created the GUI. It's a good time for modules
* to subscribe to their data sources, but they shouldn't do much else since
* these go around in order, so when this arrives in the first module, other
* modules may not yet be setup.
*/
public static final int INITIALIZATION_COMPLETE = 9;
/**
@ -404,6 +407,13 @@ public interface PamControllerInterface {
* The medium has been updated.
*/
public static final int GLOBAL_MEDIUM_UPDATE = 24;
/**
* Sent shortly after the main PAMGUard setup has been completed, but this point
* all modules will have received INITIALIZATION_COMPLETE and should be ready to
* go.
*/
public static final int READY_TO_RUN = 25;

View File

@ -33,13 +33,8 @@ import java.io.IOException;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
@ -47,11 +42,6 @@ import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;
import GPS.GPSParameters;
import GPS.UpdateClockDialog;
import binaryFileStorage.BinaryStoreSettings;
import offlineProcessing.OfflineProcessingControlledUnit;
import offlineProcessing.OfflineProcessingProcess;
import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
import pamViewFX.fxSettingsPanes.SettingsFileDialogFX;

View File

@ -0,0 +1,118 @@
package PamController.command;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import PamController.PamController;
import PamController.pamBuoyGlobals;
public class MultiportController extends CommandManager {
//The multicast addresses are in the range 224.0.0.0 through 239.255.255.255
private static String unitName = "Multiport Controller";
private PamController pamController;
private String mAddress;
private int mPort;
private MulticastSocket socket;
InetAddress inetAddr;
static private final int MAX_COMMAND_LENGTH = 4096;
private byte[] byteBuffer = new byte[MAX_COMMAND_LENGTH];
private DatagramPacket lastDatagram;
public MultiportController(PamController pamController) {
super(pamController, unitName);
this.pamController = pamController;
this.mAddress = pamBuoyGlobals.getMultiportAddress();
this.mPort = pamBuoyGlobals.getMuliportPort();
Thread t = new Thread(new ListenerThread());
t.start();
}
public void runListenerLoop() {
try {
// inetAddr = InetAddress.getByName(mAddress);
// SocketAddress sockAddr = new SocketAddress()
// socket = new MulticastSocket(mPort);
// socket.joinGroup(inetAddr, null);
// socket.joinG
// open port
InetAddress mcastaddr = InetAddress.getByName(mAddress);
InetSocketAddress group = new InetSocketAddress(mcastaddr, mPort);
NetworkInterface netIf = NetworkInterface.getByName("bge0");
socket = new MulticastSocket(mPort);
socket.joinGroup(group, netIf);
socket.setSoTimeout(0);
System.out.printf("Waiting for multicast messages at %s port %d\n", mAddress, mPort);
// sit in loop
while (true) {
try {
DatagramPacket datagram = new DatagramPacket(byteBuffer, MAX_COMMAND_LENGTH);
socket.receive(datagram);
processDatagram(datagram);
}
catch (IOException ioE) {
ioE.printStackTrace();
break;
}
}
// close port.
socket.leaveGroup(group, netIf);
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void processDatagram(DatagramPacket datagram) {
lastDatagram = datagram;
String str = new String(datagram.getData(), 0, datagram.getLength());
// str = str.substring(0, datagram.getLength());
System.out.println("Datagram received \"" + str + "\"");
interpretCommand(str);
}
@Override
public boolean sendData(String dataString) {
DatagramPacket senderInfo = lastDatagram;
System.out.printf("Send back data \"%s\" to %s port %d\n", dataString, senderInfo.getAddress(), senderInfo.getPort());
// dataString += "\n";
DatagramPacket packet = new DatagramPacket(dataString.getBytes(), dataString.length());
packet.setAddress(senderInfo.getAddress());
packet.setPort(senderInfo.getPort());
try {
socket.send(packet);
// receiveSocket.
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
private class ListenerThread implements Runnable {
@Override
public void run() {
runListenerLoop();
}
}
}

View File

@ -14,7 +14,9 @@ public class pamBuoyGlobals {
// public static Integer useGstreamer = 0;
// public static boolean useNetworkCont = false;
private static Integer networkControlPort = null;
private static String multiportAddress;
// private static boolean useDSP = false;
private static int muliportPort;
/**
* @return the networkControlPort
@ -29,6 +31,31 @@ public class pamBuoyGlobals {
public static void setNetworkControlPort(Integer networkControlPort) {
pamBuoyGlobals.networkControlPort = networkControlPort;
}
/**
* Set parameters for mulitport configutation.
* @param mAddr
* @param mPort
*/
public static void setMultiportConfig(String mAddr, int mPort) {
multiportAddress = mAddr;
muliportPort = mPort;
}
/**
* @return the multiportAddress
*/
public static String getMultiportAddress() {
return multiportAddress;
}
/**
* @return the muliportPort
*/
public static int getMuliportPort() {
return muliportPort;
}
//public static HashMap pbHash = new HashMap(10,0.75);

View File

@ -392,11 +392,11 @@ final public class PamModel implements PamModelInterface, PamSettings {
// mi.setModulesMenuGroup(utilitiesGroup);
// mi.setHidden(SMRUEnable.isEnable() == false);
mi = PamModuleInfo.registerControlledUnit("offlineProcessing.OfflineProcessingControlledUnit", "Offline Processing");
mi.setModulesMenuGroup(utilitiesGroup);
mi.setMinNumber(0);
mi.setMaxNumber(1);
mi.setHidden(SMRUEnable.isEnable() == false);
// mi = PamModuleInfo.registerControlledUnit("offlineProcessing.OfflineProcessingControlledUnit", "Offline Processing");
// mi.setModulesMenuGroup(utilitiesGroup);
// mi.setMinNumber(0);
// mi.setMaxNumber(1);
// mi.setHidden(SMRUEnable.isEnable() == false);
mi = PamModuleInfo.registerControlledUnit(TurbineOperationControl.class.getName(), TurbineOperationControl.unitType);

View File

@ -44,7 +44,10 @@ public class PamWorker<T> {
*/
public PamWorker(PamWorkWrapper<T> pamWorkWrapper, Window parentFrame, int nTextRows, String title) {
this.pamWorkWrapper = pamWorkWrapper;
if (PamGUIManager.isFX()) {
if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) {
}
else if (PamGUIManager.isFX()) {
//TODO - make a node that can be extracted here.
pamWorkProgress = new PamWorkerProgressFX();
}

View File

@ -32,6 +32,7 @@ public class NullGuiController implements PAMControllerGUI {
@Override
public void pamEnded() {
// TODO Auto-generated method stub
}

View File

@ -1659,7 +1659,8 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
}
// deal with anything that needs sorting out in the realm of UID's.
pamController.getUidManager().runShutDownOps();
// move this to pamController.pamClose()
// pamController.getUidManager().runShutDownOps();
// if the user doesn't want to save the config file, make sure they know
// that they'll lose any changes to the settings
@ -1685,7 +1686,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
pamControllerInterface.pamClose();
// shut down the JavaFX thread and the JVM
this.shutDownPamguard();
pamController.shutDownPamguard();
return true;
}

View File

@ -86,15 +86,5 @@ abstract public class PamView implements PamViewInterface {
this.frameNumber = frameNumber;
}
/**
* Shut down Pamguard
*/
public void shutDownPamguard() {
// force close the javaFX thread (because it won't close by itself - see Platform.setImplicitExit(false) in constructor
Platform.exit();
// terminate the JVM
System.exit(0);
}
}

View File

@ -10,6 +10,7 @@ import javax.swing.SwingUtilities;
import com.sun.glass.ui.Screen;
import PamController.PamGUIManager;
import javafx.scene.layout.Pane;
/**
@ -138,40 +139,49 @@ public class ScreenSize {
private static Rectangle findScreenBounds() {
Rectangle virtualBounds = new Rectangle();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs =ge.getScreenDevices();
nScreens = gs.length;
screenDimensions = new Rectangle[nScreens];
for (int j = 0; j < gs.length; j++) {
GraphicsDevice gd = gs[j];
//Think to get screen sizes on multiple monitors
//can just use getDefaultConfiguration for
//each device rather than looping over
//all configurations. Hopefully should
//let PAMGUARD start up a little quicker
//CJB 2009-06-15
GraphicsConfiguration dgc = gd.getDefaultConfiguration();
// System.out.printf("", dgc.getBufferCapabilities().)
// System.out.println(dgc);
screenDimensions[j] = dgc.getBounds();
virtualBounds = virtualBounds.union(dgc.getBounds());
}
// new Pane();
// List<Screen> screens = Screen.getScreens();
// if (screens != null) {
// for (Screen aScreen : screens) {
// System.out.printf("Screen resX %d, resY %d\n",
// aScreen.getResolutionX(),
// aScreen.getResolutionY());
// }
// }
if (PamGUIManager.getGUIType() == PamGUIManager.NOGUI) {
virtualBounds = new Rectangle(0,0,1024,768);
nScreens = 1;
screenDimensions = new Rectangle[nScreens];
screenDimensions[0] = virtualBounds;
}
else {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs =ge.getScreenDevices();
nScreens = gs.length;
screenDimensions = new Rectangle[nScreens];
for (int j = 0; j < gs.length; j++) {
GraphicsDevice gd = gs[j];
//Think to get screen sizes on multiple monitors
//can just use getDefaultConfiguration for
//each device rather than looping over
//all configurations. Hopefully should
//let PAMGUARD start up a little quicker
//CJB 2009-06-15
GraphicsConfiguration dgc = gd.getDefaultConfiguration();
// System.out.printf("", dgc.getBufferCapabilities().)
// System.out.println(dgc);
screenDimensions[j] = dgc.getBounds();
virtualBounds = virtualBounds.union(dgc.getBounds());
}
}
// new Pane();
// List<Screen> screens = Screen.getScreens();
// if (screens != null) {
// for (Screen aScreen : screens) {
// System.out.printf("Screen resX %d, resY %d\n",
// aScreen.getResolutionX(),
// aScreen.getResolutionY());
// }
// }
//System.out.println("virtualBounds="+virtualBounds);
return virtualBounds;
}
// /**
// * Thread to obtain the screen bounds.
// /**
// * Thread to obtain the screen bounds.
// * @author Doug
// *
// */

View File

@ -40,6 +40,7 @@ import PamModel.SMRUEnable;
import PamView.CancelObserver;
import PamView.ClipboardCopier;
import PamView.PamColors;
import PamView.ScreenSize;
import PamView.help.PamHelp;
import gpl.GPLParameters;
@ -151,6 +152,56 @@ abstract public class PamDialog extends JDialog {
return null;
}
}
/**
* Try to set the central location of the dialog at point
* but also check entire dialog is on screen.
* @param point
*/
protected void setCentreLocation(Point point) {
if (point == null) {
return;
}
Rectangle dialogBounds = this.getBounds();
if (dialogBounds == null) {
return;
}
point.x -= dialogBounds.width/2;
point.y -= dialogBounds.height/2;
setCloseLocation(point);
}
/**
* Set a location as close as possible to the given point, but
* ensure that the dialog stays in it's parent frame.
* If there isn't a parent frame, make sure it's at least on
* the screen.
* @param point
*/
protected void setCloseLocation(Point point) {
if (point == null) {
return;
}
try {
Rectangle frameRect = ScreenSize.getScreenBounds();
if (getOwner() != null) {
frameRect = getOwner().getBounds();
}
Rectangle dialogBounds = this.getBounds();
/*
* Check max first, then min in case dialog is too big for screen. Ensures
* top left will always be visible.
*/
point.x = Math.min(point.x, frameRect.x+frameRect.width-dialogBounds.width);
point.x = Math.max(point.x, frameRect.x);
point.y = Math.min(point.y, frameRect.y+frameRect.height-dialogBounds.height);
point.y = Math.max(point.y, frameRect.y);
super.setLocation(point);
}
catch (Exception e) {
}
}
protected void positionInFrame(Window parentFrame) {
if (parentFrame == null) {

View File

@ -157,7 +157,10 @@ public abstract class OverlayDataManager<TOverlayInfoType extends OverlayDataInf
}
protected GeneralProjector getProjector() {
// TODO Auto-generated method stub
/**
* Not 100% sure why, but this needs to return non-null if
* the overlay symbol and data select dialog is to be built correctly.
*/
return null;
}

View File

@ -49,6 +49,11 @@ public class ExtMapMouseHandler extends ExtMouseAdapter {
this.compositePopupMenus = compositePopupMenus;
}
/**
*
* @param awtWindow
* @param compositePopupMenus
*/
public ExtMapMouseHandler(Window awtWindow, boolean compositePopupMenus) {
this.awtWindow = awtWindow;
this.compositePopupMenus = compositePopupMenus;

View File

@ -9,6 +9,7 @@ import javax.swing.JMenuItem;
import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings;
import PamController.PamGUIManager;
import PamController.PamSettingManager;
import PamController.PamSettings;
@ -35,7 +36,10 @@ public class AngleVetoes extends Object implements PamSettings {
super();
this.pamControlledUnit = pamControlledUnit;
angleVetoDisplay = new AngleVetoDisplay(this);
if (PamGUIManager.getGUIType() != PamGUIManager.NOGUI) {
angleVetoDisplay = new AngleVetoDisplay(this);
}
PamSettingManager.getInstance().registerSettings(this);
}
@ -96,7 +100,9 @@ public class AngleVetoes extends Object implements PamSettings {
AngleVetoParameters newParams = AngleVetoesDialog.showDialog(frame, this);
if (newParams != null) {
angleVetoParameters = newParams.clone();
angleVetoDisplay.repaint();
if (angleVetoDisplay != null) {
angleVetoDisplay.repaint();
}
}
}
@ -132,7 +138,9 @@ public class AngleVetoes extends Object implements PamSettings {
}
private void displayAction(Frame frame) {
angleVetoDisplay.setVisible(true);
if (angleVetoDisplay != null) {
angleVetoDisplay.setVisible(true);
}
}
/**
@ -205,7 +213,9 @@ public class AngleVetoes extends Object implements PamSettings {
* @param angle angle in degrees
*/
public void addAngleData(double angle) {
angleVetoDisplay.newAngle(angle);
if (angleVetoDisplay != null) {
angleVetoDisplay.newAngle(angle);
}
}
/**
@ -213,6 +223,8 @@ public class AngleVetoes extends Object implements PamSettings {
* @param pass true if there was a pass, false for a fail.
*/
public void addPassData(boolean pass) {
angleVetoDisplay.newPassData(pass);
if (angleVetoDisplay != null) {
angleVetoDisplay.newPassData(pass);
}
}
}

View File

@ -45,7 +45,7 @@ public class AnnotationDialog extends PamDialog {
AnnotationDialog annotationDialog = new AnnotationDialog(parentFrame, dataAnnotationType, dataUnit);
if (positionInFrame != null) {
annotationDialog.setLocation(positionInFrame);
annotationDialog.setCentreLocation(positionInFrame);
}
annotationDialog.setParams();
annotationDialog.setVisible(true);

View File

@ -16,6 +16,7 @@ import com.synthbot.jasiohost.AsioSampleType;
import PamController.PamController;
import PamDetection.RawDataUnit;
import PamUtils.PamUtils;
import PamView.dialog.PamDialogPanel;
import PamguardMVC.PamConstants;
import soundPlayback.FilePlayback;
import soundPlayback.FilePlaybackDevice;
@ -334,4 +335,10 @@ public class ASIOFilePlaybackSystem implements FilePlaybackDevice {
return null;
}
@Override
public PamDialogPanel getSettingsPanel() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -21,7 +21,7 @@ public class BinaryStorageDialog extends PamDialog {
String help = "utilities.BinaryStore.docs.binarystore_overview";
setHelpPoint(help);
binaryStorageDialogPanel = new BinaryStorageDialogPanel(parentFrame, binaryStore.getClass() == SecondaryBinaryStore.class);
binaryStorageDialogPanel = new BinaryStorageDialogPanel(this, binaryStore.getClass() == SecondaryBinaryStore.class);
setDialogComponent(binaryStorageDialogPanel.getPanel());
}

View File

@ -191,6 +191,7 @@ public class BinaryStorageDialogPanel {
noiseStoreType.setSelectedItem(binaryStoreSettings.getNoiseStoreType());
enableControls();
owner.pack();
}
/**

View File

@ -3332,7 +3332,8 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
return false;
}
if (btDisplayParameters.VScale == BTDisplayParameters.DISPLAY_ICI) {
if (btDisplayParameters.showUnassignedICI == false && click.getICI() < 0) return false;
// if (btDisplayParameters.showUnassignedICI == false && click.getICI() < 0) return false;
if (btDisplayParameters.showUnassignedICI == false && click.getSuperDetectionsCount() <= 0) return false;
// otherwise may be ok, since will estimate all ici's on teh fly.
}
if (btDisplayParameters.amplitudeSelect && click.getAmplitudeDB() < btDisplayParameters.minAmplitude) {

View File

@ -10,6 +10,7 @@ import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JToolBar;
@Deprecated // - not used
public class ClickToolBar implements ActionListener{
private JToolBar toolBar;
@ -18,7 +19,7 @@ public class ClickToolBar implements ActionListener{
private ClickTabPanelControl clickTabPanelControl;
public ClickToolBar(ClickTabPanelControl clickTabPanelControl) {
private ClickToolBar(ClickTabPanelControl clickTabPanelControl) {
this.clickTabPanelControl = clickTabPanelControl;
toolBar = new JToolBar();

View File

@ -106,6 +106,7 @@ public class ClickDisplayDialog extends PamDialog implements ActionListener {
btPanel.setParams(btDisplayParameters);
sizePanel.setParams(btDisplayParameters);
speciesPanel.setParams(btDisplayParameters);
pack();
}
@Override

View File

@ -599,7 +599,7 @@ public class ClicksOffline {
* need click id and initial localisation information.
*/
// offlineTaskGroup.addTasks(clickControl.getOfflineTasks());
OfflineTaskManager.addAvailableTasks(offlineTaskGroup, clickControl.getClickDataBlock());
OfflineTaskManager.getManager().addAvailableTasks(offlineTaskGroup, clickControl.getClickDataBlock());
OfflineSuperDetFilter sdf = OfflineSuperDetFilter.makeSuperDetFilter(clickControl.getClickDataBlock(), clickControl.getUnitName()+"SuperDetFilter");
offlineTaskGroup.setSuperDetectionFilter(sdf);
// offlineTaskGroup.addTask(new ClickTrainClass(clickControl)); // bad idea !

View File

@ -246,7 +246,10 @@ public class ClickTrainControl extends PamControlledUnit implements PamSettings
this.ctLocalisationProcess.setTMlocParams(this.clickTrainParams);
this.getGUI(PamGUIManager.getGUIType()).notifyGUIChange(ClickTrainControl.NEW_PARAMS);
PamControlledUnitGUI gui = this.getGUI(PamGUIManager.getGUIType());
if (gui != null) {
gui.notifyGUIChange(ClickTrainControl.NEW_PARAMS);
}
}
/**

View File

@ -12,6 +12,7 @@ import PamUtils.PamCalendar;
import PamguardMVC.PamDataUnit;
import PamguardMVC.debug.Debug;
import clickTrainDetector.ClickTrainControl;
import clickTrainDetector.ClickTrainDataBlock;
import clickTrainDetector.TempCTDataUnit;
import clickTrainDetector.CTDataUnit;
import clickTrainDetector.clickTrainAlgorithms.CTAlgorithmInfo;
@ -287,16 +288,19 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
*/
private synchronized void grabUnconfirmedTrains(MHTAlgorithm mhtAlgorithm) {
ListIterator<TempCTDataUnit> iterator = clickTrainControl.getClickTrainProcess().getUnconfirmedCTDataBlock().getListIterator(0);
//clear the data block
TempCTDataUnit tempCTUnit;
while (iterator.hasNext()) {
tempCTUnit = iterator.next();
tempCTUnit.removeAllSubDetections();
tempCTUnit.clearSubdetectionsRemoved();
ClickTrainDataBlock<TempCTDataUnit> unconfirmedBlock = clickTrainControl.getClickTrainProcess().getUnconfirmedCTDataBlock();
synchronized (unconfirmedBlock.getSynchLock()) {
ListIterator<TempCTDataUnit> iterator = unconfirmedBlock.getListIterator(0);
//clear the data block
TempCTDataUnit tempCTUnit;
while (iterator.hasNext()) {
tempCTUnit = iterator.next();
tempCTUnit.removeAllSubDetections();
tempCTUnit.clearSubdetectionsRemoved();
}
unconfirmedBlock.clearAll();
}
clickTrainControl.getClickTrainProcess().getUnconfirmedCTDataBlock().clearAll();
if (mhtAlgorithm.mhtKernal.getActiveTracks()==null) return;

View File

@ -6,6 +6,7 @@ import offlineProcessing.OLProcessDialog;
import offlineProcessing.OfflineTask;
import offlineProcessing.OfflineTaskGroup;
import offlineProcessing.TaskMonitor;
import offlineProcessing.TaskStatus;
/**
* A click train offline dialog which ensure that the click train offline
@ -33,7 +34,7 @@ public class CTProcessDialog extends OLProcessDialog {
* @param task - the task group in whihc enable controls has been called from
*/
public void enableControls(OfflineTask task) {
boolean nr = getCurrentStatus() != TaskMonitor.TASK_RUNNING;
boolean nr = getCurrentStatus() != TaskStatus.RUNNING;
int nTasks = getTaskGroup().getNTasks();
OfflineTask aTask;
int selectedTasks = 0;

View File

@ -4,6 +4,9 @@ import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
@ -19,6 +22,7 @@ import PamView.PamSymbol;
import PamView.paneloverlay.overlaymark.OverlayMark;
import PamView.paneloverlay.overlaymark.OverlayMarkObserver;
import PamView.paneloverlay.overlaymark.OverlayMarker;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.debug.Debug;
import javafx.scene.input.MouseEvent;
@ -112,12 +116,13 @@ public class EventBuilderFunctions {
public JPopupMenu getPopupMenuItems(DetectionGroupSummary groupSummary) {
//Debug.out.println("Detection Group Localiser Pop Up Options: " + groupSummary.getNumDataUnits());
if (groupSummary == null || groupSummary.getNumDataUnits() == 0) {
noDataWarning.setEndOfLife(PamCalendar.getTimeInMillis() + 5000);
WarningSystem.getWarningSystem().addWarning(noDataWarning);
return null;
}
long currentTime = groupSummary.getFirstTimeMillis();
JPopupMenu popMenu = new JPopupMenu(detectionGroupControl.getUnitName());
// get information about what's in the currently selected data units.
@ -163,17 +168,24 @@ public class EventBuilderFunctions {
popMenu.add(menuItem);
// now a submenu listing all other groups in memory ...
JMenu subMenu = new JMenu("Add to existing group");
int maxItems = 25; // if more than this, then limit to colsest ones.
int nAdded = 0;
ListIterator<DetectionGroupDataUnit> gdIterator = gdDataBlock.getListIterator(0);
// ListIterator<DetectionGroupDataUnit> gdIterator = gdDataBlock.getListIterator(0);
ListIterator<DetectionGroupDataUnit> gdIterator = getGroupsForMenu(gdDataBlock, currentTime, maxItems);
while (gdIterator.hasNext()) {
DetectionGroupDataUnit gdUnit = gdIterator.next();
// if (superDets.contains(gdUnit)) {
// continue;
// }
String tit = String.format("Add %d %s to group with UID %d", groupSummary.getNumDataUnits(), dataName, gdUnit.getUID());
String tit = String.format("Add %d %s to group UID %d", groupSummary.getNumDataUnits(), dataName,
gdUnit.getUID());
String tip = String.format("Group start %s, end %s",
PamCalendar.formatDBDateTime(gdUnit.getTimeMilliseconds()),
PamCalendar.formatTime(gdUnit.getEndTimeInMilliseconds()));
Color detColor = PamColors.getInstance().getWhaleColor((int) gdUnit.getUID());
PamSymbol sym = new PamSymbol(detectionGroupControl.getSymbolforMenuItems(gdUnit));
menuItem = new JMenuItem(tit, sym);
menuItem.setToolTipText(tip);
menuItem.addActionListener(new AddToExisting(groupSummary, gdUnit));
subMenu.add(menuItem);
nAdded++;
@ -201,6 +213,40 @@ public class EventBuilderFunctions {
return popMenu;
}
/**
* Get a shortened list of menu items for adding to the group. This is all a bit complicated
* since there are often too many and we want the ones closest to our time. Therefore have
* to mess about copying, sorting and relisting things.
* @param groupDataBlock
* @param targetTime
* @param maxEntries
* @return
*/
private ListIterator<DetectionGroupDataUnit> getGroupsForMenu(DetectionGroupDataBlock groupDataBlock, long targetTime, int maxEntries) {
if (groupDataBlock.getUnitsCount() < maxEntries) {
return groupDataBlock.getListIterator(0);
}
ArrayList<DetectionGroupDataUnit> dataCopy = groupDataBlock.getDataCopy();
dataCopy.sort(new Comparator<DetectionGroupDataUnit>() {
@Override
public int compare(DetectionGroupDataUnit o1, DetectionGroupDataUnit o2) {
long t1 = Math.abs(o1.getTimeMilliseconds()-targetTime);
long t2 = Math.abs(o2.getTimeMilliseconds()-targetTime);
return (int) Math.signum((t1-t2));
}
});
// now reduce the size of the list to the allowed number
List<DetectionGroupDataUnit> dataCopy2 = dataCopy.subList(0, maxEntries-1);
dataCopy2.sort(new Comparator<DetectionGroupDataUnit>() {
@Override
public int compare(DetectionGroupDataUnit o1, DetectionGroupDataUnit o2) {
return (int) Math.signum(o1.getTimeMilliseconds()-o2.getTimeMilliseconds());
}
});
return dataCopy2.listIterator();
}
private class AddToExisting implements ActionListener {

View File

@ -238,7 +238,7 @@ public abstract class SuperDetLogging extends SQLLogging {
/**
* Modified view clause for super detections, may change the basic clause to either get absolutely
* everything, or to get events that overlap with the load time, no tjust start within it (requires a
* everything, or to get events that overlap with the load time, not just start within it (requires a
* reference to an endtime column)
* @param con
* @param pamViewParameters

View File

@ -122,7 +122,8 @@ public class SqliteSystem extends DBSystem implements PamSettings {
File newFile = new File(databaseName);
// if the file doesn't exit, consider creating it.
if (newFile.exists() == false) {
newFile = createNewDatabase(databaseName, null, true);
boolean ask = GlobalArguments.getParam(DBControl.GlobalDatabaseNameArg) == null;
newFile = createNewDatabase(databaseName, null, ask);
if (newFile == null) {
System.out.println("Unable to create "+newFile);
return;

View File

@ -56,7 +56,7 @@ public class Group3DLocaliserControl extends PamControlledUnit implements PamSet
* only used in viewer, but no hard in creating it.
*/
g3DOfflineTask = new Group3DOfflineTask(this);
addOfflineTask(g3DOfflineTask);
// addOfflineTask(g3DOfflineTask);
}
@Override

View File

@ -1,10 +1,15 @@
package nidaqdev;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import PamController.PamControlledUnitSettings;
import PamController.PamSettingManager;
import PamController.PamSettings;
import PamDetection.RawDataUnit;
import PamUtils.PamUtils;
import PamView.dialog.PamDialogPanel;
import soundPlayback.FilePlayback;
import soundPlayback.FilePlaybackDevice;
import soundPlayback.PlayDeviceState;
@ -17,7 +22,7 @@ import soundPlayback.PlaybackParameters;
* @author Doug Gillespie
*
*/
public class NIFilePlayback implements FilePlaybackDevice {
public class NIFilePlayback implements FilePlaybackDevice, PamSettings {
private volatile boolean prepared;
@ -39,9 +44,14 @@ public class NIFilePlayback implements FilePlaybackDevice {
private NIDeviceInfo currentDeviceInfo;
private NIPlaybackSettingsPanel playSettingsPanel;
private NIFilePlaybackParams niFilePlaybackParams = new NIFilePlaybackParams();
public NIFilePlayback(FilePlayback filePlayback) {
super();
this.filePlayback = filePlayback;
PamSettingManager.getInstance().registerSettings(this);
niDaq = new Nidaq();
getNIDevices();
}
@ -131,7 +141,7 @@ public class NIFilePlayback implements FilePlaybackDevice {
}
int playRate = (int) playbackParameters.getPlaybackRate();
int ans = niDaq.javaPreparePlayback(bn, playRate, playRate, outchans);
int ans = niDaq.javaPreparePlayback(bn, playRate, playRate, outchans, (float) niFilePlaybackParams.outputRange);
// System.out.println("NI Answer = " + ans);
prepared = (ans == 0);
return prepared;
@ -163,4 +173,59 @@ public class NIFilePlayback implements FilePlaybackDevice {
}
}
@Override
public PamDialogPanel getSettingsPanel() {
if (playSettingsPanel == null) {
playSettingsPanel = new NIPlaybackSettingsPanel(this);
}
return playSettingsPanel;
}
/**
* @return the niFilePlaybackParams
*/
public NIFilePlaybackParams getNiFilePlaybackParams() {
return niFilePlaybackParams;
}
/**
* @param niFilePlaybackParams the niFilePlaybackParams to set
*/
public void setNiFilePlaybackParams(NIFilePlaybackParams niFilePlaybackParams) {
this.niFilePlaybackParams = niFilePlaybackParams;
}
@Override
public String getUnitName() {
return "NIFilePalybackSettings";
}
@Override
public String getUnitType() {
return "NIFilePalybackSettings";
}
@Override
public Serializable getSettingsReference() {
return niFilePlaybackParams;
}
@Override
public long getSettingsVersion() {
return NIFilePlaybackParams.serialVersionUID;
}
@Override
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
niFilePlaybackParams = (NIFilePlaybackParams) pamControlledUnitSettings.getSettings();
return true;
}
/**
* @return the currentDeviceInfo
*/
public NIDeviceInfo getCurrentDeviceInfo() {
return currentDeviceInfo;
}
}

View File

@ -0,0 +1,21 @@
package nidaqdev;
import java.io.Serializable;
public class NIFilePlaybackParams implements Serializable, Cloneable{
public static final long serialVersionUID = 1L;
public double outputRange = 2.0;
@Override
protected NIFilePlaybackParams clone() {
try {
return (NIFilePlaybackParams) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,83 @@
package nidaqdev;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import PamView.dialog.PamDialog;
import PamView.dialog.PamDialogPanel;
import PamView.dialog.PamGridBagContraints;
public class NIPlaybackSettingsPanel implements PamDialogPanel {
private NIFilePlayback niFilePlayback;
private JPanel mainPanel;
private JComboBox<String> outputLevel;
public NIPlaybackSettingsPanel(NIFilePlayback niFilePlayback) {
this.niFilePlayback = niFilePlayback;
mainPanel = new JPanel(new GridBagLayout());
mainPanel.setBorder(new TitledBorder("NI Play options"));
GridBagConstraints c = new PamGridBagContraints();
mainPanel.add(new JLabel("Output level ", JLabel.RIGHT), c);
c.gridx++;
mainPanel.add(outputLevel = new JComboBox<>(), c);
c.gridx++;
mainPanel.add(new JLabel(" V(0-p)"), c);
outputLevel.addItem("1.0");
outputLevel.addItem("10.0");
}
@Override
public JComponent getDialogComponent() {
return mainPanel;
}
@Override
public void setParams() {
NIDeviceInfo deviceInfo = niFilePlayback.getCurrentDeviceInfo();
NIFilePlaybackParams params = niFilePlayback.getNiFilePlaybackParams();
if (deviceInfo == null) {
return;
}
int nRange = deviceInfo.getNumAOVoltageRanges();
outputLevel.removeAllItems();
int selInd = -1;
for (int i = 0; i < nRange; i++) {
double aRange = deviceInfo.getAOVoltageRangeEnd(i);
outputLevel.addItem(String.format("%3.1f", aRange));
if (aRange == params.outputRange) {
selInd = i;
}
}
if (selInd >= 0) {
outputLevel.setSelectedIndex(selInd);
}
}
@Override
public boolean getParams() {
NIDeviceInfo deviceInfo = niFilePlayback.getCurrentDeviceInfo();
NIFilePlaybackParams params = niFilePlayback.getNiFilePlaybackParams();
if (deviceInfo == null) {
return false;
}
int nRange = deviceInfo.getNumAOVoltageRanges();
int selInd = outputLevel.getSelectedIndex();
if (selInd < 0 || selInd >= nRange) {
return PamDialog.showWarning(null, "Invalid parameter", "Invalid output range");
}
params.outputRange = deviceInfo.getAOVoltageRangeEnd(selInd);
return true;
}
}

View File

@ -253,8 +253,20 @@ public class Nidaq {
public int javaPreparePlayback(int boardNumber, int sampleRate,
int bufferSamples, int[] outputChannelList) {
// if (loadLibraryOK) {
// return jniPreparePlayback(boardNumber, sampleRate, playVoltageRange, bufferSamples, outputChannelList);
// }
// else {
// return 0;
// }
return javaPreparePlayback(boardNumber, sampleRate, bufferSamples, outputChannelList, playVoltageRange);
}
public int javaPreparePlayback(int boardNumber, int sampleRate,
int bufferSamples, int[] outputChannelList, float outputLevel) {
if (loadLibraryOK) {
return jniPreparePlayback(boardNumber, sampleRate, playVoltageRange, bufferSamples, outputChannelList);
outputLevel = Math.abs(outputLevel);
return jniPreparePlayback(boardNumber, sampleRate, outputLevel, bufferSamples, outputChannelList);
}
else {
return 0;

View File

@ -27,12 +27,16 @@ import javax.swing.border.TitledBorder;
import PamUtils.PamCalendar;
import PamUtils.TxtFileUtils;
import PamView.CancelObserver;
import PamView.DBTextArea;
import PamView.dialog.PamDialog;
import PamView.dialog.PamFileBrowser;
import PamView.dialog.PamGridBagContraints;
import PamView.panel.PamAlignmentPanel;
import PamView.panel.PamPanel;
import PamView.panel.PamProgressBar;
import PamguardMVC.PamDataBlock;
import offlineProcessing.logging.OldTaskData;
import offlineProcessing.logging.TaskLogging;
import offlineProcessing.superdet.OfflineSuperDetFilter;
/**
@ -54,9 +58,11 @@ public class OLProcessDialog extends PamDialog {
private JCheckBox[] taskCheckBox;
private JButton[] settingsButton;
private JLabel status, currFile;
private JProgressBar globalProgress, fileProgress;
private JProgressBar globalProgress; // file by file progress 1: nFiles
private JProgressBar loadedProgress; // progress throgh loaded data
private JCheckBox deleteOldData;
private JLabel dataInfo;
private DBTextArea noteText;
/**
* Pane which can be used to add extra controls for different 'dataSelection' types.
*/
@ -85,7 +91,7 @@ public class OLProcessDialog extends PamDialog {
public static ImageIcon settings = new ImageIcon(ClassLoader.getSystemResource("Resources/SettingsButtonSmall2.png"));
int currentStatus = TaskMonitor.TASK_IDLE;
TaskStatus currentStatus = TaskStatus.IDLE;
public OLProcessDialog(Window parentFrame, OfflineTaskGroup taskGroup, String title) {
@ -96,7 +102,8 @@ public class OLProcessDialog extends PamDialog {
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JPanel dataSelectPanel = new JPanel(new BorderLayout());
JPanel dataSelectPanel = new PamAlignmentPanel(BorderLayout.WEST);
dataSelectPanel.setLayout(new BorderLayout());
dataSelectPanel.setBorder(new TitledBorder("Data Options"));
dataSelectPanel.add(BorderLayout.WEST, new JLabel("Data "));
dataInfo = new JLabel(" ", SwingConstants.CENTER); // create this first to avoid null pointer exception
@ -124,7 +131,8 @@ public class OLProcessDialog extends PamDialog {
dataSelectPanel.add(BorderLayout.SOUTH, southPanel);
JPanel tasksPanel = new JPanel(new GridBagLayout());
JPanel tasksPanel = new PamAlignmentPanel(BorderLayout.WEST);
tasksPanel.setLayout(new GridBagLayout());
tasksPanel.setBorder(new TitledBorder("Tasks"));
int nTasks = taskGroup.getNTasks();
taskCheckBox = new JCheckBox[nTasks];
@ -144,23 +152,33 @@ public class OLProcessDialog extends PamDialog {
}
c.gridy++;
}
JPanel notePanel = new JPanel(new BorderLayout());
notePanel.setBorder(new TitledBorder("Notes"));
noteText = new DBTextArea(2, 40, TaskLogging.TASK_NOTE_LENGTH);
noteText.getComponent().setToolTipText("Notes to add to database record of complete tasks");
notePanel.add(BorderLayout.CENTER, noteText.getComponent());
JPanel progressPanel = new JPanel(new GridBagLayout());
// JPanel progressPanel = new JPanel(new GridBagLayout());
JPanel progressPanel = new PamAlignmentPanel(BorderLayout.WEST);
progressPanel.setLayout(new GridBagLayout());
progressPanel.setBorder(new TitledBorder("Progress"));
c = new PamGridBagContraints();
c.gridwidth = 3;
addComponent(progressPanel, status = new JLabel(" "), c);
c.gridx++;
c.gridy++;
addComponent(progressPanel, currFile = new JLabel(" "), c);
c.gridx = 0;
c.gridy++;
c.gridwidth = 1;
addComponent(progressPanel, new JLabel("File ", SwingConstants.RIGHT), c);
c.gridx++;
addComponent(progressPanel, fileProgress = new PamProgressBar(), c);
addComponent(progressPanel, loadedProgress = new PamProgressBar(0, 100), c);
c.gridx = 0;
c.gridy++;
addComponent(progressPanel, new JLabel("All Data ", SwingConstants.RIGHT), c);
c.gridx++;
addComponent(progressPanel, globalProgress = new PamProgressBar(), c);
addComponent(progressPanel, globalProgress = new PamProgressBar(00, 100), c);
mainPanel.add(dataSelectPanel);
@ -170,6 +188,7 @@ public class OLProcessDialog extends PamDialog {
}
mainPanel.add(tasksPanel);
mainPanel.add(notePanel);
mainPanel.add(progressPanel);
getOkButton().setText("Start");
@ -214,7 +233,10 @@ public class OLProcessDialog extends PamDialog {
for (int i = 0; i < nTasks; i++) {
aTask = taskGroup.getTask(i);
taskCheckBox[i].setSelected(taskGroupParams.getTaskSelection(i));
}
noteText.setText(taskGroupParams.taskNote);
setTaskToolTips();
// deleteOldData.setSelected(offlineClassifierParams.deleteOld);
}
@ -224,7 +246,7 @@ public class OLProcessDialog extends PamDialog {
@Override
public boolean cancelPressed() {
if (currentStatus==TaskMonitor.TASK_RUNNING) {
if (currentStatus==TaskStatus.RUNNING) {
cancelButtonPressed();
return false;
}
@ -239,7 +261,7 @@ public class OLProcessDialog extends PamDialog {
return;
}
if (taskGroup.runTasks()) {
currentStatus = TaskMonitor.TASK_RUNNING;
currentStatus = TaskStatus.RUNNING;
getCancelButton().setText("Stop!");
}
}
@ -257,7 +279,7 @@ public class OLProcessDialog extends PamDialog {
* @param task - the task group in whihc enable controls has been called from
*/
public void enableControls(OfflineTask task) {
boolean nr = currentStatus != TaskMonitor.TASK_RUNNING;
boolean nr = currentStatus != TaskStatus.RUNNING;
int nTasks = taskGroup.getNTasks();
OfflineTask aTask;
int selectedTasks = 0;
@ -279,9 +301,9 @@ public class OLProcessDialog extends PamDialog {
@Override
public void cancelButtonPressed() {
if (currentStatus == TaskMonitor.TASK_RUNNING) {
if (currentStatus == TaskStatus.RUNNING) {
taskGroup.killTasks();
currentStatus=TaskMonitor.TASK_INTERRRUPTED;
currentStatus=TaskStatus.INTERRUPTED;
enableControls();
getCancelButton().setText("Close");
@ -325,8 +347,33 @@ public class OLProcessDialog extends PamDialog {
}
}
String note = noteText.getText();
if (note == null || note.length() == 0) {
return PamDialog.showWarning(super.getOwner(), "Task note", "you must enter a note about what you are doing");
}
taskGroupParams.taskNote = note;
return true;
}
public void setTaskToolTips() {
int nTasks = taskGroup.getNTasks();
OfflineTask aTask;
for (int i = 0; i < nTasks; i++) {
aTask = taskGroup.getTask(i);
OldTaskData taskData = TaskLogging.getTaskLogging().readLastTaskData(taskGroup, aTask);
if (taskData == null) {
taskCheckBox[i].setToolTipText("Task not run");
}
else {
String tip = "<html>Last run: " + taskData.toString() ;
tip = tip.replace("\n", "<br>");
taskCheckBox[i].setToolTipText(tip);
}
}
}
public void newDataSelection() {
int sel = dataSelection.getSelectedIndex();
@ -563,7 +610,7 @@ public class OLProcessDialog extends PamDialog {
@Override
public void windowClosing(WindowEvent arg0) {
if (currentStatus == TaskMonitor.TASK_RUNNING) {
if (currentStatus == TaskStatus.RUNNING) {
return;
}
setVisible(false);
@ -639,47 +686,105 @@ public class OLProcessDialog extends PamDialog {
*/
class OLMonitor implements TaskMonitor {
int doneFiles = 0;
int numFiles = 0;
@Override
public void setFileName(String fileName) {
// currFile.setText(fileName);
if (taskGroup.getTaskGroupParams().dataChoice == TaskGroupParams.PROCESS_LOADED) {
currFile.setText("Loaded data");
public void setTaskStatus(TaskMonitorData taskMonitorData) {
status.setText(taskMonitorData.taskStatus.toString() + ", " + taskMonitorData.taskActivity.toString());
if (taskMonitorData.fileOrStatus == null || taskMonitorData.fileOrStatus.length() == 0) {
currFile.setText(" ");
}
currFile.setText(String.format("File %d of %d", doneFiles, numFiles));
else {
currFile.setText(taskMonitorData.fileOrStatus);
}
switch (taskMonitorData.taskActivity) {
case LINKING:
case LOADING:
// globalProgress.setMaximum(taskMonitorData.progMaximum);
globalProgress.setValue(taskMonitorData.progValue*100/taskMonitorData.progMaximum);
loadedProgress.setIndeterminate(true);
break;
case PROCESSING:
int prog = taskMonitorData.progValue*100/taskMonitorData.progMaximum;
// System.out.println("Set loaded progress to " + prog);
loadedProgress.setIndeterminate(false);
loadedProgress.setValue(prog);
break;
case IDLE:
// globalProgress.setValue(100);
loadedProgress.setIndeterminate(false);
break;
case SAVING:
default:
break;
}
switch (taskMonitorData.taskStatus) {
case COMPLETE:
globalProgress.setValue(100);
loadedProgress.setValue(100);
break;
case CRASHED:
break;
case IDLE:
break;
case INTERRUPTED:
break;
case RUNNING:
break;
case STARTING:
globalProgress.setValue(0);
loadedProgress.setValue(0);
break;
default:
break;
}
setStatus(taskMonitorData.taskStatus);
}
@Override
public void setNumFiles(int nFiles) {
globalProgress.setMaximum(numFiles = nFiles);
}
@Override
public void setProgress(int global, double loaded) {
doneFiles = global;
globalProgress.setValue(global);
fileProgress.setValue((int) (loaded*100));
}
@Override
public void setStatus(int taskStatus) {
status.setText(TaskMonitorData.getStatusString(taskStatus));
// int doneFiles = 0;
//
// int numFiles = 0;
//
// @Override
// public void setFileName(String fileName) {
// // currFile.setText(fileName);
// if (taskGroup.getTaskGroupParams().dataChoice == TaskGroupParams.PROCESS_LOADED) {
// currFile.setText("Loaded data");
// }
// currFile.setText(String.format("File %d of %d", doneFiles, numFiles));
// }
//
// @Override
// public void setNumFiles(int nFiles) {
// globalProgress.setMaximum(numFiles = nFiles);
// }
//
// @Override
// public void setProgress(int global, double loaded) {
// doneFiles = global;
// globalProgress.setValue(global);
// fileProgress.setValue((int) (loaded*100));
// }
//
// @Override
public void setStatus(TaskStatus taskStatus) {
// status.setText(TaskMonitorData.getStatusString(taskStatus));
currentStatus=taskStatus;
enableControls();
switch(taskStatus) {
case TaskMonitor.TASK_IDLE:
case TaskMonitor.TASK_COMPLETE:
case COMPLETE:
case CRASHED:
case IDLE:
case INTERRUPTED:
getCancelButton().setText("Close");
setTaskToolTips();
break;
case TaskMonitor.TASK_RUNNING:
case RUNNING:
case STARTING:
getCancelButton().setText("Stop!");
break;
default:
getCancelButton().setText("Close");
break;
}
}
}
@ -688,7 +793,7 @@ public class OLProcessDialog extends PamDialog {
* Get the current status of the dialog.
* @return the current status.
*/
public int getCurrentStatus() {
public TaskStatus getCurrentStatus() {
return currentStatus;
}

View File

@ -12,11 +12,13 @@ import generalDatabase.clauses.PAMSelectClause;
import java.util.ArrayList;
import java.util.ListIterator;
import PamController.PamControlledUnit;
import PamController.PamViewParameters;
import dataMap.OfflineDataMapPoint;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import PamguardMVC.PamProcess;
import PamguardMVC.superdet.SuperDetection;
/**
@ -45,21 +47,51 @@ public abstract class OfflineTask<T extends PamDataUnit> {
*/
private PamDataBlock<T> parentDataBlock;
/**
* Default constructor. Should no longer be used, but kept in case there are subclasses
* of OfflineTask in other plugins. <br>
* please use constructor 'public OfflineTask(PamDataBlock<T> parentDataBlock)' instead
*/
@Deprecated
public OfflineTask() {
super();
}
// /**
// * Default constructor. Should no longer be used, but kept in case there are subclasses
// * of OfflineTask in other plugins. <br>
// * please use constructor 'public OfflineTask(PamDataBlock<T> parentDataBlock)' instead
// */
// @Deprecated
// public OfflineTask() {
// super();
// }
/**
* @param parentDataBlock
*/
public OfflineTask(PamDataBlock<T> parentDataBlock) {
super();
this.parentDataBlock = parentDataBlock;
/*
* every task is now going to be centrally registered in the offline task manager, but only
* if it has a PAMControlledUnit. Tasks can be identified in the database from the unit id
* information and the task name.
* There may be a few teething problems with this if a task is created in the constructor of
* a PamProcess ? though it should by then know it's controlled unit I think.
*/
PamControlledUnit parentControl = getTaskControlledUnit();
if (parentControl == null) {
System.out.printf("Offline task %d with datablock %s is not associated with a PAMGuard module\n", getName(), parentDataBlock);
}
else {
OfflineTaskManager.getManager().registerTask(this);
}
}
/**
* Get the PAMControlled unit associated with a task.
* @return PAMControlled unit associated with a task.
*/
public PamControlledUnit getTaskControlledUnit() {
if (parentDataBlock == null) {
return null;
}
PamProcess parentProcess = parentDataBlock.getParentProcess();
if (parentProcess == null) {
return null;
}
return parentProcess.getPamControlledUnit();
}
/**
@ -96,6 +128,36 @@ public abstract class OfflineTask<T extends PamDataUnit> {
* @return a name for the task, to be displayed in the dialog.
*/
abstract public String getName();
/**
* Get a unit type for the task. This is the unit type of
* the parent PAMGuard module.
* @return module name
*/
public String getUnitType() {
PamControlledUnit parentControl = getTaskControlledUnit();
if (parentControl == null) {
return "Unknown ModuleName";
}
else {
return parentControl.getUnitType();
}
}
/**
* Get a unit name for the task. This is the unit name of
* the parent PAMGuard module.
* @return module name
*/
public String getUnitName() {
PamControlledUnit parentControl = getTaskControlledUnit();
if (parentControl == null) {
return "Unknown ModuleName";
}
else {
return parentControl.getUnitName();
}
}
/**
* task has settings which can be called

View File

@ -12,6 +12,7 @@ import binaryFileStorage.DataUnitFileInformation;
import dataMap.OfflineDataMap;
import dataMap.OfflineDataMapPoint;
import generalDatabase.DBControlUnit;
import offlineProcessing.logging.TaskLogging;
import offlineProcessing.superdet.OfflineSuperDetFilter;
import pamScrollSystem.DataTimeLimits;
import pamScrollSystem.ViewLoadObserver;
@ -64,9 +65,10 @@ public class OfflineTaskGroup implements PamSettings {
private DataTimeLimits dataTimeLimits;
private volatile TaskStatus completionStatus = TaskStatus.IDLE;
/**
* PamControlledunit required in constructor since some bookkeeping will
* be goign on in the background which will need the unit type and name.
* be going on in the background which will need the unit type and name.
* @param pamControlledUnit host controlled unit.
* @param settingsName Name to be used in PamSettings for storing some basic information
* (which tasks are selected)
@ -150,11 +152,104 @@ public class OfflineTaskGroup implements PamSettings {
*/
public boolean runTasks() {
setSummaryLists();
checkTaskTimes();
TaskMonitorData monData = new TaskMonitorData(TaskStatus.STARTING, TaskActivity.IDLE, 0, 0, null, 0);
if (taskMonitor != null) {
taskMonitor.setTaskStatus(monData);
}
logTaskStatus(monData);
worker = new TaskGroupWorker();
worker.execute();
return true;
}
/**
* Check the start and end times of tasks before they are run. while not
* needed for things like process loaded, this is needed for the database
* record of what's been done.
*/
private void checkTaskTimes() {
if (primaryDataBlock == null) {
return;
}
long mapStart = 0;
long mapEnd = 0;
long loadedStart = 0;
long loadedEnd = 0;
OfflineDataMap dataMap = primaryDataBlock.getPrimaryDataMap();
if (dataMap != null) {
mapStart = dataMap.getFirstDataTime();
mapEnd = dataMap.getLastDataTime();
}
loadedStart = primaryDataBlock.getCurrentViewDataStart();
loadedEnd = primaryDataBlock.getCurrentViewDataEnd();
switch (taskGroupParams.dataChoice) {
case TaskGroupParams.PROCESS_ALL:
taskGroupParams.startRedoDataTime = mapStart;
taskGroupParams.endRedoDataTime = mapEnd;
break;
case TaskGroupParams.PROCESS_LOADED:
taskGroupParams.startRedoDataTime = loadedStart;
taskGroupParams.endRedoDataTime = loadedEnd;
break;
case TaskGroupParams.PROCESS_NEW:
// need to get last processed time from the database for every task
// then worry about what to do if they are different.
taskGroupParams.startRedoDataTime = getPreviousEndTime();
taskGroupParams.endRedoDataTime = mapEnd;
break;
case TaskGroupParams.PROCESS_SPECIFICPERIOD:
// should have been set already, but...
break;
case TaskGroupParams.PROCESS_TME_CHUNKS: // whatever this is ?
break;
}
}
/**
* Look in the database to get the previous end time for all tasks. if
* it doesn't exist, then take the map start time.
* @return
*/
private long getPreviousEndTime() {
long previousEnd = 0;
OfflineDataMap dataMap = primaryDataBlock.getPrimaryDataMap();
if (dataMap != null) {
previousEnd = dataMap.getFirstDataTime();
}
// then scan the database to try to find if everything is later ...
long taskMinLatest = Long.MAX_VALUE;
for (OfflineTask aTask : offlineTasks) {
if (aTask.isDoRun() == false) {
continue;
}
Long taskLatest = getPreviousEndTime(aTask);
if (taskLatest != null) {
taskMinLatest = Math.min(taskMinLatest, taskLatest);
}
}
if (taskMinLatest != Long.MAX_VALUE) {
previousEnd = taskMinLatest;
}
return previousEnd;
}
/**
* Get the time of the end of the last run of data for this task.
* @param aTask Offline task
* @return end time of data in last record in database or NULL if no database records.
*/
private Long getPreviousEndTime(OfflineTask aTask) {
// TODO Auto-generated method stub
return null;
}
public void killTasks() {
if (worker == null) {
return;
@ -285,7 +380,6 @@ public class OfflineTaskGroup implements PamSettings {
volatile boolean instantKill = false;
private int completionStatus = TaskMonitor.TASK_IDLE;
private CPUMonitor cpuMonitor = new CPUMonitor();
@ -303,7 +397,7 @@ public class OfflineTaskGroup implements PamSettings {
@Override
protected Integer doInBackground() {
completionStatus = TaskMonitor.TASK_RUNNING;
completionStatus = TaskStatus.RUNNING;
try {
prepareTasks();
switch (taskGroupParams.dataChoice) {
@ -324,15 +418,15 @@ public class OfflineTaskGroup implements PamSettings {
break;
}
if (instantKill) {
completionStatus = TaskMonitor.TASK_INTERRRUPTED;
completionStatus = TaskStatus.INTERRUPTED;
}
else {
completionStatus = TaskMonitor.TASK_COMPLETE;
completionStatus = TaskStatus.COMPLETE;
}
}
catch (Exception e) {
e.printStackTrace();
completionStatus = TaskMonitor.TASK_CRASHED;
completionStatus = TaskStatus.CRASHED;
}
completeTasks();
return null;
@ -375,14 +469,15 @@ public class OfflineTaskGroup implements PamSettings {
OfflineDataMap dataMap = primaryDataBlock.getPrimaryDataMap();
int nMapPoints = dataMap.getNumMapPoints(startTime, endTime);
int iMapPoint = 0;
publish(new TaskMonitorData(TaskMonitor.TASK_RUNNING, nMapPoints));
publish(new TaskMonitorData(0, 0.0));
publish(new TaskMonitorData(TaskStatus.RUNNING, TaskActivity.PROCESSING, nMapPoints, 0, "",
taskGroupParams.startRedoDataTime));
OfflineDataStore dataSource = dataMap.getOfflineDataSource();
Iterator<OfflineDataMapPoint> mapIterator = dataMap.getListIterator();
OfflineDataMapPoint mapPoint;
// System.out.println("NUMBER OF MAP POINTS: " + mapIterator.hasNext()
// + "Start time: " + PamCalendar.formatDateTime(startTime) + "End time: " + PamCalendar.formatDateTime(endTime));
boolean reallyDoIt = false;
int iPoint = 0;
while (mapIterator.hasNext()) {
mapPoint = mapIterator.next();
reallyDoIt = true;
@ -394,12 +489,17 @@ public class OfflineTaskGroup implements PamSettings {
Debug.out.printf("Skipping map point %s since no matching data\n", mapPoint.toString());
reallyDoIt = false;;
}
publish(new TaskMonitorData(mapPoint.getName()));
primaryDataBlock.clearAll();
long lastTime = taskGroupParams.startRedoDataTime;
if (reallyDoIt) {
Runtime.getRuntime().gc(); //garbage collection
publish(new TaskMonitorData(TaskStatus.RUNNING , TaskActivity.LOADING, nMapPoints, iPoint++, mapPoint.getName(),
lastTime));
primaryDataBlock.loadViewerData(new OfflineDataLoadInfo(mapPoint.getStartTime(), mapPoint.getEndTime()), null);
primaryDataBlock.sortData();
@ -424,17 +524,23 @@ public class OfflineTaskGroup implements PamSettings {
if (superDetectionFilter != null) {
superDetectionFilter.checkSubDetectionLinks();
}
publish(new TaskMonitorData(TaskStatus.RUNNING , TaskActivity.PROCESSING, nMapPoints, 0, mapPoint.getName(),
lastTime));
processData(iMapPoint, mapPoint, mapPoint.getStartTime(), mapPoint.getEndTime());
lastTime = mapPoint.getEndTime();
publish(new TaskMonitorData(TaskStatus.RUNNING , TaskActivity.SAVING, nMapPoints, 0, mapPoint.getName(),
lastTime));
}
iMapPoint++;
publish(new TaskMonitorData(iMapPoint+1, 0.0));
// publish(new TaskMonitorData(taskGroupParams.dataChoice, taskGroupParams.startRedoDataTime, taskGroupParams.endRedoDataTime, nMapPoints, 0,
// TaskMonitor.TASK_COMPLETE, TaskMonitor.TASK_COMPLETE, lastTime));
if (instantKill) {
break;
}
}
// }
publish(new TaskMonitorData(TaskMonitor.TASK_IDLE));
publish(new TaskMonitorData(TaskMonitor.TASK_COMPLETE));
primaryDataBlock.loadViewerData(new OfflineDataLoadInfo(currentStart, currentEnd), null);
}
@ -456,15 +562,16 @@ public class OfflineTaskGroup implements PamSettings {
}
private void processLoadedData() {
publish(new TaskMonitorData(TaskMonitor.TASK_RUNNING, 1));
publish(new TaskMonitorData(TaskStatus.RUNNING, TaskActivity.PROCESSING, 1, 0, "Loaded Data",
taskGroupParams.startRedoDataTime));
if (dataTimeLimits == null) {
processData(0, null, 0, Long.MAX_VALUE);
}
else {
processData(0, null, dataTimeLimits.getMinimumMillis(), dataTimeLimits.getMaximumMillis());
}
publish(new TaskMonitorData(TaskMonitor.TASK_IDLE));
publish(new TaskMonitorData(TaskMonitor.TASK_COMPLETE));
// publish(new TaskMonitorData(TaskGroupParams.PROCESS_LOADED, taskGroupParams.startRedoDataTime, taskGroupParams.endRedoDataTime, 1, 0, "Loaded Data",
// TaskMonitor.TASK_COMPLETE, TaskMonitor.ACTIVITY_PROCESSING, taskGroupParams.endRedoDataTime));
}
/**
@ -506,6 +613,13 @@ public class OfflineTaskGroup implements PamSettings {
OfflineTask aTask;
boolean unitChanged;
DataUnitFileInformation fileInfo;
String dataName;
if (mapPoint != null) {
dataName = mapPoint.getName();
}
else {
dataName = "Loaded Data";
}
/**
* Make sure that any data from required data blocks is loaded. First check the
* start and end times of the primary data units we actually WANT to process
@ -612,7 +726,8 @@ public class OfflineTaskGroup implements PamSettings {
}
unitsChanged++;
if (totalUnits%nSay == 0) {
publish(new TaskMonitorData(globalProgress+1, (double) totalUnits / (double) nDatas));
publish(new TaskMonitorData(TaskStatus.RUNNING, TaskActivity.PROCESSING, nToProcess, totalUnits, dataName,
dataUnit.getTimeMilliseconds()));
}
}
for (int iTask = 0; iTask < nTasks; iTask++) {
@ -623,12 +738,13 @@ public class OfflineTaskGroup implements PamSettings {
aTask.loadedDataComplete();
}
// }
publish(new TaskMonitorData(TaskStatus.RUNNING, TaskActivity.SAVING, nToProcess, totalUnits, dataName,
processEndTime));
for (int i = 0; i < affectedDataBlocks.size(); i++) {
//System.out.println("SAVE VIEWER DATA FOR: " + affectedDataBlocks.get(i) );
aDataBlock = affectedDataBlocks.get(i);
aDataBlock.saveViewerData();
}
publish(new TaskMonitorData(globalProgress+1, (double) totalUnits / (double) nDatas));
Debug.out.printf("Processd %d out of %d data units at " + mapPoint + "\n", unitsChanged, totalUnits);
commitDatabase();
}
@ -707,9 +823,9 @@ public class OfflineTaskGroup implements PamSettings {
@Override
public void sayProgress(int state, long loadStart, long loadEnd, long lastTime, int nLoaded) {
TaskMonitorData tmd = new TaskMonitorData(TaskMonitorData.LOADING_DATA);
tmd.dataType = TaskMonitorData.LOADING_DATA;
publish(tmd);
// TaskMonitorData tmd = new TaskMonitorData(TaskMonitorData.LOADING_DATA);
// tmd.dataType = TaskMonitorData.LOADING_DATA;
// publish(tmd);
}
@ -725,29 +841,47 @@ public class OfflineTaskGroup implements PamSettings {
if (taskMonitor == null) {
return;
}
int dataType = monData.dataType;
if ((dataType & TaskMonitorData.SET_STATUS) != 0) {
taskMonitor.setStatus(monData.status);
}
if ((dataType & TaskMonitorData.SET_NFILES) != 0) {
taskMonitor.setNumFiles(monData.nFiles);
}
if ((dataType & TaskMonitorData.SET_PROGRESS) != 0) {
taskMonitor.setProgress(monData.globalProgress, monData.loadedProgress);
// taskMonitor.setProgress(monData.globalProgress, .5);
}
if ((dataType & TaskMonitorData.SET_FILENAME) != 0) {
taskMonitor.setFileName(monData.fileName);
}
if (dataType == TaskMonitorData.LOADING_DATA) {
taskMonitor.setStatus(monData.status);
}
taskMonitor.setTaskStatus(monData);
// int dataType = monData.dataType;
// if ((dataType & TaskMonitorData.SET_STATUS) != 0) {
// taskMonitor.setStatus(monData.status);
// }
// if ((dataType & TaskMonitorData.SET_NFILES) != 0) {
// taskMonitor.setNumFiles(monData.nFiles);
// }
// if ((dataType & TaskMonitorData.SET_PROGRESS) != 0) {
// taskMonitor.setProgress(monData.globalProgress, monData.loadedProgress);
// // taskMonitor.setProgress(monData.globalProgress, .5);
// }
// if ((dataType & TaskMonitorData.SET_FILENAME) != 0) {
// taskMonitor.setFileName(monData.fileName);
// }
// if (dataType == TaskMonitorData.LOADING_DATA) {
// taskMonitor.setStatus(monData.status);
// }
}
private void logTaskStatus(TaskMonitorData monitorData) {
for (OfflineTask aTask : offlineTasks) {
if (aTask.isDoRun() == false) {
continue;
}
TaskLogging.getTaskLogging().logTask(this, aTask, monitorData);
}
}
/**
* some bookkeeping - write information about task completion to the database.
*/
public void tasksDone() {
// tell the logging that we're done.
TaskMonitorData monData = new TaskMonitorData(completionStatus, TaskActivity.IDLE, 1, 1, "",
taskGroupParams.endRedoDataTime);
logTaskStatus(monData); // log first, since the dialog will update it's tool tips based on databse read.
newMonitorData(monData);
long currentStart = primaryDataBlock.getCurrentViewDataStart();
long currentEnd = primaryDataBlock.getCurrentViewDataEnd();
//System.out.println("TASKS COMPLETE:");

View File

@ -13,24 +13,36 @@ import PamguardMVC.PamDataBlock;
*/
public class OfflineTaskManager {
private static OfflineTaskManager singleInstance = null;
private ArrayList<OfflineTask> globalTaskList = new ArrayList();
public static OfflineTaskManager getManager() {
if (singleInstance == null) {
singleInstance = new OfflineTaskManager();
}
return singleInstance;
}
/**
* Get a list of ALL offline tasks registered with all modules
* in all of PAMGUard. <p>
* N.B. Many tasks won't be registered.
* @return list of all offline tasks
*/
public static ArrayList<OfflineTask> getAllOfflineTasks() {
ArrayList<OfflineTask> allTasks = new ArrayList<>();
PamController pamController = PamController.getInstance();
int n = pamController.getNumControlledUnits();
for (int i = 0; i < n; i++) {
PamControlledUnit pcu = pamController.getControlledUnit(i);
ArrayList<OfflineTask> unitTasks = pcu.getOfflineTasks();
if (unitTasks != null) {
allTasks.addAll(unitTasks);
}
}
return allTasks;
public ArrayList<OfflineTask> getAllOfflineTasks() {
// ArrayList<OfflineTask> allTasks = new ArrayList<>();
// PamController pamController = PamController.getInstance();
// int n = pamController.getNumControlledUnits();
// for (int i = 0; i < n; i++) {
// PamControlledUnit pcu = pamController.getControlledUnit(i);
// ArrayList<OfflineTask> unitTasks = pcu.getOfflineTasks();
// if (unitTasks != null) {
// allTasks.addAll(unitTasks);
// }
// }
// return allTasks;
return globalTaskList;
}
/**
@ -38,7 +50,7 @@ public class OfflineTaskManager {
* @param taskParentDataBlock parent data block for tasks
* @return list of available tasks.
*/
public static ArrayList<OfflineTask> getOfflineTasks(PamDataBlock taskParentDataBlock) {
public ArrayList<OfflineTask> getOfflineTasks(PamDataBlock taskParentDataBlock) {
ArrayList<OfflineTask> allTasks = getAllOfflineTasks();
ArrayList<OfflineTask> wantedTasks = new ArrayList<>();
for (OfflineTask task : allTasks) {
@ -50,16 +62,85 @@ public class OfflineTaskManager {
return wantedTasks;
}
/**
* Get a list of all tasks in the system which associate with the given PAMGuard module
* @param pamControlledUnit parent PAMGuard module
* @return list of available tasks.
*/
public ArrayList<OfflineTask> getOfflineTasks(PamControlledUnit pamControlledUnit) {
ArrayList<OfflineTask> allTasks = getAllOfflineTasks();
ArrayList<OfflineTask> wantedTasks = new ArrayList<>();
for (OfflineTask task : allTasks) {
if (task == null) continue;
if (task.getTaskControlledUnit() == pamControlledUnit) {
wantedTasks.add(task);
}
}
return wantedTasks;
}
/**
* Add all available tasks from the system which use the given datablock
* as input. Note that tasks already in the goup will NOT be added a second time.
* as primary input.
* @param taskGroup Task group to add tasks to
* @param taskParentDataBlock parent data block
* @return number of tasks added
*/
public static int addAvailableTasks(OfflineTaskGroup taskGroup, PamDataBlock taskParentDataBlock) {
public int addAvailableTasks(OfflineTaskGroup taskGroup, PamDataBlock taskParentDataBlock) {
ArrayList<OfflineTask> tasks = getOfflineTasks(taskParentDataBlock);
return taskGroup.addTasks(tasks);
}
/**
* Register a task in the global list. It's possible some tasks might get
* recreated, in which case when registered they will replace the previous one
* This will cause trouble if two separate tasks have the same name, but that should
* not be possible.
* @param offlineTask
*/
public void registerTask(OfflineTask offlineTask) {
// if it exists, replace it.
OfflineTask existingTask = findOfflineTask(offlineTask);
if (existingTask != null) {
int ind = globalTaskList.indexOf(existingTask);
globalTaskList.set(ind, offlineTask);
}
else {
globalTaskList.add(offlineTask);
}
}
/**
* find a task with the same module type, module name and task name. This should
* be enough to uniquely identify every task.
* @param offlineTask
* @return matching task or null.
*/
public OfflineTask findOfflineTask(OfflineTask offlineTask) {
return findOfflineTask(offlineTask.getUnitType(), offlineTask.getUnitName(), offlineTask.getName());
}
/**
* Find a registered task based on it's module type, module name and task name. This should
* be enough to uniquely identify every task.
* @param unitType
* @param unitName
* @param taskName
* @return matching task or null.
*/
public OfflineTask findOfflineTask(String unitType, String unitName, String taskName) {
// could possibly also do a check on class type ????
for (OfflineTask aTask : globalTaskList) {
if (aTask.getUnitType().equals(unitType) == false) {
continue;
}
if (aTask.getUnitName().equals(unitName) == false) {
continue;
}
if (aTask.getName().equals(taskName)) {
return aTask;
}
}
return null;
}
}

View File

@ -0,0 +1,7 @@
package offlineProcessing;
public enum TaskActivity {
IDLE, PROCESSING, LOADING, LINKING, SAVING;
}

View File

@ -33,7 +33,7 @@ public class TaskGroupParams implements Cloneable, Serializable, ManagedParamete
static public final int PROCESS_NEW = 2;
/**
* Time of the last bit of data to be processed.
* Time of the last section of data to be processed.
*/
public long lastDataTime;
@ -91,6 +91,11 @@ public class TaskGroupParams implements Cloneable, Serializable, ManagedParamete
*/
public ArrayList<long[]> timeChunks;
/**
* Note which will get written to the database of completed tasks.
*/
public String taskNote;
/**
* Set the selection state of a particular task.
* @param iTask task number (counting from 0)

View File

@ -1,84 +0,0 @@
package offlineProcessing;
import java.sql.Connection;
import java.sql.Types;
import PamController.PamControlledUnit;
import PamUtils.PamCalendar;
import generalDatabase.DBControlUnit;
import generalDatabase.EmptyTableDefinition;
import generalDatabase.PamConnection;
import generalDatabase.PamTableItem;
import generalDatabase.SQLTypes;
/**
* Handles logging of tasks to the database.
*
* @author Doug Gillespie
*
*/
public class TaskLogging {
private static TaskLogging taskLogging;
private EmptyTableDefinition tableDef;
private PamTableItem localTime, moduleType, moduleName, taskName, taskStart, taskStartMillis, taskEnd, taskEndMillis,
completionCode;
private PamConnection con;
private TaskLogging() {
tableDef = new EmptyTableDefinition("OfflineTasks");
tableDef.addTableItem(localTime = new PamTableItem("PCLocalTime", Types.TIMESTAMP));
tableDef.addTableItem(moduleType = new PamTableItem("Module Type", Types.CHAR, 50));
tableDef.addTableItem(moduleName = new PamTableItem("Module Name", Types.CHAR, 50));
tableDef.addTableItem(taskName = new PamTableItem("Task Name", Types.CHAR, 50));
tableDef.addTableItem(taskStart = new PamTableItem("TaskStart", Types.TIMESTAMP));
tableDef.addTableItem(taskStartMillis = new PamTableItem("TaskStartMillis", Types.INTEGER));
tableDef.addTableItem(taskEnd = new PamTableItem("TaskEnd", Types.TIMESTAMP));
tableDef.addTableItem(taskEndMillis = new PamTableItem("TaskEndMillis", Types.INTEGER));
tableDef.addTableItem(completionCode = new PamTableItem("CompletionCode", Types.CHAR, 20));
/**
* Note that completionCode Strings can be got from
* TaskMonitorData.getStatusString
*/
}
public static TaskLogging getTaskLogging() {
if (taskLogging == null) {
taskLogging = new TaskLogging();
}
taskLogging.checkConnection();
return taskLogging;
}
private void checkConnection() {
// TODO Auto-generated method stub
PamConnection currentCon = DBControlUnit.findConnection();
if (currentCon == con) {
return;
}
/**
* Need to check tables, etc.
*/
currentCon = con;
DBControlUnit.findDatabaseControl().getDbProcess().checkTable(tableDef);
}
public boolean logTask(PamControlledUnit pcu, SQLTypes sqlTypes, OfflineTask task, long startTime,
long endTime, int completionStatus) {
localTime.setValue(sqlTypes.getTimeStamp(System.currentTimeMillis()));
moduleType.setValue(pcu.getUnitType());
moduleName.setValue(pcu.getUnitType());
taskName.setValue(task.getName());
taskStart.setValue(sqlTypes.getTimeStamp(startTime));
taskEnd.setValue(sqlTypes.getTimeStamp(endTime));
taskStartMillis.setValue(startTime%1000);
taskEndMillis.setValue(endTime%1000);
completionCode.setValue(TaskMonitorData.getStatusString(completionStatus));
return false;
}
}

View File

@ -9,36 +9,43 @@ package offlineProcessing;
*
*/
public interface TaskMonitor {
static public final int TASK_IDLE = 0;
static public final int TASK_RUNNING = 1;
static public final int TASK_INTERRRUPTED = 2;
static public final int TASK_COMPLETE = 3;
static public final int TASK_CRASHED = 4;
//
// static public final int TASK_IDLE = 0;
// static public final int TASK_STARTING = 1; // before it started.
// static public final int TASK_RUNNING = 2;
// static public final int TASK_INTERRRUPTED = 3;
// static public final int TASK_COMPLETE = 4;
// static public final int TASK_CRASHED = 5;
/**
* Set the task status.
* @param taskStatus
*/
public void setStatus(int taskStatus);
// public static final int ACTIVITY_PROCESSING = 10;
// public static final int ACTIVITY_LOADING = 11;
// public static final int ACTIVITY_LINKING = 12;
// public static final int ACTIVITY_SAVING = 13;
/**
* Set the total number of files to process
* (will be one if only loaded data are being processed).
* @param nFiles
*/
public void setNumFiles(int nFiles);
/**
* Set the overall task progress
* <p>
* @param global - global progress, i.e. number of files completed (0 - nFiles)
* @param loaded - progress though data currently loaded (0 - 1.)
*/
public void setProgress(int global, double loaded);
/**
* Set the current file name.
* @param fileName
*/
public void setFileName(String fileName);
public void setTaskStatus(TaskMonitorData taskMonitorData);
// /**
// * Set the task status.
// * @param taskStatus
// */
// public void setStatus(int taskStatus);
//
// /**
// * Set the total number of files to process
// * (will be one if only loaded data are being processed).
// * @param nFiles
// */
// public void setNumFiles(int nFiles);
// /**
// * Set the overall task progress
// * <p>
// * @param global - global progress, i.e. number of files completed (0 - nFiles)
// * @param loaded - progress though data currently loaded (0 - 1.)
// */
// public void setProgress(int global, double loaded);
//
// /**
// * Set the current file name.
// * @param fileName
// */
// public void setFileName(String fileName);
}

View File

@ -8,105 +8,128 @@ package offlineProcessing;
*/
public class TaskMonitorData {
static public final int SET_NFILES = 0x1;
static public final int SET_FILENAME = 0x2;
static public final int SET_STATUS = 0x4;
static public final int SET_PROGRESS = 0x8;
static public final int LOADING_DATA = 0x10;
static public final int LINKING_DATA = 0x20;
// static public final int SET_NFILES = 0x1;
// static public final int SET_FILENAME = 0x2;
// static public final int SET_STATUS = 0x4;
// static public final int SET_PROGRESS = 0x8;
// static public final int LOADING_DATA = 0x10;
// static public final int LINKING_DATA = 0x20;
int dataType;
public int progMaximum; // used for both files and units.
int globalProgress;
public int progValue;
int nFiles;
public String fileOrStatus; // will be a file name or the words "Current data" or null
/**
* Progress through loaded data
* Values < 0 represent unknown (i.e. currently loading data).
* so progress bars should be set to indeterminate.
*/
double loadedProgress;
public TaskStatus taskStatus;
int status;
public TaskActivity taskActivity;
public long lastDataDate;
String fileName;
/**
* Constructor used to set the status
* @param status status
*/
TaskMonitorData(int status) {
this.status = status;
dataType = SET_STATUS;
}
/**
* Constructor used to set both the status and
* the total number of files.
* @param status status
* @param nFiles number of files
*/
TaskMonitorData(int status, int nFiles) {
this.status = status;
this.nFiles = nFiles;
dataType = SET_STATUS | SET_NFILES;
}
/**
* Constructor used to set the current file name
* @param fileName file Name
*/
TaskMonitorData(String fileName) {
this.fileName = fileName;
dataType = SET_FILENAME;
}
/**
* Constructor used to set the analysis progress.
* @param globalProgress
* @param loadedProgress
*/
TaskMonitorData(int globalProgress, double loadedProgress) {
this.globalProgress = globalProgress;
this.loadedProgress = loadedProgress;
dataType = SET_PROGRESS;
public TaskMonitorData(TaskStatus taskStatus, TaskActivity taskActivity, int totalFiles, int currentFile,
String fileOrStatus, long lastDataDate) {
super();
this.progMaximum = totalFiles;
this.progValue = currentFile;
this.fileOrStatus = fileOrStatus;
this.taskStatus = taskStatus;
this.taskActivity = taskActivity;
this.lastDataDate = lastDataDate;
}
// int dataType;
//
// int globalProgress;
//
// int nFiles;
//
// /**
// * Progress through loaded data
// * Values < 0 represent unknown (i.e. currently loading data).
// * so progress bars should be set to indeterminate.
// */
// double loadedProgress;
//
// int status;
//
// String fileName;
//
//
// /**
// * Constructor used to set the status
// * @param status status
// */
// TaskMonitorData(int status) {
// this.status = status;
// dataType = SET_STATUS;
// }
//
// /**
// * Constructor used to set both the status and
// * the total number of files.
// * @param status status
// * @param nFiles number of files
// */
// TaskMonitorData(int status, int nFiles) {
// this.status = status;
// this.nFiles = nFiles;
// dataType = SET_STATUS | SET_NFILES;
// }
//
// /**
// * Constructor used to set the current file name
// * @param fileName file Name
// */
// TaskMonitorData(String fileName) {
// this.fileName = fileName;
// dataType = SET_FILENAME;
// }
//
// /**
// * Constructor used to set the analysis progress.
// * @param globalProgress
// * @param loadedProgress
// */
// TaskMonitorData(int globalProgress, double loadedProgress) {
// this.globalProgress = globalProgress;
// this.loadedProgress = loadedProgress;
// dataType = SET_PROGRESS;
// }
/**
*
* @param status Task status
* @return some string or other to represent the status.
*/
public static String getStatusString(int status) {
switch(status) {
case TaskMonitor.TASK_IDLE:
return "Idle";
case TaskMonitor.TASK_COMPLETE:
return "Done";
case TaskMonitor.TASK_INTERRRUPTED:
return "Interrupted";
case TaskMonitor.TASK_RUNNING:
return "Running";
case TaskMonitor.TASK_CRASHED:
return "Crashed";
}
return "Unknown";
}
// /**
// *
// * @param status Task status
// * @return some string or other to represent the status.
// */
// public static String getStatusString(int status) {
// switch(status) {
// case TaskMonitor.TASK_COMPLETE:
// return "Done";
// case TaskMonitor.TASK_INTERRRUPTED:
// return "Interrupted";
// case TaskMonitor.TASK_RUNNING:
// return "Running";
// case TaskMonitor.TASK_CRASHED:
// return "Crashed";
// }
// return "Unknown";
// }
/**
* Turn a status string back into a code.
* @param statusString
* @return
*/
public static int getStatusCode(String statusString) {
for (int i = 0; i < 5; i++) {
if (statusString.equals(getStatusString(i))) {
return i;
}
}
return -1;
}
// /**
// * Turn a status string back into a code.
// * @param statusString
// * @return
// */
// public static int getStatusCode(String statusString) {
// for (int i = 0; i < 5; i++) {
// if (statusString.equals(getStatusString(i))) {
// return i;
// }
// }
// return -1;
// }
}

View File

@ -0,0 +1,19 @@
package offlineProcessing;
public enum TaskStatus {
//
// static public final int TASK_IDLE = 0;
// static public final int TASK_STARTING = 1; // before it started.
// static public final int TASK_RUNNING = 2;
// static public final int TASK_INTERRRUPTED = 3;
// static public final int TASK_COMPLETE = 4;
// static public final int TASK_CRASHED = 5;
IDLE, STARTING, RUNNING, INTERRUPTED, COMPLETE, CRASHED;
@Override
public String toString() {
return super.toString();
}
}

View File

@ -0,0 +1,9 @@
package offlineProcessing;
public class TaskStatusData {
public TaskStatusData() {
// TODO Auto-generated constructor stub
}
}

View File

@ -1,12 +1,12 @@
/**
*
*/
package offlineProcessing;
package offlineProcessing.legacyremotestuff;
import java.util.ArrayList;
import dataMap.DataMapPanel;
import offlineProcessing.OfflineTaskGroup;
import PamController.PamControlledUnit;
import PamController.PamController;
import PamController.PamControllerInterface;
@ -16,6 +16,7 @@ import PamController.PamSettingManager;
* @author GrahamWeatherup
*only run in Viewer mode to run all Offline Tasks
*/
@Deprecated // too simplistic, won't be using this.
public class OfflineProcessingControlledUnit extends PamControlledUnit{
// static OfflineProcessingControlledUnit singleInstance;

View File

@ -1,11 +1,12 @@
/**
*
*/
package offlineProcessing;
package offlineProcessing.legacyremotestuff;
import PamController.PamControlledUnit;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
import offlineProcessing.OfflineTask;
/**
* @author GrahamWeatherup

View File

@ -1,4 +1,4 @@
package offlineProcessing;
package offlineProcessing.legacyremotestuff;
/**
@ -8,6 +8,7 @@ package offlineProcessing;
* @author Jamie Macaulay
*
*/
@Deprecated // there is nothing in here which shouldn't be in OfflineTaskManager
public class OfflineTaskRegister {
/**

View File

@ -22,7 +22,7 @@
package offlineProcessing;
package offlineProcessing.legacyremotestuff;
import PamModel.PamDependency;
import PamModel.PamPluginInterface;

View File

@ -0,0 +1,53 @@
package offlineProcessing.logging;
import PamUtils.PamCalendar;
import offlineProcessing.TaskActivity;
import offlineProcessing.TaskMonitorData;
import offlineProcessing.TaskStatus;
public class OldTaskData extends TaskMonitorData {
public long firstDataDate;
public long processingStart, processingEnd;
private String taskNote;
/**
*
* @param taskStatus completion status of task
* @param firstDataDate first data date
* @param lastDataDate last data date
* @param procStart date run started
* @param procEnd date run ended.
* @param taskNote
*/
public OldTaskData(TaskStatus taskStatus, long firstDataDate,
long lastDataDate, long procStart, long procEnd, String taskNote) {
super(taskStatus, TaskActivity.IDLE, 0, 0, null, lastDataDate);
this.firstDataDate = firstDataDate;
this.processingStart = procStart;
this.processingEnd = procEnd;
this.taskNote = taskNote;
}
@Override
public String toString() {
String endStatus;
if (this.taskStatus == null) {
endStatus = "Unknown completion code. Possible crash";
}
else {
endStatus = this.taskStatus.toString();
}
String str = String.format("Processed from %s to %s on %s. %s", PamCalendar.formatDateTime(firstDataDate),
PamCalendar.formatDateTime(lastDataDate), PamCalendar.formatDateTime(this.processingStart), endStatus);
if (taskNote != null) {
str = str + "\n" + taskNote;
// str = "<html>" + str + "\br" + taskNote + "<\\html>";
}
return str;
}
}

View File

@ -0,0 +1,300 @@
package offlineProcessing.logging;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.HashMap;
import PamController.PamControlledUnit;
import PamUtils.PamCalendar;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamDataUnit;
import generalDatabase.DBControlUnit;
import generalDatabase.EmptyTableDefinition;
import generalDatabase.PamConnection;
import generalDatabase.PamTableItem;
import generalDatabase.SQLLogging;
import generalDatabase.SQLTypes;
import generalDatabase.pamCursor.CursorFinder;
import generalDatabase.pamCursor.PamCursor;
import offlineProcessing.OfflineTask;
import offlineProcessing.OfflineTaskGroup;
import offlineProcessing.TaskActivity;
import offlineProcessing.TaskGroupParams;
import offlineProcessing.TaskMonitorData;
import offlineProcessing.TaskStatus;
/**
* Handles logging of tasks to the database.
*
* @author Doug Gillespie
*
*/
public class TaskLogging {
private static TaskLogging taskLogging;
public static final int TASK_NOTE_LENGTH = 80;
private EmptyTableDefinition tableDef;
private PamTableItem utc, moduleType, moduleName, taskName, dataStart, dataEnd, runEnd,
completionCode, note;
/**
* Storage mostly to keep id's of last database index for each task.
*/
private HashMap<OfflineTask, TaskLoggingData> loggingData = new HashMap();
/*
* May want several different write and update cursors for this. e.g. when a task starts
* we want to write the UTC and id comlumns and the dataStart, but probably not the dataEnd and
* the runEnd columns. Then when we update (if we update) we'll occasionally update the dataEnd
* time, then only will in the runEnd and completionCode when the task has finished.
*/
private EmptyTableDefinition startTableDef, updateTableDef, completeTableDef;
private PamConnection con;
private static final String tableName = "OfflineTasks";
// private StartLogging startLogging;
private CursorFinder startCursorFinder, completeCursorFinder;
private TaskLoggingDataBlock taskLoggingDataBlock;
private TaskLogging() {
// table for everything (mostly used for reading)
tableDef = new EmptyTableDefinition(tableName);
tableDef.addTableItem(utc = new PamTableItem("UTC", Types.TIMESTAMP));
tableDef.addTableItem(moduleType = new PamTableItem("Module Type", Types.CHAR, 50));
tableDef.addTableItem(moduleName = new PamTableItem("Module Name", Types.CHAR, 50));
tableDef.addTableItem(taskName = new PamTableItem("Task Name", Types.CHAR, 50));
tableDef.addTableItem(dataStart = new PamTableItem("DataStart", Types.TIMESTAMP));
tableDef.addTableItem(dataEnd = new PamTableItem("DataEnd", Types.TIMESTAMP));
tableDef.addTableItem(runEnd = new PamTableItem("RunEnd", Types.TIMESTAMP));
tableDef.addTableItem(completionCode = new PamTableItem("CompletionCode", Types.CHAR, 20));
tableDef.addTableItem(note = new PamTableItem("Notes", Types.CHAR, TASK_NOTE_LENGTH));
taskLoggingDataBlock = new TaskLoggingDataBlock();
/**
* Note that completionCode Strings can be got from
* TaskMonitorData.getStatusString
*/
// table for startup write
startTableDef = new EmptyTableDefinition(tableName);
startTableDef.addTableItem(utc);
startTableDef.addTableItem(moduleType);
startTableDef.addTableItem(moduleName);
startTableDef.addTableItem(taskName);
startTableDef.addTableItem(dataStart);
startTableDef.addTableItem(note);
// startLogging = new StartLogging(taskLoggingDataBlock, startTableDef);
startCursorFinder = new CursorFinder();
// table for startup write
updateTableDef = new EmptyTableDefinition(tableName);
updateTableDef.addTableItem(dataEnd);
// table for startup write
completeTableDef = new EmptyTableDefinition(tableName);
completeTableDef.addTableItem(dataEnd);
completeTableDef.addTableItem(runEnd);
completeTableDef.addTableItem(completionCode);
completeCursorFinder = new CursorFinder();
}
public static TaskLogging getTaskLogging() {
if (taskLogging == null) {
taskLogging = new TaskLogging();
}
taskLogging.checkConnection();
return taskLogging;
}
private boolean checkConnection() {
// TODO Auto-generated method stub
PamConnection currentCon = DBControlUnit.findConnection();
if (currentCon != con) {
/**
* Need to check tables, etc.
*/
con = currentCon;
DBControlUnit.findDatabaseControl().getDbProcess().checkTable(tableDef);
}
return currentCon != null;
}
public boolean logTask(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
if (!checkConnection()) {
return false;
}
switch (monitorData.taskStatus) {
// case IDLE:
case STARTING:
return logStart(taskGroup, task, monitorData);
case RUNNING:
return logUpdate(taskGroup, task, monitorData);
case COMPLETE:
case CRASHED:
case INTERRUPTED:
return logComplete(taskGroup, task, monitorData);
default:
break;
}
return true;
}
/**
* Move all data from the cursor, even though not all objects may get used by the individual cursors.
* @param taskGroup
* @param task
* @param monitorData
*/
private void fillTableData(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
TaskGroupParams groupParams = taskGroup.getTaskGroupParams();
SQLTypes sqlTypes = con.getSqlTypes();
utc.setValue(sqlTypes.getTimeStamp(System.currentTimeMillis()));
moduleType.setValue(task.getUnitType());
moduleName.setValue(task.getUnitName());
taskName.setValue(task.getName());
dataStart.setValue(sqlTypes.getTimeStamp(groupParams.startRedoDataTime));
dataEnd.setValue(sqlTypes.getTimeStamp(monitorData.lastDataDate));
runEnd.setValue(sqlTypes.getTimeStamp(System.currentTimeMillis()));
completionCode.setValue(monitorData.taskStatus.toString());
note.setValue(groupParams.taskNote);
}
/**
* Get TaskMonitorData from the database cursor.
* @param taskGroup
* @param task
* @return
*/
private OldTaskData readTableData() {
SQLTypes sqlTypes = con.getSqlTypes();
long utc = SQLTypes.millisFromTimeStamp(this.utc.getValue());
String modType = moduleType.getDeblankedStringValue();
String modName = moduleName.getDeblankedStringValue();
String tskName = taskName.getDeblankedStringValue();
long dStart = SQLTypes.millisFromTimeStamp(dataStart.getValue());
long dEnd = SQLTypes.millisFromTimeStamp(dataEnd.getValue());
long procEnd = SQLTypes.millisFromTimeStamp(runEnd.getValue());
String compStatus = completionCode.getDeblankedStringValue();
TaskStatus status = null;
try {
status = TaskStatus.valueOf(TaskStatus.class, compStatus);
}
catch (IllegalArgumentException e) {
System.out.printf("Uknown completion code \"%s\" for task %s ended at %s\n", compStatus, tskName, PamCalendar.formatDateTime(dEnd));
}
String taskNote = note.getDeblankedStringValue();
OldTaskData monData = new OldTaskData(status, dStart, dEnd, utc, procEnd, taskNote);
return monData;
}
/**
* Get the last data for an offline task.
* @param taskGroup
* @param task
* @return
*/
public OldTaskData readLastTaskData(OfflineTaskGroup taskGroup, OfflineTask task) {
if (!checkConnection()) {
return null;
}
OldTaskData taskMonitorData = null;
String clause;
if (taskGroup == null) {
// only query on the task name (not good if there is more than one module with the same tasks)
clause = String.format(" WHERE TRIM(%s)='%s' ORDER BY Id DESC", taskName.getName(), task.getName());
}
else {
clause = String.format(" WHERE TRIM(%s)='%s' AND TRIM(%s)='%s' AND TRIM(%s)='%s' ORDER BY Id DESC",
moduleType.getName(), task.getUnitType(),
moduleName.getName(), task.getUnitName(),
taskName.getName(), task.getName());
}
String selStr = tableDef.getSQLSelectString(con.getSqlTypes()) + clause;
try {
Statement selStmt = con.getConnection().createStatement();
ResultSet results = selStmt.executeQuery(selStr);
if (results.next()) {
for (int i = 0; i < tableDef.getTableItemCount(); i++) {
PamTableItem tableItem = tableDef.getTableItem(i);
tableItem.setValue(results.getObject(i+1));
}
taskMonitorData = readTableData();
}
selStmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return taskMonitorData;
}
private boolean logStart(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
fillTableData(taskGroup, task, monitorData);
PamCursor startCursor = startCursorFinder.getCursor(con, startTableDef);
int dbInd = startCursor.immediateInsert(con);
if (dbInd > 0) {
loggingData.put(task, new TaskLoggingData(task, dbInd, monitorData));
return true;
}
else {
return false;
}
}
private boolean logUpdate(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
// TODO Auto-generated method stub
return true;
}
private boolean logComplete(OfflineTaskGroup taskGroup, OfflineTask task, TaskMonitorData monitorData) {
fillTableData(taskGroup, task, monitorData);
PamCursor startCursor = completeCursorFinder.getCursor(con, completeTableDef);
TaskLoggingData taskLogData = loggingData.get(task);
if (taskLogData == null) {
System.out.println("No logging data to update for offline task " + task.getName());
return false;
}
completeTableDef.getIndexItem().setValue(taskLogData.databaseIndex);
boolean updateOk = startCursor.immediateUpdate(con);
if (updateOk) {
taskLogData.monitorData = monitorData;
return true;
}
else {
return false;
}
}
// private class StartLogging extends SQLLogging {
//
// protected StartLogging(TaskLoggingDataBlock pamDataBlock, EmptyTableDefinition startTableDef) {
// super(pamDataBlock);
// setTableDefinition(startTableDef);
// }
//
// @Override
// public void setTableData(SQLTypes sqlTypes, PamDataUnit pamDataUnit) {
// // TODO Auto-generated method stub
//
// }
//
// }
}

View File

@ -0,0 +1,26 @@
package offlineProcessing.logging;
import PamguardMVC.PamDataUnit;
import offlineProcessing.OfflineTask;
import offlineProcessing.TaskMonitorData;
/**
* Wee class for holding the latest data on each task, most importantly the
* database index which is needed for updates.
* @author dg50
*
*/
public class TaskLoggingData extends PamDataUnit {
protected OfflineTask task;
protected int databaseIndex;
protected TaskMonitorData monitorData;
public TaskLoggingData(OfflineTask task, int databaseIndex, TaskMonitorData monitorData) {
super(System.currentTimeMillis());
this.task = task;
this.databaseIndex = databaseIndex;
this.monitorData = monitorData;
}
}

View File

@ -0,0 +1,17 @@
package offlineProcessing.logging;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamProcess;
/**
* Dummy datablock to use with some dummy SQLLogging classes in TaskLogging.
* @author dg50
*
*/
public class TaskLoggingDataBlock extends PamDataBlock {
public TaskLoggingDataBlock() {
super(TaskLoggingData.class, "Logging data", null, 0);
}
}

View File

@ -880,8 +880,9 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
pamController.saveViewerData();
}
// deal with anything that needs sorting out in the realm of UID's.
pamController.getUidManager().runShutDownOps();
// // deal with anything that needs sorting out in the realm of UID's.
// move this to pamController.pamClose()
// pamController.getUidManager().runShutDownOps();
// if the user doesn't want to save the config file, make sure they know
// that they'll lose any changes to the settings

View File

@ -303,6 +303,10 @@ public class PamUtilsFX {
if (fxItem == null) {
return null;
}
String tip = swingItem.getToolTipText();
if (tip != null) {
fxItem.setUserData("Tip:" + tip);
}
// move over any action listeners from swing to fx.
fxItem.setOnAction(new EventHandler<ActionEvent>() {
@Override
@ -384,6 +388,13 @@ public class PamUtilsFX {
if (jItem == null) {
return null;
}
Object userData = fxItem.getUserData();
if (userData instanceof String) {
String tip = (String) userData;
if (tip.startsWith("Tip:")) {
jItem.setToolTipText(tip.substring(4));
}
}
jItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {

View File

@ -24,10 +24,23 @@ public class GlobalArguments {
/**
* Get a global parameter value
* @param name value name
* @return value
* @return value in original String format
*/
public static String getParam(String name) {
return globalFlags.get(name);
}
/**
* Get a param read as an integer
* @param name
* @return value as integer or null if not set. Throws exception if invalid integer.
*/
public static Integer getParamI(String name) {
String val = getParam(name);
if (val == null) {
return null;
}
return Integer.valueOf(val);
}
}

View File

@ -23,6 +23,7 @@ package pamguard;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import Acquisition.AcquisitionControl;
import Acquisition.FolderInputSystem;
import PamController.PamController;
import PamController.PamGUIManager;
@ -211,8 +212,15 @@ public class Pamguard {
System.out.println("Running using settings from " + autoPsf);
}
else if (anArg.equalsIgnoreCase("-port")) {
// port id to open a udp port to receive commands
pamBuoyGlobals.setNetworkControlPort(Integer.parseInt(args[iArg++]));
}
else if (anArg.equalsIgnoreCase("-mport")) {
// multicast control (for multiple PAMGuards)
String mAddr = args[iArg++];
int mPort = Integer.parseInt(args[iArg++]);
pamBuoyGlobals.setMultiportConfig(mAddr, mPort);
}
else if (anArg.equalsIgnoreCase("-nolog")) {
System.out.println("Disabling log file from command line switch...");
ProxyPrintStream.disableLogFile();
@ -229,6 +237,14 @@ public class Pamguard {
// source folder for wav files (or other supported sound files)
GlobalArguments.setParam(FolderInputSystem.GlobalWavFolderArg, args[iArg++]);
}
else if (anArg.equalsIgnoreCase(PamController.AUTOSTART)) {
// auto start processing.
GlobalArguments.setParam(PamController.AUTOSTART, PamController.AUTOSTART);
}
else if (anArg.equalsIgnoreCase(PamController.AUTOEXIT)) {
// auto exit at end of processing.
GlobalArguments.setParam(PamController.AUTOEXIT, PamController.AUTOEXIT);
}
else if (anArg.equalsIgnoreCase("-help")) {
System.out.println("--PamGuard Help");
System.out.println("\n--For standard GUI deployment run without any options.\n");
@ -247,7 +263,7 @@ public class Pamguard {
}
//going to need the run mode inside a Runnable later
final int chosenRunMode = runMode;
if(runMode != PamController.RUN_REMOTE) {
if(runMode != PamController.RUN_REMOTE && PamGUIManager.getGUIType() != PamGUIManager.NOGUI) {
// ScreenSize.startScreenSizeProcess();
ScreenSize.getScreenBounds();
}
@ -329,10 +345,16 @@ public class Pamguard {
Thread.setDefaultUncaughtExceptionHandler(new PamExceptionHandler());
System.setProperty("sun.awt.exception.handler", PamExceptionHandler.class.getName());
//Amongst other stuff the call to PamController.create()
//will build and show the GUI and the user can't
//do much else until that's done so let's have all
//that kicked off from with the EDT CJB 2009-06-16
/*
* Amongst other stuff the call to PamController.create()
* will build and show the GUI and the user can't
* do much else until that's done so let's have all
* that kicked off from with the EDT CJB 2009-06-16
* Either of these will call .create, just one is in a different
* thread, so it's at the end of the create function that other automatic
* processes should be started.
*
*/
if (PamGUIManager.isSwing()) {
SwingUtilities.invokeLater(createPamguard);

View File

@ -1,6 +1,7 @@
package soundPlayback;
import PamDetection.RawDataUnit;
import PamView.dialog.PamDialogPanel;
/**
* Interface to device types that can be used to play
@ -67,4 +68,10 @@ public interface FilePlaybackDevice {
public String getDeviceName();
/**
* Get a settings panel for additional options. Can be null.
* @return settings panel or null for additional options.
*/
public PamDialogPanel getSettingsPanel();
}

View File

@ -15,6 +15,7 @@ import Acquisition.SoundCardSystem;
import PamDetection.RawDataUnit;
import PamUtils.PamCalendar;
import PamUtils.PamUtils;
import PamView.dialog.PamDialogPanel;
import warnings.PamWarning;
import warnings.WarningSystem;
@ -89,4 +90,10 @@ public class SoundCardFilePlayback implements FilePlaybackDevice {
return soundCardPlaybackBase.getDeviceState();
}
@Override
public PamDialogPanel getSettingsPanel() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -20,8 +20,11 @@ import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import PamView.dialog.GenericSwingDialog;
import PamView.dialog.PamDialog;
import PamView.dialog.PamDialogPanel;
import PamView.dialog.PamGridBagContraints;
import PamView.dialog.SettingsButton;
import PamguardMVC.PamDataBlock;
import PamguardMVC.PamRawDataBlock;
import soundPlayback.FilePlayback;
@ -48,6 +51,8 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
private FilePlayback filePlayback;
private PlaybackParameters playbackParameters;
private SettingsButton deviceSettingsButton;
private JButton defButton;
@ -57,6 +62,8 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
private PamDataBlock dataSource;
private FilePlaybackDevice selectedDeviceType;
/**
* Dialog component for sound playback when input is from a file.
* <p>
@ -91,10 +98,23 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
c.gridy++;
PamDialog.addComponent(panel, deviceTypes, c);
c.gridy++;
c.gridwidth = 3;
PamDialog.addComponent(panel, new JLabel("Output device name ..."), c);
c.gridx += c.gridwidth;
c.gridwidth = 1;
PamDialog.addComponent(panel, deviceSettingsButton = new SettingsButton(), c);
c.gridx = 0;
c.gridwidth = 4;
c.gridy++;
PamDialog.addComponent(panel, soundCards, c);
deviceSettingsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
deviceSettings();
}
});
c.gridy++;
c.gridx = 0;
c.gridwidth = 1;
@ -153,6 +173,17 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
}
protected void deviceSettings() {
if (selectedDeviceType == null) {
return;
}
PamDialogPanel devicePanel = selectedDeviceType.getSettingsPanel();
if (devicePanel == null) {
return;
}
GenericSwingDialog.showDialog(getParentDialog(), "More Settings", devicePanel);
}
private void playSpeedChange() {
playbackSpeed.setText(playSpeedSlider.getRatioString());
sayDecimateInfo();
@ -280,6 +311,9 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
if (parentDialog != null) {
parentDialog.pack();
}
if (selectedDeviceType != null) {
deviceSettingsButton.setEnabled(selectedDeviceType.getSettingsPanel() != null);
}
}
}
@ -297,7 +331,7 @@ public class FilePlaybackDialogComponent extends PlaybackDialogComponent {
public void fillDeviceSpecificList() {
int deviceType = deviceTypes.getSelectedIndex();
deviceType = Math.max(0, deviceType);
FilePlaybackDevice selectedDeviceType = filePlayback.getFilePBDevices().get(deviceType);
selectedDeviceType = filePlayback.getFilePBDevices().get(deviceType);
soundCards.removeAllItems();
String[] devList = selectedDeviceType.getDeviceNames();
for (int i = 0; i < devList.length; i++) {