Big merge from doug (#139)

* binary store count

Fix issue in binary store object count

* update V10aa/other for testing

* update V10aa/other for testing

* reenable buffer dumping

* update V to 10ac for testing

* Additional diagnostics

Additional output of CPU usage for each module when stopping

* V 2.02.10ad for testing

Fixed issue of finding correct raw data block

* Tidying

Lots of GUI improvement and code tidying. Functionality to export
gzipped documents to reduce traffic.

* V 2.02.10ba for user testing

* Tidy up click selector

Improve layout and tips on dialog and improve logic for manual and
automatic event types.

* Menu tide up

* Update nilus maven for PAMGuard

* Fix reprocess choices

Make sure the choice to continue anyway is always present.

* Improve start of binary file timing

Code to better get binary files to start right on the hour when processing files offline rather than half a sec or so later.

* Fix early data discard

Fix issue in clip generator: when running very fast offline raw data being discarded before clips are generated. Changed threading model slightly and increased data keep time by 2x the thread jitter to try to avoid this.

* Update pom to JSerialCom 2.11.0

* V2.02.11e fix file start skip

Skipping start of files was causing click detector to not find clicks. Changed code so first seconds are still sent, but with data set to 0, rather than not sending data since that was causing sample counts in different bits of PAMGuard to get out of synch.
This commit is contained in:
Douglas Gillespie 2024-06-20 10:10:06 +01:00 committed by GitHub
parent 7818049ef1
commit 9d467593de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 189 additions and 52 deletions

View File

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

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.pamguard</groupId> <groupId>org.pamguard</groupId>
<artifactId>Pamguard</artifactId> <artifactId>Pamguard</artifactId>
<version>2.02.11d</version> <version>2.02.11e</version>
<name>Pamguard</name> <name>Pamguard</name>
<description>Pamguard using Maven to control dependencies</description> <description>Pamguard using Maven to control dependencies</description>
<url>www.pamguard.org</url> <url>www.pamguard.org</url>
@ -579,7 +579,7 @@
<dependency> <dependency>
<groupId>com.fazecast</groupId> <groupId>com.fazecast</groupId>
<artifactId>jSerialComm</artifactId> <artifactId>jSerialComm</artifactId>
<version>2.5.3</version> <version>2.11.0</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/edu.emory.mathcs/JTransforms --> <!-- https://mvnrepository.com/artifact/edu.emory.mathcs/JTransforms -->

View File

@ -15,6 +15,7 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.List; import java.util.List;
@ -1017,9 +1018,11 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
newDataUnit = new RawDataUnit(ms, 1 << ichan, totalSamples, newSamples); newDataUnit = new RawDataUnit(ms, 1 << ichan, totalSamples, newSamples);
newDataUnit.setRawData(doubleData[ichan]); newDataUnit.setRawData(doubleData[ichan]);
if (1000*(readFileSamples/sampleRate)>=fileInputParameters.skipStartFileTime) { if (1000*(readFileSamples/sampleRate)<fileInputParameters.skipStartFileTime) {
newDataUnits.addNewData(newDataUnit); // zero the data. Skipping it causes all the timing to screw up
Arrays.fill(doubleData[ichan], 0.);
} }
newDataUnits.addNewData(newDataUnit);
// GetOutputDataBlock().addPamData(pamDataUnit); // GetOutputDataBlock().addPamData(pamDataUnit);
} }

View File

@ -2951,6 +2951,23 @@ public class PamController implements PamControllerInterface, PamSettings {
return pamConfiguration; return pamConfiguration;
} }
/**
* Gets called on a timer when NOT processing from files.
* OR if processing files, gets called whenever the Calendar session start time or file time millis gets updated.
* @param timeInMillis
*/
public void updateMasterClock(long timeInMillis) {
/*
* this needs to notify binary stores that time has changed since the BS doesn't subscribe
* to anything, so doesn't get other clock updates.
*/
ArrayList<PamControlledUnit> bs = findControlledUnits(BinaryStore.class);
for (PamControlledUnit aBS : bs) {
BinaryStore binStore = (BinaryStore) aBS;
binStore.getBinaryStoreProcess().checkFileTime(timeInMillis);
}
}
} }

