Merge from DG (#124)

* claspath update

* Batch processing

Adding functionality for offline task batch processing.
This commit is contained in:
Douglas Gillespie 2024-01-18 09:31:00 +00:00 committed by GitHub
parent b373e169f2
commit 43811c1f9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 507 additions and 58 deletions

View File

@ -6,8 +6,9 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes> <attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>

View File

@ -31,12 +31,8 @@ import javax.swing.JMenuBar;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import offlineProcessing.OfflineTask;
import offlineProcessing.OfflineTaskGroup; import offlineProcessing.OfflineTaskGroup;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import PamController.status.ModuleStatus; import PamController.status.ModuleStatus;
import PamController.status.ModuleStatusManager; import PamController.status.ModuleStatusManager;
import PamController.status.ProcessCheck; import PamController.status.ProcessCheck;
@ -848,6 +844,16 @@ public abstract class PamControlledUnit implements SettingsNameProvider {
} }
return worstStatus; return worstStatus;
} }
/**
* Get the offline state of this module. This can generally
* be idle, but can be a higher state when map making at startup
* and when running an offline task.
* @return
*/
public int getOfflineState() {
return PamController.PAM_IDLE;
}
// /** // /**
// * Get a list of available offline tasks for this module. This is mostly used for tasks that // * Get a list of available offline tasks for this module. This is mostly used for tasks that

View File

