This commit is contained in:
Douglas Gillespie 2022-08-01 10:51:00 +01:00
commit 907a3af77b
28 changed files with 1128 additions and 364 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

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

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

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

@ -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];
@ -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);
}
}