View File

@ -31,12 +31,12 @@ public class PamguardVersionInfo {
* Version number, major version.minorversion.sub-release. * Version number, major version.minorversion.sub-release.
* Note: can't go higher than sub-release 'f' * Note: can't go higher than sub-release 'f'
*/ */
static public final String version = "2.02.11d"; static public final String version = "2.02.11e";
/** /**
* Release date * Release date
*/ */
static public final String date = "30 May 2024"; static public final String date = "19 June 2024";
// /** // /**
// * Release type - Beta or Core // * Release type - Beta or Core

View File

@ -4,6 +4,8 @@ import java.awt.BorderLayout;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.Window; import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List; import java.util.List;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
@ -64,15 +66,28 @@ public class ReprocessChoiceDialog extends PamDialog {
List<ReprocessStoreChoice> userChoices = choiceSummary.getChoices(); List<ReprocessStoreChoice> userChoices = choiceSummary.getChoices();
choiceButtons = new JRadioButton[userChoices.size()]; choiceButtons = new JRadioButton[userChoices.size()];
ButtonGroup bg = new ButtonGroup(); ButtonGroup bg = new ButtonGroup();
SelAction selAction = new SelAction();
for (int i = 0; i < userChoices.size(); i++) { for (int i = 0; i < userChoices.size(); i++) {
ReprocessStoreChoice aChoice = userChoices.get(i); ReprocessStoreChoice aChoice = userChoices.get(i);
choiceButtons[i] = new JRadioButton(aChoice.toString()); choiceButtons[i] = new JRadioButton(aChoice.toString());
choiceButtons[i].setToolTipText(aChoice.getToolTip()); choiceButtons[i].setToolTipText(aChoice.getToolTip());
bg.add(choiceButtons[i]);
choiceButtons[i].addActionListener(selAction);
choicePanel.add(choiceButtons[i], c); choicePanel.add(choiceButtons[i], c);
c.gridy++; c.gridy++;
} }
setDialogComponent(mainPanel); setDialogComponent(mainPanel);
getCancelButton().setVisible(false); getCancelButton().setVisible(false);
getOkButton().setEnabled(false);
}
private class SelAction implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
getOkButton().setEnabled(true);
}
} }
public static ReprocessStoreChoice showDialog(Window parentFrame, StoreChoiceSummary choices) { public static ReprocessStoreChoice showDialog(Window parentFrame, StoreChoiceSummary choices) {

View File

@ -62,7 +62,7 @@ public class ReprocessManager {
*/ */
boolean setupOK = setupInputStream(choiceSummary, choice); boolean setupOK = setupInputStream(choiceSummary, choice);
if (choice == ReprocessStoreChoice.DONTSSTART) { if (choice == null || choice == ReprocessStoreChoice.DONTSSTART) {
return false; return false;
} }
@ -172,6 +172,8 @@ public class ReprocessManager {
choiceSummary.addChoice(ReprocessStoreChoice.STARTNORMAL); choiceSummary.addChoice(ReprocessStoreChoice.STARTNORMAL);
return choiceSummary; return choiceSummary;
} }
choiceSummary.addChoice(ReprocessStoreChoice.STARTNORMAL);
ArrayList<PamControlledUnit> outputStores = PamController.getInstance().findControlledUnits(DataOutputStore.class, true); ArrayList<PamControlledUnit> outputStores = PamController.getInstance().findControlledUnits(DataOutputStore.class, true);
boolean partStores = false; boolean partStores = false;

View File

@ -65,6 +65,9 @@ public class StoreChoiceSummary {
* @param choice * @param choice
*/ */
public void addChoice(ReprocessStoreChoice choice) { public void addChoice(ReprocessStoreChoice choice) {
if (choices.contains(choice)) {
return;
}
choices.add(choice); choices.add(choice);
} }

View File

@ -25,6 +25,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
@ -32,6 +33,7 @@ import java.util.TimeZone;
import PamController.PamController; import PamController.PamController;
import PamUtils.time.CalendarControl; import PamUtils.time.CalendarControl;
import binaryFileStorage.BinaryStore;
/** /**
@ -85,7 +87,7 @@ public class PamCalendar {
* viewPositions which is the number of milliseconds from the sessionsStartTime. * viewPositions which is the number of milliseconds from the sessionsStartTime.
*/ */
private static long viewPosition; private static long viewPosition;
/** /**
* If files are being analysed, return the time based on the file * If files are being analysed, return the time based on the file
@ -880,14 +882,18 @@ public class PamCalendar {
*/ */
public static void setSessionStartTime(long sessionStartTime) { public static void setSessionStartTime(long sessionStartTime) {
PamCalendar.sessionStartTime = sessionStartTime; PamCalendar.sessionStartTime = sessionStartTime;
PamController.getInstance().updateMasterClock(getTimeInMillis());
} }
/** /**
* *
* @param soundFileTimeMillis The start time of a sound file * Relative time within a sound file. This is always just added to sessionStartTime
* to give an absolute time.
* @param soundFileTimeMillis The relative time of a sound file.
*/ */
public static void setSoundFileTimeInMillis(long soundFileTimeMillis) { public static void setSoundFileTimeInMillis(long soundFileTimeMillis) {
PamCalendar.soundFileTimeInMillis = soundFileTimeMillis; PamCalendar.soundFileTimeInMillis = soundFileTimeMillis;
PamController.getInstance().updateMasterClock(getTimeInMillis());
} }
/** /**

View File

@ -257,12 +257,13 @@ public class PamRawDataBlock extends AcousticDataBlock<RawDataUnit> {
synchronized public RawDataUnit[] getAvailableSamples(long startMillis, long durationMillis, int channelMap) throws RawDataUnavailableException { synchronized public RawDataUnit[] getAvailableSamples(long startMillis, long durationMillis, int channelMap) throws RawDataUnavailableException {
RawDataUnit firstUnit = getFirstUnit(); RawDataUnit firstUnit = getFirstUnit();
if (firstUnit == null) { if (firstUnit == null) {
throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startMillis, (int) durationMillis); throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, 0,0, startMillis, (int) durationMillis);
} }
long firstMillis = firstUnit.getTimeMilliseconds(); long firstMillis = firstUnit.getTimeMilliseconds();
long firstSamples = firstUnit.getStartSample(); long firstSamples = firstUnit.getStartSample();
RawDataUnit lastUnit = getLastUnit(); RawDataUnit lastUnit = getLastUnit();
long lastMillis = lastUnit.getEndTimeInMilliseconds(); long lastMillis = lastUnit.getEndTimeInMilliseconds();
long lastSample = lastUnit.getStartSample()+lastUnit.getSampleDuration();
long firstAvailableMillis = Math.max(firstMillis, startMillis); long firstAvailableMillis = Math.max(firstMillis, startMillis);
@ -272,7 +273,8 @@ public class PamRawDataBlock extends AcousticDataBlock<RawDataUnit> {
double[][] data = getSamplesForMillis(firstAvailableMillis, lastAvailableMillis-firstAvailableMillis, channelMap); double[][] data = getSamplesForMillis(firstAvailableMillis, lastAvailableMillis-firstAvailableMillis, channelMap);
if (data == null) { if (data == null) {
// this shouldn't happen. If an exception wasn't thrown from getSamples... then data should no tb enull // this shouldn't happen. If an exception wasn't thrown from getSamples... then data should no tb enull
throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startMillis, (int) durationMillis); throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED,
firstSamples, lastSample, startMillis, (int) durationMillis);
} }
RawDataUnit[] dataUnits = new RawDataUnit[data.length]; RawDataUnit[] dataUnits = new RawDataUnit[data.length];
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
@ -298,7 +300,7 @@ public class PamRawDataBlock extends AcousticDataBlock<RawDataUnit> {
synchronized public double[][] getSamplesForMillis(long startMillis, long durationMillis, int channelMap) throws RawDataUnavailableException { synchronized public double[][] getSamplesForMillis(long startMillis, long durationMillis, int channelMap) throws RawDataUnavailableException {
RawDataUnit firstUnit = getFirstUnit(); RawDataUnit firstUnit = getFirstUnit();
if (firstUnit == null) { if (firstUnit == null) {
throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startMillis, (int) durationMillis); throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, 0, 0, startMillis, (int) durationMillis);
} }
long firstMillis = firstUnit.getTimeMilliseconds(); long firstMillis = firstUnit.getTimeMilliseconds();
long firstSamples = firstUnit.getStartSample(); long firstSamples = firstUnit.getStartSample();
@ -317,23 +319,28 @@ public class PamRawDataBlock extends AcousticDataBlock<RawDataUnit> {
// run a few tests ... // run a few tests ...
int chanOverlap = channelMap & getChannelMap(); int chanOverlap = channelMap & getChannelMap();
if (chanOverlap != channelMap) { if (chanOverlap != channelMap) {
throw new RawDataUnavailableException(this, RawDataUnavailableException.INVALID_CHANNEL_LIST, startSample, duration); throw new RawDataUnavailableException(this, RawDataUnavailableException.INVALID_CHANNEL_LIST, 0,0,startSample, duration);
} }
if (duration < 0) { if (duration < 0) {
throw new RawDataUnavailableException(this, RawDataUnavailableException.NEGATIVE_DURATION, startSample, duration); throw new RawDataUnavailableException(this, RawDataUnavailableException.NEGATIVE_DURATION,0,0, startSample, duration);
} }
RawDataUnit dataUnit = getFirstUnit(); RawDataUnit dataUnit = getFirstUnit();
if (dataUnit == null) { if (dataUnit == null) {
return null; return null;
} }
if (dataUnit.getStartSample() > startSample) { RawDataUnit lastUnit = getLastUnit();
long firstSample = dataUnit.getStartSample();
long lastSample = lastUnit.getStartSample()+lastUnit.getSampleDuration();
if (firstSample > startSample) {
// System.out.println("Earliest start sample : " + dataUnit.getStartSample()); // System.out.println("Earliest start sample : " + dataUnit.getStartSample());
throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_ALREADY_DISCARDED, startSample, duration); throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_ALREADY_DISCARDED,
firstSample, lastSample, startSample, duration);
} }
dataUnit = getLastUnit(); dataUnit = getLastUnit();
if (hasLastSample(dataUnit, startSample+duration, channelMap) == false) { if (hasLastSample(dataUnit, startSample+duration, channelMap) == false) {
throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED, startSample, duration); throw new RawDataUnavailableException(this, RawDataUnavailableException.DATA_NOT_ARRIVED,
firstSample, lastSample, startSample, duration);
} }
int nChan = PamUtils.getNumChannels(channelMap); int nChan = PamUtils.getNumChannels(channelMap);

View File

@ -21,6 +21,10 @@ public class RawDataUnavailableException extends Exception {
private long startSample; private long startSample;
private int duration; private int duration;
private long availableStart;
private long availableEnd;
/** /**
* @return the dataCause * @return the dataCause
*/ */
@ -34,10 +38,12 @@ public class RawDataUnavailableException extends Exception {
* @param startSample * @param startSample
* @param cause * @param cause
*/ */
public RawDataUnavailableException(PamRawDataBlock rawDataBlock, int dataCause, long startSample, int duration) { public RawDataUnavailableException(PamRawDataBlock rawDataBlock, int dataCause, long availStart, long availEnd, long startSample, int duration) {
super(); super();
this.rawDataBlock = rawDataBlock; this.rawDataBlock = rawDataBlock;
this.dataCause = dataCause; this.dataCause = dataCause;
this.availableStart = availStart;
this.availableEnd = availEnd;
this.startSample = startSample; this.startSample = startSample;
this.duration = duration; this.duration = duration;
} }
@ -55,8 +61,8 @@ public class RawDataUnavailableException extends Exception {
public String getMessage() { public String getMessage() {
switch (dataCause) { switch (dataCause) {
case DATA_ALREADY_DISCARDED: case DATA_ALREADY_DISCARDED:
return String.format("Samples %d length %d requested from %s have already been discarded", startSample, duration, return String.format("Samples %d length %d requested from %s have already been discarded. %d to %d available", startSample, duration,
rawDataBlock.getDataName()); rawDataBlock.getDataName(), availableStart, availableEnd);
case DATA_NOT_ARRIVED: case DATA_NOT_ARRIVED:
return String.format("Samples %d length %d requested from %s have not yet arrived", return String.format("Samples %d length %d requested from %s have not yet arrived",
startSample, duration, rawDataBlock.getDataName()); startSample, duration, rawDataBlock.getDataName());
@ -70,6 +76,20 @@ public class RawDataUnavailableException extends Exception {
} }
return super.getMessage(); return super.getMessage();
} }
/**
* @return the availableStart
*/
public long getAvailableStart() {
return availableStart;
}
/**
* @return the availableEnd
*/
public long getAvailableEnd() {
return availableEnd;
}
} }

View File

@ -8,6 +8,7 @@ import Acquisition.AcquisitionControl;
import Acquisition.AcquisitionProcess; import Acquisition.AcquisitionProcess;
import Acquisition.DaqSystem; import Acquisition.DaqSystem;
import PamController.PamController; import PamController.PamController;
import PamModel.PamModel;
import PamUtils.PamCalendar; import PamUtils.PamCalendar;
import PamguardMVC.debug.Debug; import PamguardMVC.debug.Debug;
@ -130,6 +131,7 @@ public class ThreadedObserver implements PamObserver {
} }
} }
} }
h += PamModel.getPamModel().getPamModelSettings().getThreadingJitterMillis()*2;
return h; return h;
} }

