Merge pull request #70 from PAMGuard/main

Merge from main
This commit is contained in:
Douglas Gillespie 2024-03-12 11:20:33 +00:00 committed by GitHub
commit 2017b0b965
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 412 additions and 82 deletions

View File

@ -878,6 +878,7 @@ public class AcquisitionControl extends RawInputControlledUnit implements PamSet
public InputStoreInfo getStoreInfo(boolean detail) {
return getDaqProcess().getStoreInfo(detail);
}
@Override
public boolean setAnalysisStartTime(long startTime) {
return getDaqProcess().setAnalysisStartTime(startTime);

View File

@ -65,7 +65,7 @@ import pamScrollSystem.ViewLoadObserver;
* @see PamguardMVC.PamDataUnit
*
*/
public class AcquisitionProcess extends PamProcess implements DataInputStore {
public class AcquisitionProcess extends PamProcess {
public static final int LASTDATA = 2; // don't use zero since need to see if no notification has been received.
@ -211,10 +211,10 @@ public class AcquisitionProcess extends PamProcess implements DataInputStore {
if (systemPrepared == false) return;
newDataQueue.clearList(); // clear this first to make sure nothing new comes in.
// before starting, clear all old data
rawDataBlock.clearAll();
newDataQueue.clearList();
sampleRateErrorFilter.prepareFilter();
totalExtraSamples = 0;
@ -302,6 +302,7 @@ public class AcquisitionProcess extends PamProcess implements DataInputStore {
// called by PamController.
// stop the running system - not the selected system since
// this may have changed
restartTimer.stop();
// stallCheckTimer.stop();
pamStop("");
@ -471,6 +472,9 @@ public class AcquisitionProcess extends PamProcess implements DataInputStore {
* have been emptied and processing has stopped
*/
protected void pamHasStopped() {
newDataQueue.clearList(); // clear this first to make sure nothing new comes in.
if (runningSystem == null){
runningSystem = acquisitionControl.findDaqSystem(null);
}
@ -650,9 +654,10 @@ public class AcquisitionProcess extends PamProcess implements DataInputStore {
restartTimer.stop();
PamController.getInstance().pamStop();
PamController.getInstance().pamStart(false);
PamController.getInstance().restartPamguard();
// PamController.getInstance().pamStop();
//
// PamController.getInstance().pamStart(false);
}
@ -1235,7 +1240,6 @@ public class AcquisitionProcess extends PamProcess implements DataInputStore {
return daqStatusDataBlock;
}
@Override
public InputStoreInfo getStoreInfo(boolean detail) {
if (runningSystem instanceof DataInputStore) {
return ((DataInputStore) runningSystem).getStoreInfo(detail);
@ -1245,7 +1249,6 @@ public class AcquisitionProcess extends PamProcess implements DataInputStore {
}
}
@Override
public boolean setAnalysisStartTime(long startTime) {
if (runningSystem instanceof DataInputStore) {
return ((DataInputStore) runningSystem).setAnalysisStartTime(startTime);

View File

@ -404,7 +404,7 @@ public class MapRectProjector extends MapProjector {
private String findGpsTrackText(Point mousePoint, int ploNumberMatch) {
GPSControl gpsControl = GPSControl.getGpsControl();
if (gpsControl == null) {
if (gpsControl == null || mousePoint == null) {
return null;
}
LatLong currentPos = getDataPosition(new Coordinate3d(mousePoint.x, mousePoint.y));

View File

@ -28,4 +28,11 @@ public interface DataInputStore {
*/
public boolean setAnalysisStartTime(long startTime);
/**
* Very specific command handler for batch status which will only work
* with the acquisition folderinputSystem or the tritech file processing.
* @return
*/
public String getBatchStatus();
}

View File

@ -128,6 +128,10 @@ public class PamController implements PamControllerInterface, PamSettings {
public static final int PAM_COMPLETE = 6;
public static final int PAM_MAPMAKING = 7;
public static final int PAM_OFFLINETASK = 8;
public static final int BUTTON_START = 1;
public static final int BUTTON_STOP = 2;
private volatile int lastStartStopButton = 0;
// status' for RunMode = RUN_PAMVIEW
public static final int PAM_LOADINGDATA = 2;
@ -161,7 +165,7 @@ public class PamController implements PamControllerInterface, PamSettings {
/**
* The current PAM status
*/
private transient int pamStatus = PAM_IDLE;
private volatile int pamStatus = PAM_IDLE;
/**
* PamGuard view params.
@ -191,6 +195,8 @@ public class PamController implements PamControllerInterface, PamSettings {
private static PamController uniqueController;
private Timer diagnosticTimer;
private boolean debugDumpBufferAtRestart = false;
private NetworkController networkController;
private int nNetPrepared;
@ -240,6 +246,9 @@ public class PamController implements PamControllerInterface, PamSettings {
private Thread statusCheckThread;
private WaitDetectorThread detectorEndThread;
private boolean firstDataLoadComplete;
// keep a track of the total number of times PAMGuard is started for debug purposes.
private int nStarts;
private RestartRunnable restartRunnable;
private PamController(int runMode, Object object) {
@ -1045,8 +1054,45 @@ public class PamController implements PamControllerInterface, PamSettings {
*/
public void restartPamguard() {
pamStop();
startLater();
/*
* launch a restart thread, that won't do ANYTHING until
* PAMGuard is really idle and buffers are cleared. Can only
* have one of these at a time !
*/
if (restartRunnable != null) {
System.out.println("Warning !!!! PAMGuard is already trying to restart!");
return;
}
restartRunnable = new RestartRunnable();
Thread restartThread = new Thread(restartRunnable, "RestartPAMGuard Thread");
restartThread.run();
}
private class RestartRunnable implements Runnable {
@Override
public void run() {
long t1 = System.currentTimeMillis();
while (getPamStatus() != PAM_IDLE) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
long t2 = System.currentTimeMillis();
restartRunnable = null;
System.out.printf("PAMGuard safe to restart after %d milliseconds\n", t2-t1);
startLater(false);
}
}
/**
* calls pamStart using the SwingUtilities
* invokeLater command to start PAMGAURD
@ -1078,7 +1124,13 @@ public class PamController implements PamControllerInterface, PamSettings {
@Override
public void run() {
pamStart(saveSettings);
/*
* do a final check that the stop button hasn't been pressed - can arrive a bit
* late if the system was continually restarting.
*/
if (lastStartStopButton != BUTTON_STOP) {
pamStart(saveSettings);
}
}
}
@ -1103,6 +1155,26 @@ public class PamController implements PamControllerInterface, PamSettings {
}
}
/**
* Called from the start button. A little book keeping
* to distinguish this from automatic starts / restarts
* @return true if started.
*/
@Override
public boolean manualStart() {
lastStartStopButton = BUTTON_START;
return pamStart();
}
/**
* Called from the stop button. A little book keeping
* to distinguish this from automatic starts / restarts
*/
@Override
public void manualStop() {
lastStartStopButton = BUTTON_STOP;
pamStop();
}
/**
* Start PAMGUARD. This function also gets called from the
@ -1193,6 +1265,12 @@ public class PamController implements PamControllerInterface, PamSettings {
saveSettings(PamCalendar.getSessionStartTime());
}
if (++nStarts > 1 && debugDumpBufferAtRestart) {
// do this here - all processses should have reset buffers to start again by now.
String msg = String.format("Starting PAMGuard go %d", nStarts);
dumpBufferStatus(msg, false);
}
StorageOptions.getInstance().setBlockOptions();
t1 = System.currentTimeMillis();
@ -1254,6 +1332,7 @@ public class PamController implements PamControllerInterface, PamSettings {
}
}
dumpBufferStatus("In stopping", false);
/*
* now launch another thread to wait for everything to have stopped, but
* leave this function so that AWT is released and graphics can update, the
@ -1281,9 +1360,11 @@ public class PamController implements PamControllerInterface, PamSettings {
long t2 = System.currentTimeMillis();
if (t2 - t1 > 5000) {
System.out.printf("Stopping, but stuck in loop for CheckRunStatus for %3.1fs\n", (double) (t2-t1)/1000.);
dumpBufferStatus("Stopping stuck in loop", false);
break; // crap out anyway.
}
try {
Thread.sleep(10);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
@ -1294,19 +1375,43 @@ public class PamController implements PamControllerInterface, PamSettings {
}
/**
* Look in every data block, particularly threaded ones, and dump
* the buffer status. This will have to go via PamProcess so that
* additional information can be added from any processes that
* hold additional data in other internal buffers.
* @param message Message to print prior to dumping buffers for debug.
* @param sayEmpties dump info even if a buffer is empty (otherwise, only ones that have stuff still)
*/
public void dumpBufferStatus(String message, boolean sayEmpties) {
if (debugDumpBufferAtRestart == false) return;
System.out.println("**** Dumping process buffer status: " + message);
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
for (PamControlledUnit aUnit : pamControlledUnits) {
int numProcesses = aUnit.getNumPamProcesses();
for (int i=0; i<numProcesses; i++) {
PamProcess aProcess = aUnit.getPamProcess(i);
aProcess.dumpBufferStatus(message, sayEmpties);
}
}
System.out.println("**** End of process buffer dump: " + message);
}
/**
* Called once the detectors have actually stopped and puts a few finalising
* functions into the AWT thread.
*/
private void finishStopping() {
detectorEndThread = null;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// this was never getting invoked for some reason.
// SwingUtilities.invokeLater(new Runnable() {
//
// @Override
// public void run() {
pamStopped();
}
});
// }
// });
}
@ -1320,6 +1425,8 @@ public class PamController implements PamControllerInterface, PamSettings {
* it is necessary to make sure that all internal datablock
* buffers have had time to empty.
*/
System.out.println("Arrived in PamStopped() in thread " + Thread.currentThread().toString());
ArrayList<PamControlledUnit> pamControlledUnits = pamConfiguration.getPamControlledUnits();
if (PamModel.getPamModel().isMultiThread()) {
@ -1327,7 +1434,7 @@ public class PamController implements PamControllerInterface, PamSettings {
pamControlledUnits.get(iU).flushDataBlockBuffers(2000);
}
}
setPamStatus(PAM_IDLE);
dumpBufferStatus("In pamStopped, now idle", true);
// wait here until the status has changed to Pam_Idle, so that we know
// that we've really finished processing all data
@ -1350,6 +1457,8 @@ public class PamController implements PamControllerInterface, PamSettings {
long stopTime = PamCalendar.getTimeInMillis();
saveEndSettings(stopTime);
setPamStatus(PAM_IDLE);
// no good having this here since it get's called at the end of every file.
// if (GlobalArguments.getParam(PamController.AUTOEXIT) != null) {
@ -1960,7 +2069,10 @@ public class PamController implements PamControllerInterface, PamSettings {
/*
* 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 (debugDumpBufferAtRestart) {
System.out.printf("******* PamController.setPamStatus to %d, real status is %d set in thread %s\n",
pamStatus, getRealStatus(), Thread.currentThread().toString());
}
if (getRunMode() != RUN_PAMVIEW) {
TopToolBar.enableStartButton(pamStatus == PAM_IDLE);
TopToolBar.enableStopButton(pamStatus == PAM_RUNNING);
@ -2054,6 +2166,7 @@ public class PamController implements PamControllerInterface, PamSettings {
statusWarning.setWarningMessage(warningMessage);
statusWarning.setWarnignLevel(1);
warningSystem.addWarning(statusWarning);
// System.out.println(warningMessage);
}
}

View File

@ -458,6 +458,17 @@ public interface PamControllerInterface {
* Close all modules and free up resources.
*/
public void pamClose();
/**
* Start function called from button to do a bit of extra book keeping
* @return
*/
public boolean manualStart();
/**
* Stop function called from button to do a bit of extra book keeping
*/
public void manualStop();
//public void controllerAddFileMenuItem();

View File

@ -16,7 +16,7 @@ public class PamguardVersionInfo {
* @return release type
*/
static public ReleaseType getReleaseType() {
return ReleaseType.CORE;
return ReleaseType.OTHER;
}
/**
@ -36,7 +36,7 @@ public class PamguardVersionInfo {
/**
* Release date
*/
static public final String date = "30 January 2024";
static public final String date = "2 March 2024";
// /**
// * Release type - Beta or Core

View File

@ -1,6 +1,10 @@
package PamController.command;
import java.util.ArrayList;
import Acquisition.AcquisitionControl;
import PamController.DataInputStore;
import PamController.PamControlledUnit;
import PamController.PamController;
import offlineProcessing.OfflineTaskManager;
import pamViewFX.PamControlledGUIFX;
@ -35,7 +39,16 @@ public class BatchStatusCommand extends ExtCommand {
}
private String getNormalModeStatus(String command) {
AcquisitionControl daqControl = (AcquisitionControl) PamController.getInstance().findControlledUnit(AcquisitionControl.class, null);
/**
* find a controlled unit thats a DataInputSource which should either be a sound daq or a Tritech daq module.
*/
ArrayList<PamControlledUnit> inputSources = PamController.getInstance().findControlledUnits(DataInputStore.class, true);
if (inputSources.size() == 0) {
return null;
}
// DataInputStore daqControl = (DataInputStore) PamController.getInstance().findControlledUnit(DataInputStore.class, null);
DataInputStore daqControl = (DataInputStore) inputSources.get(0);
// System.out.println("Getting batch status from : " + daqControl);
if (daqControl == null) {
return null;
}

View File

@ -23,6 +23,7 @@ package PamModel;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
@ -1212,13 +1213,15 @@ final public class PamModel implements PamSettings {
if (intf[j].getName().equals("PamModel.PamPluginInterface")) {
// create an instance of the interface class.
PamPluginInterface pf = (PamPluginInterface) c.newInstance();
Constructor constructor = c.getDeclaredConstructor(null);
PamPluginInterface pf = (PamPluginInterface) constructor.newInstance(null);
if (getPluginBeingLoaded()==null) {
continue;
}
// Let the user know which valid plugins have been found
System.out.println(" Creating instance of " + pf.getDefaultName() + ": " + pf.getClassName());
System.out.printf(" Loading plugin interface for %s : %s version %s\n",
pf.getDefaultName(), pf.getClassName(), pf.getVersion());
if (getPluginBeingLoaded()==null) {
continue;
}
@ -1234,7 +1237,7 @@ final public class PamModel implements PamSettings {
pluginList.add(pf); // add it to the list
} else {
System.out.println(" Error: "+pf.getDefaultName()+" cannot run in this mode. Skipping module.");
System.out.println(" Error: " + pf.getDefaultName()+" cannot run in this mode. Skipping module.");
}
if (getPluginBeingLoaded()==null) {
continue;
@ -1243,12 +1246,16 @@ final public class PamModel implements PamSettings {
// now check for interfaces that implement DaqSystemInterface
if (intf[j].getName().equals("Acquisition.DaqSystemInterface")) {
DaqSystemInterface pf = (DaqSystemInterface) c.newInstance(); // create an instance of the interface class
Constructor constructor = c.getDeclaredConstructor(null);
DaqSystemInterface pf = (DaqSystemInterface) constructor.newInstance(null);
// DaqSystemInterface pf = (DaqSystemInterface) c.newInstance(); // create an instance of the interface class
if (getPluginBeingLoaded()==null) {
continue;
}
System.out.println(" Creating instance of " + pf.getDefaultName() + ": " + className);
System.out.printf(" Loading daq plugin interface for %s version %s\n",
pf.getDefaultName(), pf.getVersion());
// System.out.println(" Creating instance of " + pf.getDefaultName() + ": " + className);
if (getPluginBeingLoaded()==null) {
continue;
}

View File

@ -60,17 +60,19 @@ public class FileList {
// System.out.println("Adding files from folder " + folder.getAbsolutePath());
// first go through all the files in this folder
File[] newFiles = folder.listFiles(fileFilter);
if (newFiles == null) {
return fileList; // nothing to do here.
}
for (int i = 0; i < newFiles.length; i++) {
if (!newFiles[i].isDirectory()) {
fileList.add(newFiles[i]);
// System.out.println(" adding file " + newFiles[i].getName());
// System.out.println(" adding file " + newFiles[i].getName());
}
else if (includeSubFolders) {
fileList = addFiles(newFiles[i], fileList, fileFilter, includeSubFolders);
}
}
return fileList;
}
}

View File

@ -1268,7 +1268,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
class menuPamStart implements ActionListener {
public void actionPerformed(ActionEvent ev){
pamControllerInterface.pamStart();
pamControllerInterface.manualStart();
}
}
@ -1285,7 +1285,7 @@ public class PamGui extends PamView implements WindowListener, PamSettings {
class menuPamStop implements ActionListener {
public void actionPerformed(ActionEvent ev){
pamControllerInterface.pamStop();
pamControllerInterface.manualStop();
// enableLoggingMenu();
}
}

View File

@ -2164,7 +2164,7 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
*/
@Override
public String toString() {
return getDataName();
return getLongDataName();
}
/**
@ -4286,4 +4286,23 @@ public class PamDataBlock<Tunit extends PamDataUnit> extends PamObservable {
inputEl.setAttribute("Channels", String.format("0x%X", getChannelMap()));
return inputEl;
}
/**
* Look in every data block, particularly threaded ones, and dump
* the buffer status. This will have to go via PamProcess so that
* additional information can be added from any processes that
* hold additional data in other internal buffers.
* @param message Message to print prior to dumping buffers for debug.
* @param sayEmpties dump info even if a buffer is empty (otherwise, only ones that have stuff still)
*/
public void dumpBufferStatus(String message, boolean sayEmpties) {
int nObs = countObservers();
for (int i = 0; i < nObs; i++) {
PamObserver obs = getPamObserver(i);
if (obs instanceof ThreadedObserver) {
ThreadedObserver tObs = (ThreadedObserver) obs;
tObs.dumpBufferStatus(message, sayEmpties);
}
}
}
}

View File

@ -208,6 +208,14 @@ public class PamObservable {//extends PanelOverlayDraw {
if (System.currentTimeMillis() - startTime > timeOutms) {
// have taken too long, so return that we've failed.
System.out.println("Wait timeout in threaded observer");
// and clear everything that's left.
for (int i = 0; i < pamObservers.size(); i++) {
pamObserver = pamObservers.get(i);
if (pamObserver.getClass() == ThreadedObserver.class) {
threadedObserver = (ThreadedObserver) pamObserver;
threadedObserver.clearEverything();
}
}
return false;
}
try {

View File

@ -767,7 +767,7 @@ abstract public class PamProcess implements PamObserver, ProcessAnnotator {
}
});
private int lastSourceNotificationType;
private volatile int lastSourceNotificationType;
private Object lastSourceNotificationObject;
@ -1065,4 +1065,24 @@ abstract public class PamProcess implements PamObserver, ProcessAnnotator {
return lastSourceNotificationObject;
}
/**
* Say the status of any buffers, particularly in output buffers of
* data blocks, but can add bespoke info for other internal buffers
* for some processes.
* @param message
* @param sayEmpties include info even if a buffer is empty.
*/
public void dumpBufferStatus(String message, boolean sayEmpties) {
ArrayList<PamDataBlock> outputs = getOutputDataBlocks();
try {
for (PamDataBlock output : outputs) {
output.dumpBufferStatus(message, sayEmpties);
}
}
catch (Exception e) {
System.err.println("Error dumping buffer data from process " + getProcessName());
e.printStackTrace();
}
}
}

View File

@ -145,6 +145,17 @@ public class PamRawDataBlock extends AcousticDataBlock<RawDataUnit> {
}
}
/**
* Reset data integrity checking counters.
*/
public void reset() {
prevChannelSample = new long[PamConstants.MAX_CHANNELS];
summaryTotals = new double[PamConstants.MAX_CHANNELS];
summaryTotals2 = new double[PamConstants.MAX_CHANNELS];
summaryMaxVal = new double[PamConstants.MAX_CHANNELS];
summaryCount = new int[PamConstants.MAX_CHANNELS];
}
@Override
public void addPamData(RawDataUnit pamDataUnit) {
/*

View File

@ -444,6 +444,7 @@ public class ThreadedObserver implements PamObserver {
else {
emptyRead = false;
int lc=0;
ObservedObject observedObject;
while (!toDoList.isEmpty()) {
// if (stopFlag) {
@ -458,11 +459,21 @@ public class ThreadedObserver implements PamObserver {
// get the first object, send it for processing and then remove from the list
ObservedObject observedObject = toDoList.get(0);
performAction(observedObject);
synchronized(synchLock) {
toDoList.remove(0);
if (toDoList.size() > 0) {
observedObject = toDoList.remove(0);
}
else {
break;
}
}
// need to do this bit outside of the synch block.
performAction(observedObject);
// synchronized(synchLock) {
// if (toDoList.size() > 0) { // list may have been cleared during a shut down.
// toDoList.remove(0);
// }
// }
}
}
}
@ -525,4 +536,21 @@ public class ThreadedObserver implements PamObserver {
}
}
public void clearEverything() {
synchronized (synchLock) {
System.out.printf("Clearing %d objects from todo list in %s\n", toDoList.size(), singleThreadObserver.getObserverName());
toDoList.clear();
}
}
public void dumpBufferStatus(String message, boolean sayEmpties) {
int n = toDoList.size();
if (sayEmpties == false && n == 0) {
return;
}
String name = singleThreadObserver.getObserverName();
System.out.printf("Threaded observer %s has %d objects in queue\n", name, n);
}
}

View File

@ -49,7 +49,7 @@ public class BinaryOutputStream {
private DataOutputStream noiseOutputStream;
private int storedObjects;
private int storedObjects, storedNoiseCount;
private String mainFileName, indexFileName;
@ -219,6 +219,7 @@ public class BinaryOutputStream {
else {
noiseOutputStream = null;
}
storedNoiseCount = 0;
return true;
}
@ -450,6 +451,7 @@ public class BinaryOutputStream {
footer.setHighestUID(parentDataBlock.getUidHandler().getCurrentUID());
boolean ok = footer.writeFooter(dataOutputStream, BinaryStore.getCurrentFileFormat());
if (noiseOutputStream != null) {
// footer.setnObjects(storedNoiseCount);
ok &= footer.writeFooter(noiseOutputStream, BinaryStore.getCurrentFileFormat());
}
lastObjectType = BinaryTypes.FILE_FOOTER;
@ -487,12 +489,20 @@ public class BinaryOutputStream {
// }
public synchronized boolean storeData(int objectId, DataUnitBaseData baseData, BinaryObjectData binaryObjectData) {
boolean ok;
if (objectId == BinaryTypes.BACKGROUND_DATA & noiseOutputStream != null) {
return storeData(noiseOutputStream, objectId, baseData, binaryObjectData);
ok = storeData(noiseOutputStream, objectId, baseData, binaryObjectData);
if (ok) {
storedNoiseCount++;
}
}
else {
return storeData(dataOutputStream, objectId, baseData, binaryObjectData);
ok = storeData(dataOutputStream, objectId, baseData, binaryObjectData);
if (ok) {
storedObjects++;
}
}
return ok;
}
/**
* Writes data to a file. Note that the length of data may be greater than
@ -564,7 +574,6 @@ public class BinaryOutputStream {
return false;
}
storedObjects++;
return true;

View File

@ -45,6 +45,7 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
public static final String MHT_NAME = "MHT detector";
/**
* Reference to the click train control.
*/
@ -354,6 +355,7 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
TrackBitSet trackBitSet;
TrackDataUnits trackUnits;
if (nTracks>0) Debug.out.println("-------------------Grab Done Trains---------------");
try {
for (int i =0; i<nTracks; i++) {
trackBitSet=mhtKernal.getConfirmedTrack(i);
Debug.out.println("MHTAlgorithm: Confirmed Track Grab: No. " + MHTKernel.getTrueBitCount(trackBitSet.trackBitSet) + " flag: " + trackBitSet.flag + " chi2: " +trackBitSet.chi2Track.getChi2());
@ -379,6 +381,10 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
trackCount++;
saveClickTrain(trackUnits, trackBitSet.chi2Track.getMHTChi2Info());
}
}
catch (Exception e) {
System.out.printf("Handled MHTClickTrainAlgorithm Exception %s in grabDoneTrains: %s\n", e.getClass().getSimpleName(), e.getMessage());
}
if (nTracks>0) Debug.out.println("-------------------------------------------------");
@ -415,12 +421,19 @@ public class MHTClickTrainAlgorithm implements ClickTrainAlgorithm, PamSettings
return mhtGUI;
}
Thread previousThread = null;
/**
* Update the algorithm
* @param flag- flag indicating the update type.
*/
public void update(int flag, Object info) {
public synchronized void update(int flag, Object info) {
if (Thread.currentThread() != previousThread) {
// see flag id constants in ClickTrianControl
System.out.printf("Thread change to %s in MHTClicktrainAlgorithm.update flag %d, object %s\n",
Thread.currentThread().toString(), flag, info);
previousThread = Thread.currentThread();
}
switch (flag) {
case ClickTrainControl.PROCESSING_START:
//make sure the kernel is cleared before processing

View File

@ -3,6 +3,7 @@ package clickTrainDetector.clickTrainAlgorithms.mht;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
import PamUtils.PamArrayUtils;
import PamguardMVC.debug.Debug;
@ -285,28 +286,39 @@ public class MHTKernel<T> {
BitSet currentBitSet;
MHTChi2<T> mhtChi2;
int index;
for (int i=0; i<possibleTracks.size(); i++) {
synchronized(trackSynchronisation) {
try {
for (int i=0; i<possibleTracks.size(); i++) {
currentBitSet=possibleTracks.get(i).trackBitSet;
currentBitSet=possibleTracks.get(i).trackBitSet;
//index is the total detection count-1;
index=kcount-1;
//index is the total detection count-1;
index=kcount-1;
//now add both a true and false for the data unit to be in this possibility.
currentBitSet.set(index, true);
mhtChi2=possibleTracks.get(i).chi2Track.cloneMHTChi2();
//now add both a true and false for the data unit to be in this possibility.
currentBitSet.set(index, true);
mhtChi2=possibleTracks.get(i).chi2Track.cloneMHTChi2();
newPossibilities.add(new TrackBitSet(currentBitSet, mhtChi2));
newPossibilities.add(new TrackBitSet(currentBitSet, mhtChi2));
//add a coast to the possibility
currentBitSet=(BitSet) currentBitSet.clone();
currentBitSet.set(index, false);
//currentBitSet.set(currentBitSet.size(), true);
//add new chi2 value - need to clone this time.
mhtChi2=possibleTracks.get(i).chi2Track.cloneMHTChi2();
//add a coast to the possibility
currentBitSet=(BitSet) currentBitSet.clone();
currentBitSet.set(index, false);
//currentBitSet.set(currentBitSet.size(), true);
//add new chi2 value - need to clone this time.
/*
* This line can throw an error due to poor sunchronisation if
* the list is emptied from a different thread.
*/
mhtChi2=possibleTracks.get(i).chi2Track.cloneMHTChi2();
//added the cloned bitset to not mess up references
newPossibilities.add(new TrackBitSet(currentBitSet, mhtChi2));
//added the cloned bitset to not mess up references
newPossibilities.add(new TrackBitSet(currentBitSet, mhtChi2));
}
}
catch (Exception e) {
System.out.printf("******* MHTKernel Exception %s in growProbMatrix: %s\n", e.getClass().getSimpleName(), e.getMessage());
}
}
}
@ -342,10 +354,21 @@ public class MHTKernel<T> {
//first sort the tracks by increasing chi2 values.
//sort the possible tracks by chi2 values
//now sort the chi2 values so they correspond to the track list.
Collections.sort(newPossibleTracks, (left, right)->{
//Note- this is definitely in the correct order
return Double.compare(left.chi2Track.getChi2(), right.chi2Track.getChi2());
});
// Collections.sort(newPossibleTracks, (left, right)->{
// //Note- this is definitely in the correct order
// return Double.compare(left.chi2Track.getChi2(), right.chi2Track.getChi2());
// });
try {
Collections.sort(newPossibleTracks, new Comparator<TrackBitSet>() {
@Override
public int compare(TrackBitSet left, TrackBitSet right) {
return Double.compare(left.chi2Track.getChi2(), right.chi2Track.getChi2());
}
});
}
catch (Exception e) {
System.out.printf("Handled MHTKernel Exception %s in pruneProbMatrix: %s\n", e.getClass().getSimpleName(), e.getMessage());
}
// for (int i=0; i<newPossibleTracks.size(); i++) {
// System.out.print("Possibility chi2: " + i + " " + String.format("%.3f", newPossibleTracks.get(i).chi2Track.getChi2()));

View File

@ -38,8 +38,10 @@ public class DecimatorProcessW extends PamProcess {
@Override
public void pamStart() {
// TODO Auto-generated method stub
outputDataBlock.reset();
if (decimatorWorker != null) {
decimatorWorker.reset();
}
}
@Override

View File

@ -77,6 +77,13 @@ public class DecimatorWorker {
createFilters();
}
/**
* Reset all counters and output buffers.
*/
public void reset() {
createFilters();
}
/**
* Make the decimator filters. If reducing frequency, then the filter
* is applied before decimation (obviously!) so is set up based on the

View File

@ -124,6 +124,7 @@ public class PamFFTProcess extends PamProcess {
public synchronized void setupFFT() {
System.out.println("In call to setupFFT in " + getProcessName());
// need to find the existing source data block and remove from observing it.
// then find the new one and subscribe to that instead.
channelCounts = new int[PamConstants.MAX_CHANNELS];
@ -390,28 +391,32 @@ public class PamFFTProcess extends PamProcess {
}
}
}
TempOutputStore[] oldStores = tempStores;
if (iChan == PamUtils.getHighestChannel(fftParameters.channelMap)) {
// time to empty the stores - assume they all have the same
// amount of data
int[] chanList = PamUtils.getChannelArray(fftParameters.channelMap);
try {
int n = tempStores[iChan].getN();
for (int iF = 0; iF < n; iF++) {
for (int iC = 0; iC < chanList.length; iC++) {
// pu = tempStores[chanList[iC]].get(iF);
try {
outputData.addPamData(tempStores[chanList[iC]].get(iF));
int n = tempStores[iChan].getN();
for (int iF = 0; iF < n; iF++) {
for (int iC = 0; iC < chanList.length; iC++) {
// pu = tempStores[chanList[iC]].get(iF);
try {
outputData.addPamData(tempStores[chanList[iC]].get(iF));
}
catch (ArrayIndexOutOfBoundsException e) {
// e.printStackTrace();
System.err.printf("%s.newData: %s Store %s (was %s) iC: %d of %d iF: %d of %d\n",
this.getPamControlledUnit().getUnitName(), e.getMessage(),
tempStores[chanList[iC]], oldStores[chanList[iC]],
iC, chanList.length, iF, n);
}
// outputData.addPamData(null);
}
catch (ArrayIndexOutOfBoundsException e) {
// e.printStackTrace();
System.err.println("PAMFFTProcess.newData: " + e.getMessage() + " " + this.getPamControlledUnit().getUnitName() + " iC: " + iC + " iF: " + iF);
}
// outputData.addPamData(null);
}
}
for (int iC = 0; iC < chanList.length; iC++) {
tempStores[chanList[iC]].clearStore();
}
for (int iC = 0; iC < chanList.length; iC++) {
tempStores[chanList[iC]].clearStore();
}
}
catch (Exception e) {
e.printStackTrace();
@ -539,6 +544,25 @@ public class PamFFTProcess extends PamProcess {
return new ArrayList<Class<? extends PamDataUnit>>(Arrays.asList(RawDataUnit.class));
}
@Override
public synchronized void dumpBufferStatus(String message, boolean sayEmpties) {
super.dumpBufferStatus(message, sayEmpties);
int nTemp = 0;
if (tempStores != null) {
nTemp = tempStores.length;
}
for (int i = 0; i < nTemp; i++) {
if (tempStores[i] == null) {
continue;
}
int n = tempStores[i].tempUnits.size();
if (n > 0 || sayEmpties) {
System.out.printf("FFT %s temp store %d has %d datas\n", getProcessName(), i, n);
}
}
}
// @Override
// public boolean requestOfflineData(PamDataBlock dataBlock, long startMillis,
// long endMillis) {

View File

@ -1,5 +1,6 @@
package pamScrollSystem;
import PamUtils.PamCalendar;
import PamguardMVC.PamDataBlock;
/**
@ -68,6 +69,14 @@ public class DataLoadQueData {
public void setDataEnd(long dataEnd) {
this.dataEnd = dataEnd;
}
@Override
public String toString() {
String str = String.format("%s %s - %s", pamDataBlock.getLongDataName(),
PamCalendar.formatDBDateTime(dataStart),PamCalendar.formatDBDateTime(dataEnd));
return str;
}
}