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
This commit is contained in:
Douglas Gillespie 2022-08-01 11:13:24 +01:00 committed by GitHub
parent 55f5a3fcf1
commit c9f2ab3e97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1249 additions and 388 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,6 +52,7 @@ 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.NetworkController;
@ -129,6 +131,11 @@ public class PamController implements PamControllerInterface, PamSettings {
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.
*/
@ -300,10 +307,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 +556,7 @@ public class PamController implements PamControllerInterface, PamSettings {
clearSelectorsAndSymbols();
/**
* Debug code for starting PG as soon as it's initialised.
*/
@ -660,11 +691,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 +1341,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;
/**
@ -405,6 +408,13 @@ public interface PamControllerInterface {
*/
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

@ -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

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

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

@ -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

@ -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

@ -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

@ -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);
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();
//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

@ -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

@ -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];
@ -145,22 +153,32 @@ public class OLProcessDialog extends PamDialog {
c.gridy++;
}
JPanel progressPanel = new JPanel(new GridBagLayout());
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 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,9 +347,34 @@ 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();
PamDataBlock primaryDataBlock = taskGroup.getPrimaryDataBlock();
@ -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();
}
/**
@ -97,6 +129,36 @@ public abstract class OfflineTask<T extends PamDataUnit> {
*/
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
* @return true or false

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,22 +841,34 @@ 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);
}
}
@ -748,6 +876,12 @@ public class OfflineTaskGroup implements PamSettings {
* 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_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;
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;
// 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 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);
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;
String fileName;
public long lastDataDate;
/**
* Constructor used to set the status
* @param status status
*/
TaskMonitorData(int status) {
this.status = status;
dataType = SET_STATUS;
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;
}
/**
* 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;
}
// 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;
// }
/**
* Constructor used to set the current file name
* @param fileName file Name
*/
TaskMonitorData(String fileName) {
this.fileName = fileName;
dataType = SET_FILENAME;
}
// /**
// *
// * @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";
// }
/**
* 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";
}
/**
* 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

@ -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;
@ -229,6 +230,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");
@ -329,10 +338,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);