@ -37,6 +37,7 @@ import javax.swing.ToolTipManager;
import com.jcraft.jsch.ConfigRepository.Config; import com.jcraft.jsch.ConfigRepository.Config;
import com.sun.xml.bind.v2.TODO; import com.sun.xml.bind.v2.TODO;
import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionProcess; import Acquisition.AcquisitionProcess;
//import com.sun.org.apache.xerces.internal.dom.DocumentImpl; //import com.sun.org.apache.xerces.internal.dom.DocumentImpl;
@ -65,6 +66,7 @@ import PamController.command.TerminalController;
import PamController.command.WatchdogComms; import PamController.command.WatchdogComms;
import PamController.fileprocessing.ReprocessManager; import PamController.fileprocessing.ReprocessManager;
import PamController.masterReference.MasterReferencePoint; import PamController.masterReference.MasterReferencePoint;
import PamController.settings.BatchViewSettingsImport;
import PamController.settings.output.xml.PamguardXMLWriter; import PamController.settings.output.xml.PamguardXMLWriter;
import PamController.settings.output.xml.XMLWriterDialog; import PamController.settings.output.xml.XMLWriterDialog;
import PamController.soundMedium.GlobalMediumManager; import PamController.soundMedium.GlobalMediumManager;
@ -124,6 +126,8 @@ public class PamController implements PamControllerInterface, PamSettings {
public static final int PAM_INITIALISING = 4; public static final int PAM_INITIALISING = 4;
public static final int PAM_STOPPING = 5; public static final int PAM_STOPPING = 5;
public static final int PAM_COMPLETE = 6; public static final int PAM_COMPLETE = 6;
public static final int PAM_MAPMAKING = 7;
public static final int PAM_OFFLINETASK = 8;
// status' for RunMode = RUN_PAMVIEW // status' for RunMode = RUN_PAMVIEW
public static final int PAM_LOADINGDATA = 2; public static final int PAM_LOADINGDATA = 2;
@ -235,6 +239,7 @@ public class PamController implements PamControllerInterface, PamSettings {
*/ */
private Thread statusCheckThread; private Thread statusCheckThread;
private WaitDetectorThread detectorEndThread; private WaitDetectorThread detectorEndThread;
private boolean firstDataLoadComplete;
private PamController(int runMode, Object object) { private PamController(int runMode, Object object) {
@ -437,7 +442,7 @@ public class PamController implements PamControllerInterface, PamSettings {
// addModule(mi, "Temporary Database"); // addModule(mi, "Temporary Database");
// } // }
// Add a note to the putput console for the user to ignore the SLF4J warning (see http://www.slf4j.org/codes.html#StaticLoggerBinder // Add a note to the output console for the user to ignore the SLF4J warning (see http://www.slf4j.org/codes.html#StaticLoggerBinder
// for details). I spent a few hours trying to get rid of this warning, but without any luck. If you do a google search // for details). I spent a few hours trying to get rid of this warning, but without any luck. If you do a google search
// there are a lot of forum suggestions on how to fix, but none seemed to work for me. Added both slf4j-nop and // there are a lot of forum suggestions on how to fix, but none seemed to work for me. Added both slf4j-nop and
// slf4j-simple to dependency list, neither made a difference. Changed order of dependencies, ran purges and updates, // slf4j-simple to dependency list, neither made a difference. Changed order of dependencies, ran purges and updates,
@ -492,17 +497,31 @@ public class PamController implements PamControllerInterface, PamSettings {
addView(guiFrameManager.initPrimaryView(this, pamModelInterface)); addView(guiFrameManager.initPrimaryView(this, pamModelInterface));
} }
/**
* Calling this will cause a callback to this.restoreSettings which
* includes a list of modules which will then get created, and in turn
* load all of their own settings from the settings manager.
*/
PamSettingManager.getInstance().registerSettings(this); PamSettingManager.getInstance().registerSettings(this);
/**
* For offline batch processing a few funnies happen here. We'll be open
* in viewer mode, but it's likely a psf will have been passed as an input argument.
* We will therefore have to extract all the modules from that psfx as well and either
* add them as new modules, or get their settings and use those to update existing settings
* That should probably be done here before the final calls to setup processes, etc.
*/
if (getRunMode() == RUN_PAMVIEW && PamSettingManager.remote_psf != null) {
loadOtherSettings(PamSettingManager.remote_psf);
}
/*
* Get any other required modules for this run mode.
*/
pamModelInterface.startModel(); pamModelInterface.startModel();
setupProcesses(); setupProcesses();
// if (getRunMode() == RUN_PAMVIEW) {
// createViewerStatusBar();
// pamControlledUnits.add(new OfflineProcessingControlledUnit("OfflineProcessing"));
// }
/* /*
* We are running as a remote application, start process straight away! * We are running as a remote application, start process straight away!
*/ */
@ -573,6 +592,7 @@ public class PamController implements PamControllerInterface, PamSettings {
// }); // });
} }
/** /**
* Clear all data selectors and symbol managers. Required since some of these will have loaded as various modules were created, * Clear all data selectors and symbol managers. Required since some of these will have loaded as various modules were created,
* but may also require additional data selectors and symbol managers from super detections which were not availble. * but may also require additional data selectors and symbol managers from super detections which were not availble.
@ -585,6 +605,11 @@ public class PamController implements PamControllerInterface, PamSettings {
} }
/**
* This gets called after other data initialisation tasks (such as data mapping).
* @author dg50
*
*/
class DataInitialised implements Runnable { class DataInitialised implements Runnable {
@Override @Override
public void run() { public void run() {
@ -1792,6 +1817,10 @@ public class PamController implements PamControllerInterface, PamSettings {
if (moduleChange(changeType)) { if (moduleChange(changeType)) {
clearSelectorsAndSymbols(); clearSelectorsAndSymbols();
} }
if (changeType == DATA_LOAD_COMPLETE) {
firstDataLoadComplete = true;
}
} }
@ -1928,12 +1957,75 @@ public class PamController implements PamControllerInterface, PamSettings {
public void setPamStatus(int pamStatus) { public void setPamStatus(int pamStatus) {
this.pamStatus = pamStatus; this.pamStatus = pamStatus;
/*
* This only get's called once when set idle at viewer mode startup.
*/
// System.out.printf("******* PamController.setPamStatus to %d, real status is %d\n", pamStatus, getRealStatus());
if (getRunMode() != RUN_PAMVIEW) { if (getRunMode() != RUN_PAMVIEW) {
TopToolBar.enableStartButton(pamStatus == PAM_IDLE); TopToolBar.enableStartButton(pamStatus == PAM_IDLE);
TopToolBar.enableStopButton(pamStatus == PAM_RUNNING); TopToolBar.enableStopButton(pamStatus == PAM_RUNNING);
} }
showStatusWarning(pamStatus); showStatusWarning(pamStatus);
} }
/**
* This was within the StatusCommand class, but useful to have it here since it's needed
* in more than one place. In viewer mode at startup there are a number of things going on
* in different threads, such as the creation of datamaps, and this can (hopefully) handle those bespoke
* goings on.
* @return program status for multithreaded statup tasks.
*/
public int getRealStatus() {
PamController pamController = PamController.getInstance();
if (pamController.isInitializationComplete() == false) {
return PamController.PAM_INITIALISING;
}
int runMode = PamController.getInstance().getRunMode();
if (runMode == PamController.RUN_NETWORKRECEIVER) {
return PamController.PAM_RUNNING;
}
int status = pamController.getPamStatus();
if (status == PamController.PAM_IDLE) {
status = PamController.PAM_IDLE;
}
else {
ArrayList<PamControlledUnit> daqs = PamController.getInstance().findControlledUnits(AcquisitionControl.unitType);
if (daqs != null) for (int i = 0; i < daqs.size(); i++) {
try {
AcquisitionControl daq = (AcquisitionControl) daqs.get(i);
if (daq.isStalled()) {
status = PamController.PAM_STALLED;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
WatchdogComms watchdogComms = PamController.getInstance().getWatchdogComms();
status = watchdogComms.getModifiedWatchdogState(status);
/*
* This function is now being used in batch processing of offline data, where it may be necessary
* to get status information from many different modules, for example when executing offline tasks
* or just at startup while generating datamaps and datagrams.
* So go through all modules and get the highest state of any of them.
*/
if (getRunMode() == RUN_PAMVIEW) {
if (firstDataLoadComplete == false) {
status = PAM_INITIALISING;
}
try {
for (PamControlledUnit aUnit : pamConfiguration.getPamControlledUnits()) {
status = Math.max(status, aUnit.getOfflineState());
}
}
catch (Exception e) {
//just incase there is a concurrent modification at startup.
}
}
return status;
}
/** /**
* show a warning when we're waiting for detectors to stop * show a warning when we're waiting for detectors to stop
@ -2218,6 +2310,31 @@ public class PamController implements PamControllerInterface, PamSettings {
private boolean manualStop; private boolean manualStop;
/**
* Used when in viewer mode and planning batch processing with a modified
* configuration, i.e. the command line has been supplied a normal viewer mode
* database and also a psfx file. The settings from the database will already have
* been loaded, this will load any modules that weren't there and will override all the
* settings in other modules with these ones (except some specials such as data storage locations)
* @param psfxFile Name of additional psfx file.
*/
private boolean loadOtherSettings(String psfxName) {
File psfxFile = new File(psfxName);
if (psfxFile.exists() == false) {
return false;
}
PamSettingsGroup settingsGroup = PSFXReadWriter.getInstance().loadFileSettings(psfxFile);
if (settingsGroup == null) {
return false;
}
BatchViewSettingsImport importer = new BatchViewSettingsImport(this, settingsGroup);
importer.importSettings();
return true;
}
/** /**
* Called to load a specific set of PAMGUARD settings in * Called to load a specific set of PAMGUARD settings in
* viewer mode, which were previously loaded in from a * viewer mode, which were previously loaded in from a

View File

@ -44,6 +44,7 @@ import javax.swing.plaf.FontUIResource;
import pamViewFX.fxNodes.utilsFX.PamUtilsFX; import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
import pamViewFX.fxSettingsPanes.SettingsFileDialogFX; import pamViewFX.fxSettingsPanes.SettingsFileDialogFX;
import pamguard.GlobalArguments;
//XMLSettings //XMLSettings
//import org.jdom.Document; //import org.jdom.Document;
@ -492,7 +493,7 @@ public class PamSettingManager {
/** /**
* Call just before PAMGUARD exits to save the settings * Call just before PAMGUARD exits to save the settings
* either to psf and / or database tables. * either to psf and / or database tables.
* @return true if settings saved sucessfully. * @return true if settings saved successfully.
*/ */
public boolean saveFinalSettings() { public boolean saveFinalSettings() {
int runMode = PamController.getInstance().getRunMode(); int runMode = PamController.getInstance().getRunMode();
@ -1029,8 +1030,9 @@ public class PamSettingManager {
loadingLocalSettings = true; loadingLocalSettings = true;
loadSettingsFileData(); loadSettingsFileData();
if (PamSettingManager.RUN_REMOTE == false) { if (PamSettingManager.RUN_REMOTE == false && GlobalArguments.isBatch() == false) {
if (settingsFileData != null) { if (settingsFileData != null) {
TipOfTheDayManager.getInstance().setShowAtStart(settingsFileData.showTipAtStartup); TipOfTheDayManager.getInstance().setShowAtStart(settingsFileData.showTipAtStartup);
if (settingsFileData.showTipAtStartup) { if (settingsFileData.showTipAtStartup) {

View File

@ -2,6 +2,7 @@ package PamController.command;
import Acquisition.AcquisitionControl; import Acquisition.AcquisitionControl;
import PamController.PamController; import PamController.PamController;
import offlineProcessing.OfflineTaskManager;
import pamViewFX.PamControlledGUIFX; import pamViewFX.PamControlledGUIFX;
/** /**
@ -21,6 +22,19 @@ public class BatchStatusCommand extends ExtCommand {
@Override @Override
public String execute(String command) { public String execute(String command) {
if (PamController.getInstance().getRunMode() == PamController.RUN_NORMAL) {
return getNormalModeStatus(command);
}
else {
return getViewerModeStatus(command);
}
}
private String getViewerModeStatus(String command) {
return OfflineTaskManager.getManager().getBatchStatus();
}
private String getNormalModeStatus(String command) {
AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.class, null); AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
if (daqControl == null) { if (daqControl == null) {
return null; return null;

View File

@ -31,33 +31,7 @@ public class StatusCommand extends ExtCommand {
private int getRealStatus() { private int getRealStatus() {
PamController pamController = PamController.getInstance(); PamController pamController = PamController.getInstance();
if (pamController.isInitializationComplete() == false) { return pamController.getRealStatus();
return PamController.PAM_INITIALISING;
}
int runMode = PamController.getInstance().getRunMode();
if (runMode == PamController.RUN_NETWORKRECEIVER) {
return PamController.PAM_RUNNING;
}
int status = pamController.getPamStatus();
if (status == PamController.PAM_IDLE) {
status = PamController.PAM_IDLE;
}
else {
ArrayList<PamControlledUnit> daqs = PamController.getInstance().findControlledUnits(AcquisitionControl.unitType);
if (daqs != null) for (int i = 0; i < daqs.size(); i++) {
try {
AcquisitionControl daq = (AcquisitionControl) daqs.get(i);
if (daq.isStalled()) {
status = PamController.PAM_STALLED;
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
WatchdogComms watchdogComms = PamController.getInstance().getWatchdogComms();
return watchdogComms.getModifiedWatchdogState(status);
} }

View File

@ -0,0 +1,155 @@
package PamController.settings;
import java.util.ArrayList;
import PamController.DataInputStore;
import PamController.OfflineDataStore;
import PamController.OfflineFileDataStore;
import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings;
import PamController.PamController;
import PamController.PamSettingManager;
import PamController.PamSettings;
import PamController.PamSettingsGroup;
import PamController.UsedModuleInfo;
import PamModel.PamModuleInfo;
/**
* A set of functions to handle importing and overriding settings imported from a psfx during
* batch mode processing in viewer mode. Some of this is quite similar to code in SettingsImport
* but different enough that it's easier to have in a separate set of functions.
* @author dg50
*
*/
public class BatchViewSettingsImport {
private PamController pamController;
private PamSettingsGroup settingsGroup;
private SettingsImport settingsImport;
public BatchViewSettingsImport(PamController pamController, PamSettingsGroup settingsGroup) {
this.pamController = pamController;
this.settingsGroup = settingsGroup;
settingsImport = new SettingsImport(pamController);
}
public boolean importSettings() {
// first organise by controlled unit
ArrayList<SettingsImportGroup> moduleGroups = settingsImport.organiseSettingsGroups(settingsGroup.getUnitSettings());
// can now go through those modules and see which exist and which need to be added. Not asking questions, just doing it!
for (SettingsImportGroup moduleGroup : moduleGroups) {
UsedModuleInfo moduleInfo = moduleGroup.getUsedModuleInfo();
PamControlledUnit exModule = pamController.findControlledUnit(moduleInfo.getUnitType(), moduleInfo.getUnitName());
boolean existingStore = false;
if (exModule != null) {
existingStore = isDataStore(exModule);
System.out.printf("Module %s:%s already exists in model (data store: %s)\n", moduleInfo.getUnitType(), moduleInfo.getUnitName(), Boolean.valueOf(existingStore));
}
else {
System.out.printf("Module %s:%s will be added to model\n", moduleInfo.getUnitType(), moduleInfo.getUnitName());
// add the module. No questions asked.
PamModuleInfo pamModuleInfo = moduleGroup.getPamModuleInfo();
if (pamModuleInfo == null) {
System.out.printf("Module %s:%s is not available to this PAMGuard installation\n", moduleInfo.getUnitType(), moduleInfo.getUnitName());
continue;
}
exModule = pamController.addModule(pamModuleInfo, moduleInfo.getUnitName());
}
// set the settings for that module, but only if it's NOT a data storage module.
if (exModule == null) {
continue;
}
// if (exModule.getUnitName().contains("Noise")) {
// System.out.printf("restoring settings for %s, %s\n", exModule.getUnitType(), exModule.getUnitName());
//
// }
if (isDataStore(exModule)) {
System.out.printf("Skip restoring settings for %s, %s\n", exModule.getUnitType(), exModule.getUnitName());
continue;
}
restoreSettings(moduleGroup.getMainSettings());
ArrayList<PamControlledUnitSettings> subSets = moduleGroup.getSubSettings();
if (subSets != null) {
for (PamControlledUnitSettings aSet : subSets) {
restoreSettings(aSet);
}
}
// exModule.notifyModelChanged(PamController.INITIALIZATION_COMPLETE);
// if (exModule.getTabPanel() != null) {
//// exModule.getTabPanel()
// }
}
/*
* Don't need to call this here since it get's called shortly
* from PAMController once all modules are in place.
*/
// pamController.notifyModelChanged(PamController.INITIALIZATION_COMPLETE);
// send out an initialisation complete to help restore settings
// ArrayList<PamControlledUnitSettings> allSettings = settingsGroup.getUnitSettings();
// for (PamControlledUnitSettings aSet : allSettings) {
// PamSettings owner = PamSettingManager.getInstance().findSettingsOwner(aSet.getUnitType(), aSet.getUnitName(), null);
// if (owner == null) {
// System.out.printf("Cannot find owner for %s, %s, %s\n", aSet.getUnitType(), aSet.getUnitName(), aSet.getOwnerClassName());
// }
// else {
// owner.restoreSettings(aSet);
// }
// }
return true;
}
/**
* Find the owner of these settings and send it it's new settings.
* @param aSet
* @return true if found and set sucessfully.
*/
private boolean restoreSettings(PamControlledUnitSettings aSet) {
PamSettings owner = PamSettingManager.getInstance().findSettingsOwner(aSet.getUnitType(), aSet.getUnitName(), null);
if (owner == null) {
System.out.printf("Cannot find owner for %s, %s, %s\n", aSet.getUnitType(), aSet.getUnitName(), aSet.getOwnerClassName());
return false;
}
else {
try {
owner.restoreSettings(aSet);
}
catch (Exception e) {
System.out.printf("Exception restoring settings %s, %s, %s\n", aSet.getUnitType(), aSet.getUnitName(), aSet.getOwnerClassName());
e.printStackTrace();
return false;
}
}
return true;
}
/**
* Is the module a data store. If it is, we probably won't want to copy over it's settings.
* @param controlledUnit PAMGuard module
* @return true if it's data output or input.
*/
private boolean isDataStore(PamControlledUnit controlledUnit) {
return isDataStore(controlledUnit.getClass());
}
/**
* Is the class a data store. If it is, we probably won't want to copy over it's settings.
* @param moduleClass module class
* @return true if it's data output or input.
*/
private boolean isDataStore(Class<? extends PamControlledUnit> moduleClass) {
//OfflineFileDataStore, DataInputStore
if (OfflineDataStore.class.isAssignableFrom(moduleClass)) {
return true;
}
if (DataInputStore.class.isAssignableFrom(moduleClass)) {
return true;
}
return false;
}
}

View File

@ -29,7 +29,10 @@ import PamView.dialog.warn.WarnOnce;
*/ */
public class SettingsImport { public class SettingsImport {
private PamController pamController;
public SettingsImport(PamController pamController) { public SettingsImport(PamController pamController) {
this.pamController = pamController;
} }
/** /**
@ -235,7 +238,7 @@ public class SettingsImport {
* @param settings * @param settings
* @return * @return
*/ */
ArrayList<SettingsImportGroup> organiseSettingsGroups(ArrayList<PamControlledUnitSettings> settings) { public ArrayList<SettingsImportGroup> organiseSettingsGroups(ArrayList<PamControlledUnitSettings> settings) {
/** /**
* this needs rewriting for psfx files which are organised differently. first we need to find * this needs rewriting for psfx files which are organised differently. first we need to find
* a list of PAMGuard modules by finding the settings group of the PAMController. * a list of PAMGuard modules by finding the settings group of the PAMController.

View File

@ -944,14 +944,17 @@ final public class PamModel implements PamSettings {
} }
/* (non-Javadoc)
* @see PamModel.PamModelInterface#startModel()
/**
* Add any remaining REQUIRED modules.<br>
* this get's called after the PamController has loaded it's main settings.
* So at this point, go through all the PamModuleInfo's and check that
* all have at least the minimum number required
* @return true
*/ */
public synchronized boolean startModel() { public synchronized boolean startModel() {
/* /*
* this get's called after the PamController has loaded it's main settings.
* So at this point, go through all the PamModuleInfo's and check that
* all have at least the minimum number required
*/ */
PamSettingManager.getInstance().registerSettings(this); PamSettingManager.getInstance().registerSettings(this);
@ -968,11 +971,11 @@ final public class PamModel implements PamSettings {
// writeModuleList(); // writeModuleList();
return false; return true;
} }
/** /**
* Really just debu goutput to make a list of all modules ... * Really just debug output to make a list of all modules ...
*/ */
private void writeModuleList() { private void writeModuleList() {
ArrayList<PamModuleInfo> moduleInfoList = PamModuleInfo.getModuleList(); ArrayList<PamModuleInfo> moduleInfoList = PamModuleInfo.getModuleList();

View File

@ -77,6 +77,7 @@ import pamScrollSystem.PamScrollerData;
import pamScrollSystem.RangeSpinner; import pamScrollSystem.RangeSpinner;
import pamScrollSystem.RangeSpinnerListener; import pamScrollSystem.RangeSpinnerListener;
import pamScrollSystem.jumping.ScrollJumper; import pamScrollSystem.jumping.ScrollJumper;
import pamguard.GlobalArguments;
import soundPlayback.PlaybackControl; import soundPlayback.PlaybackControl;
import soundPlayback.PlaybackProgressMonitor; import soundPlayback.PlaybackProgressMonitor;
import userDisplay.UserDisplayControl; import userDisplay.UserDisplayControl;
@ -274,7 +275,8 @@ InternalFrameListener, DisplayPanelContainer, SpectrogramParametersUser, PamSett
// this should result in settings being loaded if they exist. // this should result in settings being loaded if they exist.
PamSettingManager.getInstance().registerSettings(this); // always need to register, even if we're using old parameters PamSettingManager.getInstance().registerSettings(this); // always need to register, even if we're using old parameters
// } // }
if (spectrogramParameters == null) { boolean isBatch = GlobalArguments.getParam("-batch") != null;
if (spectrogramParameters == null && isBatch == false) {
this.spectrogramParameters = new SpectrogramParameters(); this.spectrogramParameters = new SpectrogramParameters();
PamView view = userDisplayControl.getPamView(); PamView view = userDisplayControl.getPamView();
if (view != null) { if (view != null) {
@ -285,6 +287,14 @@ InternalFrameListener, DisplayPanelContainer, SpectrogramParametersUser, PamSett
} }
} }
} }
if (spectrogramParameters == null) {
/*
* this can happen in batch mode if a display was added.
* Hopefully not a problem, but may need to set some parameters to
* set display up correctly.
*/
spectrogramParameters = new SpectrogramParameters();
}
spectrogramDisplay = this; spectrogramDisplay = this;

View File

@ -155,6 +155,8 @@ PamSettingsSource, DataOutputStore {
private PamControlledGUISwing binaryStoreGUISwing; private PamControlledGUISwing binaryStoreGUISwing;
private BackupInformation backupInformation; private BackupInformation backupInformation;
private BinaryDataMapMaker dataMapMaker;
public static int getCurrentFileFormat() { public static int getCurrentFileFormat() {
return CURRENT_FORMAT; return CURRENT_FORMAT;
@ -424,6 +426,25 @@ PamSettingsSource, DataOutputStore {
} }
return true; return true;
} }
public boolean checkCommandLine() {
/*
* check to see if there is a command line override of the currently stored folder name.
*/
String globFolder = GlobalArguments.getParam(GlobalFolderArg);
if (globFolder == null) {
return false;
}
boolean ok = checkGlobFolder(globFolder);
if (ok) {
binaryStoreSettings.setStoreLocation(globFolder); // remember it.
return true;
}
else {
System.err.println("Unable to set binary storage folder " + globFolder);
return false;
}
}
/** /**
* Set and create if necessary the global folder. * Set and create if necessary the global folder.
@ -601,7 +622,8 @@ PamSettingsSource, DataOutputStore {
// this first operation should be fast enough that it doesn't // this first operation should be fast enough that it doesn't
// need rethreading. // need rethreading.
if (isViewer()) { boolean hasCommandLine = checkCommandLine();
if (isViewer() && !hasCommandLine) {
BinaryStoreSettings newSettings = null; BinaryStoreSettings newSettings = null;
if (PamGUIManager.isSwing()) { if (PamGUIManager.isSwing()) {
//open the swing dialog. //open the swing dialog.
@ -790,8 +812,8 @@ PamSettingsSource, DataOutputStore {
* updates to the dialog to display progress, then close the * updates to the dialog to display progress, then close the
* dialog. * dialog.
*/ */
BinaryDataMapMaker bdmm = new BinaryDataMapMaker(this); dataMapMaker = new BinaryDataMapMaker(this);
AWTScheduler.getInstance().scheduleTask(bdmm); AWTScheduler.getInstance().scheduleTask(dataMapMaker);
} }
@ -923,6 +945,7 @@ PamSettingsSource, DataOutputStore {
} }
PamController.getInstance().notifyModelChanged(PamControllerInterface.CHANGED_OFFLINE_DATASTORE); PamController.getInstance().notifyModelChanged(PamControllerInterface.CHANGED_OFFLINE_DATASTORE);
// System.out.println("BinaryDataMapMaker really done " + this); // System.out.println("BinaryDataMapMaker really done " + this);
dataMapMaker = null;
} }
@Override @Override
@ -2554,6 +2577,18 @@ PamSettingsSource, DataOutputStore {
return storeDeleter.deleteDataFrom(timeMillis); return storeDeleter.deleteDataFrom(timeMillis);
} }
@Override @Override
public int getOfflineState() {
int state = super.getOfflineState();
if (dataMapMaker != null) {
System.out.println("Binary store is map making");
state = Math.max(state, PamController.PAM_MAPMAKING);
}
if (datagramManager != null & datagramManager.getStatus()) {
state = Math.max(state, PamController.PAM_MAPMAKING);
System.out.println("Binary store is creating datagram");
}
return state;
public String getDataLocation() { public String getDataLocation() {
return binaryStoreSettings.getStoreLocation(); return binaryStoreSettings.getStoreLocation();
} }

View File

@ -12,6 +12,7 @@ import javax.swing.SwingWorker;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import pamViewFX.pamTask.PamTaskUpdate; import pamViewFX.pamTask.PamTaskUpdate;
import pamViewFX.pamTask.SimplePamTaskUpdate; import pamViewFX.pamTask.SimplePamTaskUpdate;
import pamguard.GlobalArguments;
import dataMap.OfflineDataMap; import dataMap.OfflineDataMap;
import dataMap.OfflineDataMapPoint; import dataMap.OfflineDataMapPoint;
import binaryFileStorage.BinaryOfflineDataMap; import binaryFileStorage.BinaryOfflineDataMap;
@ -68,10 +69,11 @@ public class DatagramManager {
public ArrayList<PamDataBlock> checkAllDatagrams() { public ArrayList<PamDataBlock> checkAllDatagrams() {
ArrayList<PamDataBlock> grammedDataBlocks = getDataBlocks(); ArrayList<PamDataBlock> grammedDataBlocks = getDataBlocks();
ArrayList<PamDataBlock> updateBlocks = new ArrayList<PamDataBlock>(); ArrayList<PamDataBlock> updateBlocks = new ArrayList<PamDataBlock>();
boolean isBatch = GlobalArguments.getParam("-batch") != null;
/** /**
* Check to see if any of the blocks have an existing datagram * Check to see if any of the blocks have an existing datagram
*/ */
if (datagramSettings.validDatagramSettings == false) { if (datagramSettings.validDatagramSettings == false && isBatch == false) {
/* /*
* this is the first time this has been run, so ask * this is the first time this has been run, so ask
* the user what datagram size they want. * the user what datagram size they want.
@ -169,6 +171,8 @@ public class DatagramManager {
private volatile DatagramProgressDialog datagramProgressDialog; private volatile DatagramProgressDialog datagramProgressDialog;
private volatile DatagramCreator datagramCreator;
/** /**
* update a list of datagrams. This should be done in a * update a list of datagrams. This should be done in a
@ -176,9 +180,17 @@ public class DatagramManager {
* @param updateList * @param updateList
*/ */
public void updateDatagrams(ArrayList<PamDataBlock> updateList) { public void updateDatagrams(ArrayList<PamDataBlock> updateList) {
DatagramCreator datagramCreator = new DatagramCreator(updateList); datagramCreator = new DatagramCreator(updateList);
AWTScheduler.getInstance().scheduleTask(datagramCreator); AWTScheduler.getInstance().scheduleTask(datagramCreator);
} }
/**
* Get true if the datagram worker is running.
* @return
*/
public boolean getStatus() {
return datagramCreator != null;
}
class DatagramCreatorTask extends Task<Integer> { class DatagramCreatorTask extends Task<Integer> {
@ -540,6 +552,7 @@ public class DatagramManager {
PamController.getInstance().notifyTaskProgress( PamController.getInstance().notifyTaskProgress(
new SimplePamTaskUpdate("Finished Datagram Mapping", PamTaskUpdate.STATUS_DONE)); new SimplePamTaskUpdate("Finished Datagram Mapping", PamTaskUpdate.STATUS_DONE));
} }
datagramCreator = null;
} }
@Override @Override

View File

@ -50,6 +50,7 @@ public class DBControlUnit extends DBControl implements DataOutputStore {
private boolean initialisationComplete; private boolean initialisationComplete;
private BackupInformation backupInformation; private BackupInformation backupInformation;
private CreateDataMap createDataMap;
public DBControlUnit(String unitName) { public DBControlUnit(String unitName) {
this(null, unitName); this(null, unitName);
@ -188,8 +189,8 @@ public class DBControlUnit extends DBControl implements DataOutputStore {
pamDataBlocks.get(i).removeOfflineDataMap(THIS); pamDataBlocks.get(i).removeOfflineDataMap(THIS);
updateDataBlocks.add(pamDataBlocks.get(i)); updateDataBlocks.add(pamDataBlocks.get(i));
} }
createDataMap = new CreateDataMap(updateDataBlocks);
AWTScheduler.getInstance().scheduleTask(new CreateDataMap(updateDataBlocks)); AWTScheduler.getInstance().scheduleTask(createDataMap);
} }
@ -258,6 +259,7 @@ public class DBControlUnit extends DBControl implements DataOutputStore {
*/ */
public CreateDataMap(ArrayList<PamDataBlock> loggingBlocks) { public CreateDataMap(ArrayList<PamDataBlock> loggingBlocks) {
super(); super();
createDataMap = this;
this.loggingBlocks = loggingBlocks; this.loggingBlocks = loggingBlocks;
} }
@ -379,6 +381,7 @@ public class DBControlUnit extends DBControl implements DataOutputStore {
PamController.getInstance().notifyTaskProgress(new CreateMapInfo(PamTaskUpdate.STATUS_DONE)); PamController.getInstance().notifyTaskProgress(new CreateMapInfo(PamTaskUpdate.STATUS_DONE));
PamController.getInstance().notifyModelChanged(PamControllerInterface.CHANGED_OFFLINE_DATASTORE); PamController.getInstance().notifyModelChanged(PamControllerInterface.CHANGED_OFFLINE_DATASTORE);
// System.out.println("Create datamap point: DONE2"); // System.out.println("Create datamap point: DONE2");
createDataMap = null;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -513,5 +516,13 @@ public class DBControlUnit extends DBControl implements DataOutputStore {
return getDbProcess().deleteDataFrom(timeMillis); return getDbProcess().deleteDataFrom(timeMillis);
} }
@Override
public int getOfflineState() {
int state = super.getOfflineState();
if (createDataMap != null) {
state = Math.max(state, PamController.PAM_MAPMAKING);
}
return state;
}
} }

View File

@ -13,6 +13,7 @@ import org.w3c.dom.Element;
import PamController.PamControlledUnit; import PamController.PamControlledUnit;
import PamController.PamControlledUnitSettings; import PamController.PamControlledUnitSettings;
import PamController.PamController;
import PamController.PamSettingManager; import PamController.PamSettingManager;
import PamController.PamSettings; import PamController.PamSettings;
import PamView.PamTabPanel; import PamView.PamTabPanel;
@ -298,4 +299,15 @@ public class NoiseControl extends PamControlledUnit implements PamSettings {
public NoiseSettings getNoiseSettings() { public NoiseSettings getNoiseSettings() {
return noiseSettings; return noiseSettings;
} }
@Override
public void notifyModelChanged(int changeType) {
super.notifyModelChanged(changeType);
switch (changeType) {
case PamController.INITIALIZATION_COMPLETE:
noiseProcess.setupProcess();
sortBandEdges();
}
}
} }

View File

@ -789,7 +789,7 @@ private void setAxisLabels() {
double[][] noiseData, lastNoisedata = null; double[][] noiseData, lastNoisedata = null;
int chan; int chan;
int nMeasures = noiseDataBlock.getNumMeasurementBands(); int nMeasures = noiseDataBlock.getNumMeasurementBands();
int x1, x2=0, y1, y2; int x1, x2=0, y1=0, y2;
int xWin = getWidth() / 10; int xWin = getWidth() / 10;
synchronized (noiseDataBlock.getSynchLock()) { synchronized (noiseDataBlock.getSynchLock()) {
noiseIterator = noiseDataBlock.getListIterator(0); noiseIterator = noiseDataBlock.getListIterator(0);
@ -812,15 +812,22 @@ private void setAxisLabels() {
lastNoisedata = lastUnit.getNoiseBandData(); lastNoisedata = lastUnit.getNoiseBandData();
} }
nMeasures = noiseData.length; nMeasures = noiseData.length;
for (int i = 0; i < nMeasures; i++) { for (int i = 0; i < nMeasures; i++) {
if (noiseDisplaySettings.isSelectData(i) == false) { if (noiseDisplaySettings.isSelectData(i) == false) {
continue; continue;
} }
nStats = noiseData[i].length;
for (int m = 0; m < nStats; m++) { for (int m = 0; m < nStats; m++) {
if ((noiseDisplaySettings.selectedStats & noiseDataBlock.statIndexToBit(m)) == 0) { if ((noiseDisplaySettings.selectedStats & noiseDataBlock.statIndexToBit(m)) == 0) {
continue; continue;
} }
try {
y1 = dBToYPix(noiseData[i][m]+bandCorrection[i]); y1 = dBToYPix(noiseData[i][m]+bandCorrection[i]);
}
catch (Exception e) {
e.printStackTrace();
}
setSymbol(symbol, chan, i, m); setSymbol(symbol, chan, i, m);
symbol.draw(g, new Point(x1, y1)); symbol.draw(g, new Point(x1, y1));
if (lastNoisedata != null && lastNoisedata.length > i) { if (lastNoisedata != null && lastNoisedata.length > i) {

View File

@ -123,6 +123,16 @@ public abstract class OfflineTask<T extends PamDataUnit> {
} }
} }
/**
* Get a uniquely identifyng name for the task which consists of the
* pamControlledUnit type and name as well as the tasks shorter name from getName();
* @return a long name which should be unique within a configuration.
*/
public String getLongName() {
PamControlledUnit tcu = getTaskControlledUnit();
String str = String.format("%s:%s:%s", tcu.getUnitType(), tcu.getUnitName(), getName());
return str;
}
/** /**
* *
* @return a name for the task, to be displayed in the dialog. * @return a name for the task, to be displayed in the dialog.

View File

@ -17,6 +17,10 @@ public class OfflineTaskManager {
private ArrayList<OfflineTask> globalTaskList = new ArrayList(); private ArrayList<OfflineTask> globalTaskList = new ArrayList();
public static final String commandFlag = "-offlinetask";
public ArrayList<String> commandLineTasks = new ArrayList();
public static OfflineTaskManager getManager() { public static OfflineTaskManager getManager() {
if (singleInstance == null) { if (singleInstance == null) {
singleInstance = new OfflineTaskManager(); singleInstance = new OfflineTaskManager();
@ -116,8 +120,9 @@ public class OfflineTaskManager {
* @param offlineTask * @param offlineTask
* @return matching task or null. * @return matching task or null.
*/ */
@SuppressWarnings("rawtypes")
public OfflineTask findOfflineTask(OfflineTask offlineTask) { public OfflineTask findOfflineTask(OfflineTask offlineTask) {
return findOfflineTask(offlineTask.getUnitType(), offlineTask.getUnitName(), offlineTask.getName()); return findOfflineTask(offlineTask.getLongName());
} }
/** /**
@ -128,6 +133,7 @@ public class OfflineTaskManager {
* @param taskName * @param taskName
* @return matching task or null. * @return matching task or null.
*/ */
@SuppressWarnings("rawtypes")
public OfflineTask findOfflineTask(String unitType, String unitName, String taskName) { public OfflineTask findOfflineTask(String unitType, String unitName, String taskName) {
// could possibly also do a check on class type ???? // could possibly also do a check on class type ????
for (OfflineTask aTask : globalTaskList) { for (OfflineTask aTask : globalTaskList) {
@ -143,4 +149,51 @@ public class OfflineTaskManager {
} }
return null; return null;
} }
/**
* Another way of finding offline tasks based on their long name. This is basically
* the three names unitType, unitName and taskName concatenated together. Get's used
* for some task management such as passing batch processing instructions.
* @param taskLongName
* @return matching task or null.
*/
@SuppressWarnings("rawtypes")
public OfflineTask findOfflineTask(String taskLongName) {
for (OfflineTask aTask : globalTaskList) {
if (aTask.getLongName().equals(taskLongName)) {
return aTask;
}
}
return null;
}
/**
* Add a task listed in the command line when PAMGuard was started.
* @param taskLongName
*/
public void addCommandLineTask(String taskLongName) {
commandLineTasks.add(taskLongName);
}
/**
* The list of tasks from the command line.
* @return the commandLineTasks
*/
public ArrayList<String> getCommandLineTasks() {
return commandLineTasks;
}
/**
* Get the status of jobs to pass back to the batch process controller.
* @return
*/
public String getBatchStatus() {
/**
* this needs to largely follow the format of the data in folderinputsystem:
* String bs = String.format("%d,%d,%d,%s", nFiles,currentFile,generalStatus,currFile);
*/
int generalStatus = PamController.getInstance().getRealStatus();
String bs = String.format("%d,%d,%d,%s", commandLineTasks.size(), 0, generalStatus, "Processing");
return bs;
}
} }

View File

@ -9,6 +9,11 @@ import java.util.HashMap;
* *
*/ */
public class GlobalArguments { public class GlobalArguments {
/**
* Put some common flags here for convenience.
*/
public static final String BATCHFLAG = "-batch";
static HashMap<String, String> globalFlags = new HashMap<>(); static HashMap<String, String> globalFlags = new HashMap<>();
@ -43,4 +48,12 @@ public class GlobalArguments {
return Integer.valueOf(val); return Integer.valueOf(val);
} }
/**
* Is the batch flag set ?
* @return
*/
public static boolean isBatch() {
return getParam(BATCHFLAG) != null;
}
} }

View File

@ -44,6 +44,7 @@ import binaryFileStorage.BinaryStore;
import dataPlotsFX.JamieDev; import dataPlotsFX.JamieDev;
import generalDatabase.DBControl; import generalDatabase.DBControl;
import networkTransfer.send.NetworkSender; import networkTransfer.send.NetworkSender;
import offlineProcessing.OfflineTaskManager;
import rocca.RoccaDev; import rocca.RoccaDev;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -176,6 +177,11 @@ public class Pamguard {
else if (anArg.equalsIgnoreCase("-nosplash")) { else if (anArg.equalsIgnoreCase("-nosplash")) {
showSplash = false; showSplash = false;
} }
else if (anArg.equalsIgnoreCase(GlobalArguments.BATCHFLAG)) {
// flag to say we're in batch processing mode. Can be used
// to avoid one or two dialogs that pop up in Viewer mode.
GlobalArguments.setParam(GlobalArguments.BATCHFLAG, Boolean.TRUE.toString());
}
// removed SEICHE switch when the two SEICHE modules were converted to plugins // removed SEICHE switch when the two SEICHE modules were converted to plugins
// else if (anArg.equalsIgnoreCase("-seiche")) { // else if (anArg.equalsIgnoreCase("-seiche")) {
@ -244,6 +250,10 @@ public class Pamguard {
pamBuoyGlobals.setMultiportConfig(mAddr, mPort); pamBuoyGlobals.setMultiportConfig(mAddr, mPort);
System.out.printf("Setting multicast control addr %s port %d\n", mAddr, mPort); System.out.printf("Setting multicast control addr %s port %d\n", mAddr, mPort);
} }
else if (anArg.equalsIgnoreCase(OfflineTaskManager.commandFlag)) {
String taskName = args[iArg++];
OfflineTaskManager.getManager().addCommandLineTask(taskName);
}
else if (anArg.equalsIgnoreCase("-nolog")) { else if (anArg.equalsIgnoreCase("-nolog")) {
System.out.println("Disabling log file from command line switch..."); System.out.println("Disabling log file from command line switch...");
ProxyPrintStream.disableLogFile(); ProxyPrintStream.disableLogFile();