You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
482 lines
13 KiB
C++
482 lines
13 KiB
C++
/***************************************************************************
|
|
* Copyright (C) gempa GmbH *
|
|
* All rights reserved. *
|
|
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
|
* *
|
|
* GNU Affero General Public License Usage *
|
|
* This file may be used under the terms of the GNU Affero *
|
|
* Public License version 3.0 as published by the Free Software Foundation *
|
|
* and appearing in the file LICENSE included in the packaging of this *
|
|
* file. Please review the following information to ensure the GNU Affero *
|
|
* Public License version 3.0 requirements will be met: *
|
|
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
|
* *
|
|
* Other Usage *
|
|
* Alternatively, this file may be used in accordance with the terms and *
|
|
* conditions contained in a signed written agreement between you and *
|
|
* gempa GmbH. *
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef SEISCOMP_GUI_AMPLITUDEVIEW_H
|
|
#define SEISCOMP_GUI_AMPLITUDEVIEW_H
|
|
|
|
#include <seiscomp/gui/datamodel/ui_amplitudeview.h>
|
|
#include <seiscomp/gui/core/recordview.h>
|
|
#include <seiscomp/gui/core/connectionstatelabel.h>
|
|
#include <seiscomp/gui/core/utils.h>
|
|
#ifndef Q_MOC_RUN
|
|
#include <seiscomp/seismology/ttt.h>
|
|
#include <seiscomp/datamodel/databasequery.h>
|
|
#include <seiscomp/datamodel/origin.h>
|
|
#include <seiscomp/datamodel/magnitude.h>
|
|
#include <seiscomp/datamodel/pick.h>
|
|
#include <seiscomp/datamodel/amplitude.h>
|
|
#include <seiscomp/processing/amplitudeprocessor.h>
|
|
#include <seiscomp/processing/magnitudeprocessor.h>
|
|
#include <seiscomp/math/matrix3.h>
|
|
#endif
|
|
|
|
#include <QActionGroup>
|
|
#include <QComboBox>
|
|
#include <QSpinBox>
|
|
#include <QCheckBox>
|
|
#include <QMovie>
|
|
#include <QSet>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
|
|
|
|
namespace Seiscomp {
|
|
|
|
namespace DataModel {
|
|
|
|
class SensorLocation;
|
|
|
|
}
|
|
|
|
namespace Gui {
|
|
|
|
class TimeScale;
|
|
class AmplitudeView;
|
|
|
|
|
|
namespace PrivateAmplitudeView {
|
|
|
|
class AmplitudeRecordLabel;
|
|
|
|
class SC_GUI_API ThreeComponentTrace : public QObject {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
ThreeComponentTrace() = default;
|
|
~ThreeComponentTrace();
|
|
|
|
public:
|
|
void setTransformationEnabled(bool);
|
|
void showProcessedData(bool);
|
|
void setRecordWidget(RecordWidget *);
|
|
void setFilter(RecordWidget::Filter *, const std::string &filterID);
|
|
bool transform(int comp = -1, Record *rec = nullptr);
|
|
|
|
bool setProcessedData(int comp,
|
|
const std::string &networkCode,
|
|
const std::string &stationCode,
|
|
const std::string &locationCode,
|
|
const Core::Time &startTime,
|
|
double samplingFrequency,
|
|
DoubleArrayPtr data);
|
|
void removeProcessedData(int comp);
|
|
|
|
private slots:
|
|
void widgetDestroyed(QObject *obj);
|
|
|
|
private:
|
|
void transformedRecord(int comp, const Record *rec);
|
|
|
|
public:
|
|
// One component
|
|
struct Component {
|
|
std::string channelCode;
|
|
int recordSlot;
|
|
RecordSequence *raw{nullptr};
|
|
RecordSequence *transformed{nullptr};
|
|
RecordSequence *processed{nullptr};
|
|
RecordWidget::Filter *filter{nullptr};
|
|
RecordStreamThread *thread{nullptr};
|
|
};
|
|
|
|
AmplitudeRecordLabel *label;
|
|
Math::Matrix3d transformation;
|
|
Component traces[3];
|
|
std::string filterID;
|
|
RecordWidget *widget{nullptr};
|
|
bool enableTransformation{false};
|
|
bool showProcessed{false};
|
|
};
|
|
|
|
|
|
class SC_GUI_API AmplitudeRecordLabel : public StandardRecordLabel {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
AmplitudeRecordLabel(int items=3, QWidget *parent=0, const char* name = 0);
|
|
~AmplitudeRecordLabel();
|
|
|
|
public:
|
|
void setControlledItem(RecordViewItem *controlledItem);
|
|
RecordViewItem *controlledItem() const;
|
|
|
|
void setLinkedItem(bool sm);
|
|
|
|
void enabledExpandButton(RecordViewItem *controlledItem);
|
|
void disableExpandButton();
|
|
void unlink();
|
|
|
|
bool isLinkedItem() const;
|
|
bool isExpanded() const;
|
|
|
|
void setLabelColor(QColor);
|
|
void removeLabelColor();
|
|
|
|
void updateProcessingInfo();
|
|
|
|
protected:
|
|
void visibilityChanged(bool);
|
|
void resizeEvent(QResizeEvent *e);
|
|
void paintEvent(QPaintEvent *e);
|
|
|
|
public slots:
|
|
void extentButtonPressed();
|
|
|
|
private slots:
|
|
void enableExpandable(const Seiscomp::Record*);
|
|
|
|
private:
|
|
bool _isLinkedItem;
|
|
bool _isExpanded;
|
|
QPushButton *_btnExpand;
|
|
RecordViewItem *_linkedItem;
|
|
bool _hasLabelColor;
|
|
QColor _labelColor;
|
|
|
|
public:
|
|
double latitude;
|
|
double longitude;
|
|
const DataModel::SensorLocation *location;
|
|
|
|
Core::TimeWindow timeWindow;
|
|
ThreeComponentTrace data;
|
|
|
|
Math::Matrix3f orientationZNE;
|
|
Math::Matrix3f orientationZRT;
|
|
|
|
Processing::AmplitudeProcessorPtr processor;
|
|
Processing::MagnitudeProcessorPtr magnitudeProcessor;
|
|
|
|
double initialMinSNR;
|
|
|
|
QString infoText;
|
|
bool isError;
|
|
|
|
bool hasGotData;
|
|
bool isEnabledByConfig;
|
|
|
|
friend class Gui::AmplitudeView;
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
class AmplitudeViewPrivate;
|
|
|
|
|
|
class SC_GUI_API AmplitudeView : public QMainWindow {
|
|
public:
|
|
struct SC_GUI_API Config {
|
|
typedef QPair<QString, QString> FilterEntry;
|
|
typedef QVector<FilterEntry> FilterList;
|
|
typedef QList<QString> StringList;
|
|
|
|
QString recordURL;
|
|
FilterList filters;
|
|
|
|
bool showAllComponents;
|
|
bool loadStrongMotionData;
|
|
double allComponentsMaximumStationDistance;
|
|
double defaultAddStationsDistance;
|
|
|
|
bool ignoreDisabledStations;
|
|
bool hideStationsWithoutData;
|
|
|
|
QColor timingQualityLow;
|
|
QColor timingQualityMedium;
|
|
QColor timingQualityHigh;
|
|
|
|
Core::TimeSpan preOffset;
|
|
Core::TimeSpan postOffset;
|
|
|
|
Config();
|
|
|
|
void addFilter(const QString &f, const QString &n) {
|
|
filters.push_back(QPair<QString, QString>(f, n));
|
|
}
|
|
};
|
|
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
//! Default c'tor
|
|
AmplitudeView(QWidget *parent = 0, Qt::WindowFlags f = 0);
|
|
~AmplitudeView();
|
|
|
|
public:
|
|
bool setConfig(const Config &c, QString *error = nullptr);
|
|
|
|
void setDatabase(Seiscomp::DataModel::DatabaseQuery*);
|
|
|
|
//! Sets an origin and inserts the traces for each arrival
|
|
//! in the view.
|
|
bool setOrigin(Seiscomp::DataModel::Origin*, const std::string &magType);
|
|
|
|
bool hasModifiedAmplitudes() const;
|
|
void getChangedAmplitudes(ObjectChangeList<DataModel::Amplitude> &list) const;
|
|
|
|
void stop();
|
|
|
|
void selectTrace(const Seiscomp::DataModel::WaveformStreamID &wid);
|
|
void selectTrace(const std::string &code);
|
|
|
|
const std::string ¤tMagnitudeType() const;
|
|
|
|
void setStrongMotionCodes(const std::vector<std::string> &codes);
|
|
|
|
|
|
public slots:
|
|
void setDefaultDisplay();
|
|
void applyAmplitudes();
|
|
void changeFilter(int);
|
|
void setArrivalState(int arrivalId, bool state);
|
|
|
|
void setStationEnabled(const std::string& networkCode,
|
|
const std::string& stationCode,
|
|
bool state);
|
|
|
|
void setCurrentStation(const std::string& networkCode,
|
|
const std::string& stationCode);
|
|
|
|
|
|
signals:
|
|
void magnitudeCreated(Seiscomp::DataModel::Magnitude*);
|
|
void amplitudesConfirmed(Seiscomp::DataModel::Origin*, QList<Seiscomp::DataModel::AmplitudePtr>);
|
|
|
|
|
|
private slots:
|
|
void receivedRecord(Seiscomp::Record*);
|
|
|
|
void updateTraceInfo(RecordViewItem*, const Seiscomp::Record*);
|
|
void onAddedItem(const Seiscomp::Record*, Seiscomp::Gui::RecordViewItem*);
|
|
void onSelectedTime(Seiscomp::Core::Time);
|
|
void onSelectedTimeRange(Seiscomp::Core::Time, Seiscomp::Core::Time);
|
|
void onChangingTimeRange(Seiscomp::Core::Time, Seiscomp::Core::Time);
|
|
void onSelectedTime(Seiscomp::Gui::RecordWidget*, Seiscomp::Core::Time);
|
|
void setAlignment(Seiscomp::Core::Time);
|
|
void acquisitionFinished();
|
|
void commit();
|
|
void itemSelected(RecordViewItem*, RecordViewItem*);
|
|
void updateMainCursor(RecordWidget*,int);
|
|
void updateSubCursor(RecordWidget*,int);
|
|
void updateItemLabel(RecordViewItem*, char);
|
|
void updateItemRecordState(const Seiscomp::Record*);
|
|
void updateRecordValue(Seiscomp::Core::Time);
|
|
void showTraceScaleToggled(bool);
|
|
void showTheoreticalArrivals(bool);
|
|
|
|
void limitFilterToZoomTrace(bool);
|
|
|
|
void toggleFilter();
|
|
void addNewFilter(const QString&);
|
|
|
|
void scaleVisibleAmplitudes();
|
|
|
|
void changeScale(double, double);
|
|
void changeTimeRange(double, double);
|
|
|
|
void sortAlphabetically();
|
|
void sortByDistance();
|
|
|
|
void showZComponent();
|
|
void showNComponent();
|
|
void showEComponent();
|
|
|
|
void alignOnOriginTime();
|
|
void alignOnPArrivals();
|
|
|
|
void pickNone(bool);
|
|
void pickAmplitudes(bool);
|
|
|
|
void scaleAmplUp();
|
|
void scaleAmplDown();
|
|
void scaleTimeUp();
|
|
void scaleTimeDown();
|
|
|
|
void scaleReset();
|
|
|
|
void scrollLeft();
|
|
void scrollFineLeft();
|
|
void scrollRight();
|
|
void scrollFineRight();
|
|
|
|
void createAmplitude();
|
|
void setAmplitude();
|
|
void confirmAmplitude();
|
|
void deleteAmplitude();
|
|
|
|
void setCurrentRowEnabled(bool);
|
|
void setCurrentRowDisabled(bool);
|
|
|
|
void loadNextStations();
|
|
void showUsedStations(bool);
|
|
|
|
void moveTraces(double offset);
|
|
void move(double offset);
|
|
void zoom(float factor);
|
|
void applyTimeRange(double,double);
|
|
|
|
void sortByState();
|
|
void alignByState();
|
|
void componentByState();
|
|
void updateLayoutFromState();
|
|
|
|
void firstConnectionEstablished();
|
|
void lastConnectionClosed();
|
|
|
|
void beginWaitForRecords();
|
|
void doWaitForRecords(int value);
|
|
void endWaitForRecords();
|
|
|
|
void showFullscreen(bool);
|
|
|
|
void recalculateAmplitude();
|
|
void recalculateAmplitudes();
|
|
|
|
void enableAutoScale();
|
|
void disableAutoScale();
|
|
|
|
void zoomSelectionHandleMoved(int,double,Qt::KeyboardModifiers);
|
|
void zoomSelectionHandleMoveFinished();
|
|
|
|
void selectionHandleMoved(int,double,Qt::KeyboardModifiers);
|
|
void selectionHandleMoveFinished();
|
|
|
|
void addStations();
|
|
|
|
void searchStation();
|
|
void search(const QString&);
|
|
void nextSearch();
|
|
void abortSearchStation();
|
|
|
|
void openConnectionInfo(const QPoint &);
|
|
|
|
void ttInterfaceChanged(QString);
|
|
void ttTableChanged(QString);
|
|
|
|
|
|
protected:
|
|
void showEvent(QShowEvent* event);
|
|
|
|
RecordLabel* createLabel(RecordViewItem*) const;
|
|
|
|
|
|
private:
|
|
void figureOutTravelTimeTable();
|
|
|
|
void init();
|
|
|
|
RecordViewItem* addStream(const DataModel::SensorLocation *,
|
|
const DataModel::WaveformStreamID& streamID,
|
|
const Core::Time &referenceTime,
|
|
bool showDisabled);
|
|
|
|
RecordViewItem* addRawStream(const DataModel::SensorLocation *,
|
|
const DataModel::WaveformStreamID& streamID,
|
|
const Core::Time &referenceTime);
|
|
|
|
void queueStream(const DataModel::WaveformStreamID& streamID, int component);
|
|
|
|
void setupItem(const char comps[3], RecordViewItem*);
|
|
bool addTheoreticalArrivals(RecordViewItem*,
|
|
const std::string& netCode,
|
|
const std::string& staCode,
|
|
const std::string& locCode);
|
|
bool fillTheoreticalArrivals();
|
|
|
|
void resetState();
|
|
|
|
void updateOriginInformation();
|
|
|
|
void loadNextStations(float distance);
|
|
|
|
void setCursorText(const QString&);
|
|
void setCursorPos(const Seiscomp::Core::Time&, bool always = false);
|
|
void setTimeRange(float, float);
|
|
|
|
void acquireStreams();
|
|
|
|
bool applyFilter(RecordViewItem *item = nullptr);
|
|
|
|
|
|
//! Makes sure that the time range [tmin, tmax] is visible.
|
|
//! When the interval is larger than the visible area
|
|
//! the time range will be left aligned.
|
|
void ensureVisibility(double &tmin, double &tmax);
|
|
void ensureVisibility(const Seiscomp::Core::Time &time, int pixelMargin);
|
|
|
|
RecordMarker *updatePhaseMarker(Seiscomp::Gui::RecordViewItem*,
|
|
const Processing::AmplitudeProcessor *proc,
|
|
const Processing::AmplitudeProcessor::Result &res);
|
|
|
|
void setPhaseMarker(Seiscomp::Gui::RecordWidget*, const Seiscomp::Core::Time&);
|
|
|
|
void updateCurrentRowState();
|
|
void setMarkerState(Seiscomp::Gui::RecordWidget*, bool);
|
|
|
|
bool setArrivalState(Seiscomp::Gui::RecordWidget* w, int arrivalId, bool state);
|
|
void resetAmplitude(RecordViewItem *item, const QString &text, bool enable);
|
|
|
|
void fetchManualAmplitudes(std::vector<RecordMarker*>* marker = nullptr) const;
|
|
|
|
void showComponent(char componentCode);
|
|
void fetchComponent(char componentCode);
|
|
|
|
void addAmplitude(Gui::RecordViewItem*,
|
|
DataModel::Amplitude*,
|
|
DataModel::Pick*, Core::Time reference, int id);
|
|
|
|
void addFilter(const QString& name, const QString& filter);
|
|
|
|
void changeFilter(int, bool force);
|
|
|
|
void closeThreads();
|
|
|
|
char currentComponent() const;
|
|
|
|
void searchByText(const QString &text);
|
|
|
|
void newAmplitudeAvailable(const Processing::AmplitudeProcessor*,
|
|
const Processing::AmplitudeProcessor::Result &);
|
|
|
|
private:
|
|
AmplitudeViewPrivate *_d_ptr;
|
|
};
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|