View File

@ -228,6 +228,7 @@ PamSettingsSource, DataOutputStore {
super.pamToStart(); super.pamToStart();
prepareStores(); prepareStores();
openStores(); openStores();
binaryStoreProcess.checkFileTimer();
} }
@Override @Override
@ -245,9 +246,9 @@ PamSettingsSource, DataOutputStore {
* Called from the process to close and reopen each datastream in * Called from the process to close and reopen each datastream in
* a new file. Probably gets called about once an hour on the hour. * a new file. Probably gets called about once an hour on the hour.
*/ */
protected void reOpenStores(int endReason) { protected synchronized void reOpenStores(int endReason, long newFileTime) {
long dataTime = PamCalendar.getTimeInMillis(); long dataTime = newFileTime;//PamCalendar.getTimeInMillis();
long analTime = System.currentTimeMillis(); long analTime = System.currentTimeMillis();
BinaryOutputStream dataStream; BinaryOutputStream dataStream;
for (int i = 0; i < storageStreams.size(); i++) { for (int i = 0; i < storageStreams.size(); i++) {
@ -536,7 +537,7 @@ PamSettingsSource, DataOutputStore {
*/ */
if (immediateChanges) { if (immediateChanges) {
if (storesOpen) { if (storesOpen) {
reOpenStores(BinaryFooter.END_UNKNOWN); reOpenStores(BinaryFooter.END_UNKNOWN, PamCalendar.getTimeInMillis());
} }
} }
@ -2601,5 +2602,11 @@ PamSettingsSource, DataOutputStore {
public DataIntegrityChecker getInegrityChecker() { public DataIntegrityChecker getInegrityChecker() {
return new BinaryIntegrityChecker(this); return new BinaryIntegrityChecker(this);
} }
/**
* @return the binaryStoreProcess
*/
public BinaryStoreProcess getBinaryStoreProcess() {
return binaryStoreProcess;
}
} }

View File

@ -7,37 +7,43 @@ import PamUtils.PamCalendar;
import PamguardMVC.PamProcess; import PamguardMVC.PamProcess;
public class BinaryStoreProcess extends PamProcess { public class BinaryStoreProcess extends PamProcess {
private BinaryStore binaryStore; private BinaryStore binaryStore;
private long startTime; private long startTime;
private long nextFileTime; private long nextFileTime;
private Timer timer; private Timer timer;
private Object timerSynch = new Object();
public BinaryStoreProcess(BinaryStore binaryStore) { public BinaryStoreProcess(BinaryStore binaryStore) {
super(binaryStore, null); super(binaryStore, null);
this.binaryStore = binaryStore; this.binaryStore = binaryStore;
} }
@Override @Override
public String getProcessName() { public String getProcessName() {
return "Binary store file control"; return "Binary store file control";
} }
public synchronized void checkFileTime() { public synchronized void checkFileTime(long masterClockTime) {
// if (binaryStore.binaryStoreSettings.autoNewFiles &&
// PamCalendar.getTimeInMillis() >= nextFileTime) {
// startNewFiles();
// }
if (binaryStore.binaryStoreSettings.autoNewFiles && if (binaryStore.binaryStoreSettings.autoNewFiles &&
PamCalendar.getTimeInMillis() >= nextFileTime) { masterClockTime >= nextFileTime) {
startNewFiles(); startNewFiles(masterClockTime);
} }
} }
private synchronized void startNewFiles() { private synchronized void startNewFiles(long masterClockTime) {
nextFileTime += binaryStore.binaryStoreSettings.fileSeconds * 1000; nextFileTime += binaryStore.binaryStoreSettings.fileSeconds * 1000;
binaryStore.reOpenStores(BinaryFooter.END_FILETOOLONG); binaryStore.reOpenStores(BinaryFooter.END_FILETOOLONG, masterClockTime);
} }
@ -46,24 +52,55 @@ public class BinaryStoreProcess extends PamProcess {
startTime = PamCalendar.getTimeInMillis(); startTime = PamCalendar.getTimeInMillis();
long round = binaryStore.binaryStoreSettings.fileSeconds * 1000; long round = binaryStore.binaryStoreSettings.fileSeconds * 1000;
nextFileTime = (startTime/round) * round + round; nextFileTime = (startTime/round) * round + round;
// System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime)); // System.out.println("Next file start at " + PamCalendar.formatDateTime(nextFileTime));
timer = new Timer(); }
timer.schedule(new FileTimerTask(), 1000, 1000);
public void checkFileTimer() {
boolean needTimer = PamCalendar.isSoundFile() == false;
if (needTimer) {
startTimer();
}
else {
stopTimer();
}
} }
private void startTimer() {
synchronized (timerSynch) {
if (timer == null) {
timer = new Timer();
timer.schedule(new FileTimerTask(), 1000, 1000);
}
}
}
private void stopTimer() {
synchronized (timerSynch) {
if (timer != null) {
timer.cancel();
timer = null;
}
}
}
// @Override
// public void masterClockUpdate(long timeMilliseconds, long sampleNumber) {
// super.masterClockUpdate(timeMilliseconds, sampleNumber);
// checkFileTime(timeMilliseconds);
// }
class FileTimerTask extends TimerTask { class FileTimerTask extends TimerTask {
@Override @Override
public void run() { public void run() {
checkFileTime(); checkFileTime(PamCalendar.getTimeInMillis());
} }
} }
@Override @Override
public void pamStop() { public void pamStop() {
if (timer != null) { stopTimer();
timer.cancel();
}
} }
} }

View File

@ -329,7 +329,7 @@ public class ClickDetector extends PamProcess {
offlineEventLogging.setSubLogging(getClickDataBlock().getOfflineClickLogging()); offlineEventLogging.setSubLogging(getClickDataBlock().getOfflineClickLogging());
triggerBackgroundHandler = new TriggerBackgroundHandler(this); triggerBackgroundHandler = new TriggerBackgroundHandler(this);
clickBackgroundManager = new ClickBackgroundManager(this); clickBackgroundManager = new ClickBackgroundManager(this);
setProcessCheck(new BaseProcessCheck(this, RawDataUnit.class, 1, 0.0000001)); setProcessCheck(new BaseProcessCheck(this, RawDataUnit.class, 1, 0.0000001));
@ -1378,7 +1378,7 @@ public class ClickDetector extends PamProcess {
private boolean initialiseFilters; private boolean initialiseFilters;
private long clickStartSample, clickEndSample; private long clickStartSample, clickEndSample;
private double maxSignalExcess; private double maxSignalExcess;
private int clickTriggers; private int clickTriggers;

View File

@ -140,10 +140,13 @@ public class ClipProcess extends SpectrogramMarkProcess {
clipErr = clipRequest.clipBlockProcess.processClipRequest(clipRequest); clipErr = clipRequest.clipBlockProcess.processClipRequest(clipRequest);
switch (clipErr) { switch (clipErr) {
case 0: // no error - clip should have been created. case 0: // no error - clip should have been created.
li.remove();
break;
case RawDataUnavailableException.DATA_ALREADY_DISCARDED: case RawDataUnavailableException.DATA_ALREADY_DISCARDED:
case RawDataUnavailableException.INVALID_CHANNEL_LIST: case RawDataUnavailableException.INVALID_CHANNEL_LIST:
// System.out.println("Clip error : " + clipErr); // System.out.println("Clip error : " + clipErr);
li.remove(); li.remove();
break;
case RawDataUnavailableException.DATA_NOT_ARRIVED: case RawDataUnavailableException.DATA_NOT_ARRIVED:
continue; // hopefully, will get this next time ! continue; // hopefully, will get this next time !
} }
@ -230,6 +233,17 @@ public class ClipProcess extends SpectrogramMarkProcess {
} }
minH = Math.max(minH, clipBlockProcesses[i].getRequiredDataHistory(o, arg)); minH = Math.max(minH, clipBlockProcesses[i].getRequiredDataHistory(o, arg));
} }
ClipRequest firstClip = null;
synchronized(clipRequestSynch) {
if (clipRequestQueue.size() > 0) {
firstClip = clipRequestQueue.get(0);
}
}
if (firstClip != null) {
minH += firstClip.dataUnit.getDurationInMilliseconds();
}
minH += Math.max(3000, 192000/(long)getSampleRate()); minH += Math.max(3000, 192000/(long)getSampleRate());
if (specMouseDown) { if (specMouseDown) {
minH = Math.max(minH, masterClockTime-specMouseDowntime); minH = Math.max(minH, masterClockTime-specMouseDowntime);
@ -453,8 +467,7 @@ public class ClipProcess extends SpectrogramMarkProcess {
this.dataBlock = dataBlock; this.dataBlock = dataBlock;
this.clipGenSetting = clipGenSetting; this.clipGenSetting = clipGenSetting;
clipBudgetMaker = new StandardClipBudgetMaker(this); clipBudgetMaker = new StandardClipBudgetMaker(this);
dataBlock.addObserver(this, true); dataBlock.addObserver(this, false);
if (rawDataBlock != null) { if (rawDataBlock != null) {
int chanMap = decideChannelMap(rawDataBlock.getChannelMap()); int chanMap = decideChannelMap(rawDataBlock.getChannelMap());
@ -499,6 +512,7 @@ public class ClipProcess extends SpectrogramMarkProcess {
rawData = rawDataBlock.getSamples(rawStart, (int) (rawEnd-rawStart), channelMap); rawData = rawDataBlock.getSamples(rawStart, (int) (rawEnd-rawStart), channelMap);
} }
catch (RawDataUnavailableException e) { catch (RawDataUnavailableException e) {
System.out.println(e.getMessage());
return e.getDataCause(); return e.getDataCause();
} }
if (rawData==null) { if (rawData==null) {
@ -583,9 +597,15 @@ public class ClipProcess extends SpectrogramMarkProcess {
public PamObserver getObserverObject() { public PamObserver getObserverObject() {
return clipProcess.getObserverObject(); return clipProcess.getObserverObject();
} }
@Override @Override
public long getRequiredDataHistory(PamObservable o, Object arg) { public long getRequiredDataHistory(PamObservable o, Object arg) {
return (long) ((clipGenSetting.preSeconds+clipGenSetting.postSeconds) * 1000.); long h = (long) ((clipGenSetting.preSeconds+clipGenSetting.postSeconds) * 1000.);
// if (dataBlock != null) {
// can't do this since dataBlock is observing this, so will wrap.
// h += dataBlock.getRequiredHistory();
// }
return h;
} }

View File

@ -150,8 +150,7 @@ public class DBXMLConnect {
*/ */
public boolean postAndLog(Object nilusObject, String documentName) throws TethysException public boolean postAndLog(Object nilusObject, String documentName) throws TethysException
{ {
boolean ok = NilusChecker.warnEmptyFields(tethysControl.getGuiFrame(), nilusObject); // boolean ok = NilusChecker.warnEmptyFields(tethysControl.getGuiFrame(), nilusObject);
TethysException e = null; TethysException e = null;
boolean success = false; boolean success = false;