Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
4f47f9f343
@ -9,6 +9,7 @@ from PySide import QtCore, QtGui, QtCore
|
|||||||
from asp3d_layout import *
|
from asp3d_layout import *
|
||||||
from fmtomo_parameters_layout import *
|
from fmtomo_parameters_layout import *
|
||||||
from generate_survey_layout import *
|
from generate_survey_layout import *
|
||||||
|
from generate_survey_layout_minimal import *
|
||||||
from generate_seisarray_layout import *
|
from generate_seisarray_layout import *
|
||||||
from picking_parameters_layout import *
|
from picking_parameters_layout import *
|
||||||
from pylot.core.active import activeSeismoPick, surveyUtils, fmtomoUtils, seismicArrayPreparation
|
from pylot.core.active import activeSeismoPick, surveyUtils, fmtomoUtils, seismicArrayPreparation
|
||||||
@ -85,6 +86,34 @@ class gui_control(object):
|
|||||||
if self.checkSurveyState():
|
if self.checkSurveyState():
|
||||||
if not self.continueDialogExists('Survey'):
|
if not self.continueDialogExists('Survey'):
|
||||||
return
|
return
|
||||||
|
if self.checkSeisArrayState():
|
||||||
|
if self.continueDialogMessage('Use geometry information of active Seismic Array?'):
|
||||||
|
if self.gen_survey_fromSeisArray():
|
||||||
|
self.initNewSurvey()
|
||||||
|
else:
|
||||||
|
if self.gen_survey_fromSRfiles():
|
||||||
|
self.initNewSurvey()
|
||||||
|
|
||||||
|
def initNewSurvey(self):
|
||||||
|
self.survey.setArtificialPick(0, 0) # artificial pick at source origin
|
||||||
|
surveyUtils.setDynamicFittedSNR(self.survey.getShotDict())
|
||||||
|
self.setSurveyState(True)
|
||||||
|
self.setPickState(False)
|
||||||
|
|
||||||
|
def gen_survey_fromSeisArray(self):
|
||||||
|
qdialog = QtGui.QDialog(self.mainwindow)
|
||||||
|
ui = Ui_generate_survey_minimal()
|
||||||
|
ui.setupUi(qdialog)
|
||||||
|
self.gen_new_survey_min = ui
|
||||||
|
self.connectButtons_gen_survey_min()
|
||||||
|
if qdialog.exec_():
|
||||||
|
obsdir = self.gen_new_survey_min.lineEdit_obs.text()
|
||||||
|
self.survey = activeSeismoPick.Survey(obsdir, seisArray = self.seisarray,
|
||||||
|
useDefaultParas = True)
|
||||||
|
self.setConnected2SurveyState(True)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def gen_survey_fromSRfiles(self):
|
||||||
qdialog = QtGui.QDialog(self.mainwindow)
|
qdialog = QtGui.QDialog(self.mainwindow)
|
||||||
ui = Ui_generate_survey()
|
ui = Ui_generate_survey()
|
||||||
ui.setupUi(qdialog)
|
ui.setupUi(qdialog)
|
||||||
@ -96,11 +125,8 @@ class gui_control(object):
|
|||||||
obsdir = self.gen_new_survey.lineEdit_obs.text()
|
obsdir = self.gen_new_survey.lineEdit_obs.text()
|
||||||
self.survey = activeSeismoPick.Survey(obsdir, srcfile, recfile,
|
self.survey = activeSeismoPick.Survey(obsdir, srcfile, recfile,
|
||||||
useDefaultParas = True)
|
useDefaultParas = True)
|
||||||
self.survey.setArtificialPick(0, 0) # artificial pick at source origin
|
|
||||||
surveyUtils.setDynamicFittedSNR(self.survey.getShotDict())
|
|
||||||
self.setSurveyState(True)
|
|
||||||
self.setPickState(False)
|
|
||||||
self.setConnected2SurveyState(False)
|
self.setConnected2SurveyState(False)
|
||||||
|
return True
|
||||||
|
|
||||||
def addArrayPlot(self):
|
def addArrayPlot(self):
|
||||||
self.seisArrayFigure = Figure()
|
self.seisArrayFigure = Figure()
|
||||||
@ -182,6 +208,7 @@ class gui_control(object):
|
|||||||
pass
|
pass
|
||||||
self.survey.seisarray = self.seisarray
|
self.survey.seisarray = self.seisarray
|
||||||
self.setConnected2SurveyState(True)
|
self.setConnected2SurveyState(True)
|
||||||
|
self.survey._initiate_SRfiles()
|
||||||
print('Connected Seismic Array to active Survey object.')
|
print('Connected Seismic Array to active Survey object.')
|
||||||
|
|
||||||
def getMaxCPU(self):
|
def getMaxCPU(self):
|
||||||
@ -393,7 +420,7 @@ class gui_control(object):
|
|||||||
if self.checkSurveyState():
|
if self.checkSurveyState():
|
||||||
self.statFigure_left.clf()
|
self.statFigure_left.clf()
|
||||||
self.statFigure_right.clf()
|
self.statFigure_right.clf()
|
||||||
self.mainUI.comboBox.setEnabled(True)
|
self.mainUI.comboBox.setEnabled(False)
|
||||||
self.survey.picked = False
|
self.survey.picked = False
|
||||||
|
|
||||||
def setSeisArrayState(self, state):
|
def setSeisArrayState(self, state):
|
||||||
@ -458,6 +485,9 @@ class gui_control(object):
|
|||||||
QtCore.QObject.connect(self.gen_new_survey.pushButton_src, QtCore.SIGNAL("clicked()"), self.chooseSourcefile)
|
QtCore.QObject.connect(self.gen_new_survey.pushButton_src, QtCore.SIGNAL("clicked()"), self.chooseSourcefile)
|
||||||
QtCore.QObject.connect(self.gen_new_survey.pushButton_obs, QtCore.SIGNAL("clicked()"), self.chooseObsdir)
|
QtCore.QObject.connect(self.gen_new_survey.pushButton_obs, QtCore.SIGNAL("clicked()"), self.chooseObsdir)
|
||||||
|
|
||||||
|
def connectButtons_gen_survey_min(self):
|
||||||
|
QtCore.QObject.connect(self.gen_new_survey_min.pushButton_obs, QtCore.SIGNAL("clicked()"), self.chooseObsdir_min)
|
||||||
|
|
||||||
def connectButtons_gen_seisarray(self):
|
def connectButtons_gen_seisarray(self):
|
||||||
QtCore.QObject.connect(self.gen_new_seisarray.pushButton_rec, QtCore.SIGNAL("clicked()"), self.chooseMeasuredRec)
|
QtCore.QObject.connect(self.gen_new_seisarray.pushButton_rec, QtCore.SIGNAL("clicked()"), self.chooseMeasuredRec)
|
||||||
QtCore.QObject.connect(self.gen_new_seisarray.pushButton_src, QtCore.SIGNAL("clicked()"), self.chooseMeasuredSrc)
|
QtCore.QObject.connect(self.gen_new_seisarray.pushButton_src, QtCore.SIGNAL("clicked()"), self.chooseMeasuredSrc)
|
||||||
@ -481,6 +511,9 @@ class gui_control(object):
|
|||||||
def chooseObsdir(self):
|
def chooseObsdir(self):
|
||||||
self.gen_new_survey.lineEdit_obs.setText(self.browseDir('Choose observation directory.'))
|
self.gen_new_survey.lineEdit_obs.setText(self.browseDir('Choose observation directory.'))
|
||||||
|
|
||||||
|
def chooseObsdir_min(self):
|
||||||
|
self.gen_new_survey_min.lineEdit_obs.setText(self.browseDir('Choose observation directory.'))
|
||||||
|
|
||||||
def openFile(self, name = 'Open'):
|
def openFile(self, name = 'Open'):
|
||||||
dialog = QtGui.QFileDialog()
|
dialog = QtGui.QFileDialog()
|
||||||
dialog.setWindowTitle(name) #not working yet
|
dialog.setWindowTitle(name) #not working yet
|
||||||
|
@ -13,7 +13,7 @@ def picker(shot):
|
|||||||
return picks
|
return picks
|
||||||
|
|
||||||
class Survey(object):
|
class Survey(object):
|
||||||
def __init__(self, path, sourcefile, receiverfile, useDefaultParas=False):
|
def __init__(self, path, sourcefile = None, receiverfile = None, seisArray = None, useDefaultParas=False):
|
||||||
'''
|
'''
|
||||||
The Survey Class contains all shots [class: Seismicshot] of a survey
|
The Survey Class contains all shots [class: Seismicshot] of a survey
|
||||||
as well as the aquisition geometry and the topography.
|
as well as the aquisition geometry and the topography.
|
||||||
@ -24,23 +24,61 @@ class Survey(object):
|
|||||||
creating plots for all shots.
|
creating plots for all shots.
|
||||||
'''
|
'''
|
||||||
self.data = {}
|
self.data = {}
|
||||||
self.seisarray = None
|
self.seisarray = seisArray
|
||||||
self._topography = None
|
self._topography = None
|
||||||
self._recfile = receiverfile
|
self._recfile = receiverfile
|
||||||
self._sourcefile = sourcefile
|
self._sourcefile = sourcefile
|
||||||
self._obsdir = path
|
self._obsdir = path
|
||||||
self._generateSurvey()
|
self._generateSurvey()
|
||||||
self._initiate_fnames()
|
self._initiate_SRfiles()
|
||||||
if useDefaultParas == True:
|
if useDefaultParas == True:
|
||||||
self.setParametersForAllShots()
|
self.setParametersForAllShots()
|
||||||
self._removeAllEmptyTraces()
|
self._removeAllEmptyTraces()
|
||||||
self._updateShots()
|
self._updateShots()
|
||||||
self.picked = False
|
self.picked = False
|
||||||
|
|
||||||
def _initiate_fnames(self):
|
def _coordsFromSeisArray(self):
|
||||||
for shot in self.data.values():
|
self._receiverCoords = self.seisarray.getReceiverCoordinates()
|
||||||
shot.setRecfile(self.getReceiverfile())
|
self._sourceCoords = self.seisarray.getSourceCoordinates()
|
||||||
shot.setSourcefile(self.getSourcefile())
|
|
||||||
|
def _coordsFromFiles(self):
|
||||||
|
self._receiversFromFile()
|
||||||
|
self._sourcesFromFile()
|
||||||
|
|
||||||
|
def _receiversFromFile(self):
|
||||||
|
self._receiverCoords = {}
|
||||||
|
reclist = open(self.getReceiverfile(), 'r').readlines()
|
||||||
|
for line in reclist:
|
||||||
|
line = line.split()
|
||||||
|
traceID = int(line[0])
|
||||||
|
x = float(line[1])
|
||||||
|
y = float(line[2])
|
||||||
|
z = float(line[3])
|
||||||
|
self._receiverCoords[traceID] = (x, y, z)
|
||||||
|
|
||||||
|
def _sourcesFromFile(self):
|
||||||
|
self._sourceCoords = {}
|
||||||
|
reclist = open(self.getSourcefile(), 'r').readlines()
|
||||||
|
for line in reclist:
|
||||||
|
line = line.split()
|
||||||
|
sourceID = int(line[0])
|
||||||
|
x = float(line[1])
|
||||||
|
y = float(line[2])
|
||||||
|
z = float(line[3])
|
||||||
|
self._sourceCoords[sourceID] = (x, y, z)
|
||||||
|
|
||||||
|
def _initiate_SRfiles(self):
|
||||||
|
if self._recfile == None and self._sourcefile == None:
|
||||||
|
if self.seisarray == None:
|
||||||
|
raise RuntimeError('No SeisArray defined. No source or receiver file given.')
|
||||||
|
self._coordsFromSeisArray()
|
||||||
|
else:
|
||||||
|
self._coordsFromFiles()
|
||||||
|
for shotnumber in self.data.keys():
|
||||||
|
shot = self.data[shotnumber]
|
||||||
|
shot.setShotnumber(shotnumber)
|
||||||
|
shot.setReceiverCoords(self._receiverCoords)
|
||||||
|
shot.setSourceCoords(self._sourceCoords[shotnumber])
|
||||||
|
|
||||||
def _generateSurvey(self):
|
def _generateSurvey(self):
|
||||||
from obspy.core import read
|
from obspy.core import read
|
||||||
@ -49,8 +87,8 @@ class Survey(object):
|
|||||||
shotlist = self.getShotlist()
|
shotlist = self.getShotlist()
|
||||||
for shotnumber in shotlist: # loop over data files
|
for shotnumber in shotlist: # loop over data files
|
||||||
# generate filenames and read manual picks to a list
|
# generate filenames and read manual picks to a list
|
||||||
#fileending = '_pickle.dat'
|
fileending = '_pickle.dat'
|
||||||
fileending = '.sg2'
|
#fileending = '.sg2'
|
||||||
obsfile = os.path.join(self._obsdir, str(shotnumber)) + fileending
|
obsfile = os.path.join(self._obsdir, str(shotnumber)) + fileending
|
||||||
if obsfile not in shot_dict.keys():
|
if obsfile not in shot_dict.keys():
|
||||||
shot_dict[shotnumber] = []
|
shot_dict[shotnumber] = []
|
||||||
@ -372,12 +410,17 @@ class Survey(object):
|
|||||||
'''
|
'''
|
||||||
Returns a list of all shotnumbers contained in the set Sourcefile.
|
Returns a list of all shotnumbers contained in the set Sourcefile.
|
||||||
'''
|
'''
|
||||||
|
if self._recfile == None and self._sourcefile == None:
|
||||||
|
if self.seisarray == None:
|
||||||
|
raise RuntimeError('No SeisArray defined. No source or receiver file given.')
|
||||||
|
return self.seisarray.getSourceCoordinates().keys()
|
||||||
|
|
||||||
filename = self.getSourcefile()
|
filename = self.getSourcefile()
|
||||||
srcfile = open(filename, 'r')
|
srcfile = open(filename, 'r')
|
||||||
shotlist = []
|
shotlist = []
|
||||||
for line in srcfile.readlines():
|
for line in srcfile.readlines():
|
||||||
line = line.split()
|
line = line.split()
|
||||||
shotlist.append(line[0])
|
shotlist.append(int(line[0]))
|
||||||
|
|
||||||
return shotlist
|
return shotlist
|
||||||
|
|
||||||
@ -385,6 +428,11 @@ class Survey(object):
|
|||||||
'''
|
'''
|
||||||
Returns a list of all trace IDs contained in the set Receiverfile.
|
Returns a list of all trace IDs contained in the set Receiverfile.
|
||||||
'''
|
'''
|
||||||
|
if self._recfile == None and self._sourcefile == None:
|
||||||
|
if self.seisarray == None:
|
||||||
|
raise RuntimeError('No SeisArray defined. No source or receiver file given.')
|
||||||
|
return self.seisarray.getReceiverCoordinates().keys()
|
||||||
|
|
||||||
filename = self.getReceiverfile()
|
filename = self.getReceiverfile()
|
||||||
recfile = open(filename, 'r')
|
recfile = open(filename, 'r')
|
||||||
reclist = []
|
reclist = []
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file 'asp3d_layout.ui'
|
# Form implementation generated from reading ui file 'asp3d_layout.ui'
|
||||||
#
|
#
|
||||||
# Created: Mon Jun 27 15:18:25 2016
|
# Created: Tue Jun 28 14:40:06 2016
|
||||||
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file 'fmtomo_parameters_layout.ui'
|
# Form implementation generated from reading ui file 'fmtomo_parameters_layout.ui'
|
||||||
#
|
#
|
||||||
# Created: Mon Jun 27 15:18:25 2016
|
# Created: Tue Jun 28 14:40:06 2016
|
||||||
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file 'generate_seisarray_layout.ui'
|
# Form implementation generated from reading ui file 'generate_seisarray_layout.ui'
|
||||||
#
|
#
|
||||||
# Created: Mon Jun 27 15:18:25 2016
|
# Created: Tue Jun 28 14:40:06 2016
|
||||||
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
@ -99,9 +99,9 @@ class Ui_generate_seisarray(object):
|
|||||||
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
|
||||||
"p, li { white-space: pre-wrap; }\n"
|
"p, li { white-space: pre-wrap; }\n"
|
||||||
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load receiver input file. The input file must be in the following format:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load<span style=\" font-weight:600;\"> measured </span>receiver input file. The input file must be in the following format:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, seperated by spaces:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, separated by spaces:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[trace ID (int)] [receiver line ID (int)] [number of the geophone on receiver line (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[trace ID (int)] [receiver line ID (int)] [number of the geophone on receiver line (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
@ -117,7 +117,7 @@ class Ui_generate_seisarray(object):
|
|||||||
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load measured sources input file to improve interpolation precision. The input file must be in the following format:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load measured sources input file to improve interpolation precision. The input file must be in the following format:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, seperated by spaces:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, separated by spaces:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[source ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[source ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
@ -133,7 +133,7 @@ class Ui_generate_seisarray(object):
|
|||||||
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load measured points input file to improve interpolation precision. The input file must be in the following format:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load measured points input file to improve interpolation precision. The input file must be in the following format:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, seperated by spaces:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, separated by spaces:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[point ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[point ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file 'generate_survey_layout.ui'
|
# Form implementation generated from reading ui file 'generate_survey_layout.ui'
|
||||||
#
|
#
|
||||||
# Created: Mon Jun 27 15:18:25 2016
|
# Created: Tue Jun 28 14:40:06 2016
|
||||||
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
@ -68,7 +68,7 @@ class Ui_generate_survey(object):
|
|||||||
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load receiver input file. The input file must be in the following format:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load receiver input file. The input file must be in the following format:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, seperated by spaces:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, separated by spaces:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[trace ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[trace ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
@ -99,7 +99,7 @@ class Ui_generate_survey(object):
|
|||||||
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
"</style></head><body style=\" font-family:\'Sans\'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load sources input file. The input file must be in the following format:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Load sources input file. The input file must be in the following format:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, seperated by spaces:</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Containing in each line, separated by spaces:</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[trace ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">[trace ID (int)] [X (float)] [Y (float)] [Z (float)]</p>\n"
|
||||||
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"></p>\n"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file 'picking_parameters_layout.ui'
|
# Form implementation generated from reading ui file 'picking_parameters_layout.ui'
|
||||||
#
|
#
|
||||||
# Created: Mon Jun 27 15:18:25 2016
|
# Created: Tue Jun 28 14:40:07 2016
|
||||||
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
# by: pyside-uic 0.2.15 running on PySide 1.2.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
@ -23,7 +23,7 @@ class SeisArray(object):
|
|||||||
self._receiverCoords = {}
|
self._receiverCoords = {}
|
||||||
self._measuredReceivers = {}
|
self._measuredReceivers = {}
|
||||||
self._measuredTopo = {}
|
self._measuredTopo = {}
|
||||||
self._sourceLocs = {}
|
self._sourceCoords = {}
|
||||||
self._geophoneNumbers = {}
|
self._geophoneNumbers = {}
|
||||||
self._receiverlist = open(self.recfile, 'r').readlines()
|
self._receiverlist = open(self.recfile, 'r').readlines()
|
||||||
self._generateReceiverlines()
|
self._generateReceiverlines()
|
||||||
@ -79,13 +79,13 @@ class SeisArray(object):
|
|||||||
return self._receiverCoords[traceID][2]
|
return self._receiverCoords[traceID][2]
|
||||||
|
|
||||||
def _getXshot(self, shotnumber):
|
def _getXshot(self, shotnumber):
|
||||||
return self._sourceLocs[shotnumber][0]
|
return self._sourceCoords[shotnumber][0]
|
||||||
|
|
||||||
def _getYshot(self, shotnumber):
|
def _getYshot(self, shotnumber):
|
||||||
return self._sourceLocs[shotnumber][1]
|
return self._sourceCoords[shotnumber][1]
|
||||||
|
|
||||||
def _getZshot(self, shotnumber):
|
def _getZshot(self, shotnumber):
|
||||||
return self._sourceLocs[shotnumber][2]
|
return self._sourceCoords[shotnumber][2]
|
||||||
|
|
||||||
def _getReceiverValue(self, traceID, coordinate):
|
def _getReceiverValue(self, traceID, coordinate):
|
||||||
setCoordinate = {'X': self._getXreceiver,
|
setCoordinate = {'X': self._getXreceiver,
|
||||||
@ -102,8 +102,8 @@ class SeisArray(object):
|
|||||||
def getMeasuredTopo(self):
|
def getMeasuredTopo(self):
|
||||||
return self._measuredTopo
|
return self._measuredTopo
|
||||||
|
|
||||||
def getSourceLocations(self):
|
def getSourceCoordinates(self):
|
||||||
return self._sourceLocs
|
return self._sourceCoords
|
||||||
|
|
||||||
def _setXvalue(self, traceID, value):
|
def _setXvalue(self, traceID, value):
|
||||||
self._checkKey(traceID)
|
self._checkKey(traceID)
|
||||||
@ -209,7 +209,7 @@ class SeisArray(object):
|
|||||||
x = float(line[1])
|
x = float(line[1])
|
||||||
y = float(line[2])
|
y = float(line[2])
|
||||||
z = float(line[3])
|
z = float(line[3])
|
||||||
self._sourceLocs[pointID] = (x, y, z)
|
self._sourceCoords[pointID] = (x, y, z)
|
||||||
|
|
||||||
def interpZcoords4rec(self, method='linear'):
|
def interpZcoords4rec(self, method='linear'):
|
||||||
'''
|
'''
|
||||||
@ -274,10 +274,10 @@ class SeisArray(object):
|
|||||||
x = [];
|
x = [];
|
||||||
y = [];
|
y = [];
|
||||||
z = []
|
z = []
|
||||||
for pointID in self.getSourceLocations().keys():
|
for pointID in self.getSourceCoordinates().keys():
|
||||||
x.append(self.getSourceLocations()[pointID][0])
|
x.append(self.getSourceCoordinates()[pointID][0])
|
||||||
y.append(self.getSourceLocations()[pointID][1])
|
y.append(self.getSourceCoordinates()[pointID][1])
|
||||||
z.append(self.getSourceLocations()[pointID][2])
|
z.append(self.getSourceCoordinates()[pointID][2])
|
||||||
return x, y, z
|
return x, y, z
|
||||||
|
|
||||||
def getAllMeasuredPointsLists(self):
|
def getAllMeasuredPointsLists(self):
|
||||||
@ -457,7 +457,7 @@ class SeisArray(object):
|
|||||||
outfile = open(outfilename, 'w')
|
outfile = open(outfilename, 'w')
|
||||||
|
|
||||||
recx, recy, recz = self.getReceiverLists()
|
recx, recy, recz = self.getReceiverLists()
|
||||||
nsrc = len(self.getSourceLocations())
|
nsrc = len(self.getSourceCoordinates())
|
||||||
outfile.write('%s\n' % (len(zip(recx, recy, recz)) * nsrc))
|
outfile.write('%s\n' % (len(zip(recx, recy, recz)) * nsrc))
|
||||||
|
|
||||||
for index in range(nsrc):
|
for index in range(nsrc):
|
||||||
@ -816,7 +816,7 @@ class SeisArray(object):
|
|||||||
for traceID in self.getReceiverCoordinates().keys():
|
for traceID in self.getReceiverCoordinates().keys():
|
||||||
ax.annotate((' ' + str(traceID)), xy=(self._getXreceiver(traceID), self._getYreceiver(traceID)),
|
ax.annotate((' ' + str(traceID)), xy=(self._getXreceiver(traceID), self._getYreceiver(traceID)),
|
||||||
fontsize='x-small', color='k')
|
fontsize='x-small', color='k')
|
||||||
for shotnumber in self.getSourceLocations().keys():
|
for shotnumber in self.getSourceCoordinates().keys():
|
||||||
ax.annotate((' ' + str(shotnumber)), xy=(self._getXshot(shotnumber), self._getYshot(shotnumber)),
|
ax.annotate((' ' + str(shotnumber)), xy=(self._getXshot(shotnumber), self._getYshot(shotnumber)),
|
||||||
fontsize='x-small', color='b')
|
fontsize='x-small', color='b')
|
||||||
|
|
||||||
@ -994,7 +994,7 @@ class SeisArray(object):
|
|||||||
outfile = open(filename, 'w')
|
outfile = open(filename, 'w')
|
||||||
shotnumbers = []
|
shotnumbers = []
|
||||||
|
|
||||||
for shotnumber in self.getSourceLocations():
|
for shotnumber in self.getSourceCoordinates():
|
||||||
shotnumbers.append(shotnumber)
|
shotnumbers.append(shotnumber)
|
||||||
|
|
||||||
nPoints = len(shotnumbers)
|
nPoints = len(shotnumbers)
|
||||||
|
@ -24,7 +24,6 @@ class SeismicShot(object):
|
|||||||
'''
|
'''
|
||||||
SuperClass for a seismic shot object.
|
SuperClass for a seismic shot object.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, obsfile):
|
def __init__(self, obsfile):
|
||||||
'''
|
'''
|
||||||
Initialize seismic shot object giving an inputfile.
|
Initialize seismic shot object giving an inputfile.
|
||||||
@ -34,8 +33,8 @@ class SeismicShot(object):
|
|||||||
'''
|
'''
|
||||||
self.traces = read(obsfile)
|
self.traces = read(obsfile)
|
||||||
self.renameChannelIDs()
|
self.renameChannelIDs()
|
||||||
self.recCoordlist = None
|
# self.recCoordlist = None
|
||||||
self.srcCoordlist = None
|
# self.srcCoordlist = None
|
||||||
self.traceIDs = None
|
self.traceIDs = None
|
||||||
self.picks = {}
|
self.picks = {}
|
||||||
self.pwindow = {}
|
self.pwindow = {}
|
||||||
@ -55,10 +54,8 @@ class SeismicShot(object):
|
|||||||
|
|
||||||
def removeEmptyTraces(self):
|
def removeEmptyTraces(self):
|
||||||
traceIDs = []
|
traceIDs = []
|
||||||
coordlist = self.getRecCoordlist()
|
|
||||||
removed = []
|
removed = []
|
||||||
for i in range(0, len(coordlist)):
|
traceIDs = self.getReceiverCoords().keys()
|
||||||
traceIDs.append(int(coordlist[i].split()[0]))
|
|
||||||
|
|
||||||
for trace in self.traces:
|
for trace in self.traces:
|
||||||
try:
|
try:
|
||||||
@ -110,14 +107,14 @@ class SeismicShot(object):
|
|||||||
def setTgap(self, tgap):
|
def setTgap(self, tgap):
|
||||||
self.setParameters('tgap', tgap)
|
self.setParameters('tgap', tgap)
|
||||||
|
|
||||||
def setShotnumber(self, shotname):
|
def setShotnumber(self, shotnumber):
|
||||||
self.setParameters('shotname', shotname)
|
self.setParameters('shotnumber', shotnumber)
|
||||||
|
|
||||||
def setRecfile(self, recfile):
|
def setReceiverCoords(self, receiver):
|
||||||
self.setParameters('recfile', recfile)
|
self.setParameters('receiverLoc', receiver)
|
||||||
|
|
||||||
def setSourcefile(self, sourcefile):
|
def setSourceCoords(self, source):
|
||||||
self.setParameters('sourcefile', sourcefile)
|
self.setParameters('sourceLoc', source)
|
||||||
|
|
||||||
def setMethod(self, method):
|
def setMethod(self, method):
|
||||||
self.setParameters('method', method)
|
self.setParameters('method', method)
|
||||||
@ -159,8 +156,14 @@ class SeismicShot(object):
|
|||||||
def getParas(self):
|
def getParas(self):
|
||||||
return self.paras
|
return self.paras
|
||||||
|
|
||||||
def getShotname(self):
|
def getShotnumber(self):
|
||||||
return self.paras['shotname']
|
return self.paras['shotnumber']
|
||||||
|
|
||||||
|
def getSourceCoords(self):
|
||||||
|
return self.paras['sourceLoc']
|
||||||
|
|
||||||
|
def getReceiverCoords(self):
|
||||||
|
return self.paras['receiverLoc']
|
||||||
|
|
||||||
def getCut(self):
|
def getCut(self):
|
||||||
return self.paras['cut']
|
return self.paras['cut']
|
||||||
@ -180,12 +183,6 @@ class SeismicShot(object):
|
|||||||
def getShotnumber(self):
|
def getShotnumber(self):
|
||||||
return self.paras['shotnumber']
|
return self.paras['shotnumber']
|
||||||
|
|
||||||
def getRecfile(self):
|
|
||||||
return self.paras['recfile']
|
|
||||||
|
|
||||||
def getSourcefile(self):
|
|
||||||
return self.paras['sourcefile']
|
|
||||||
|
|
||||||
def getVmin(self):
|
def getVmin(self):
|
||||||
return self.paras['vmin']
|
return self.paras['vmin']
|
||||||
|
|
||||||
@ -237,15 +234,12 @@ class SeismicShot(object):
|
|||||||
|
|
||||||
def getTraceIDlist(self):
|
def getTraceIDlist(self):
|
||||||
'''
|
'''
|
||||||
Returns a list containing the traceIDs read from the receiver inputfile.
|
Returns a list containing the traceIDs.
|
||||||
'''
|
'''
|
||||||
traceIDs = []
|
traceIDs = []
|
||||||
if self.traceIDs == None:
|
if self.traceIDs == None:
|
||||||
recCoordlist = self.getRecCoordlist()
|
traceIDs = self.getReceiverCoords().keys()
|
||||||
for i in range(0, len(recCoordlist)):
|
|
||||||
traceIDs.append(int(recCoordlist[i].split()[0]))
|
|
||||||
self.traceIDs = traceIDs
|
self.traceIDs = traceIDs
|
||||||
|
|
||||||
return self.traceIDs
|
return self.traceIDs
|
||||||
|
|
||||||
def getPickwindow(self, traceID):
|
def getPickwindow(self, traceID):
|
||||||
@ -262,19 +256,19 @@ class SeismicShot(object):
|
|||||||
def getSNRthreshold(self, traceID):
|
def getSNRthreshold(self, traceID):
|
||||||
return self.snrthreshold[traceID]
|
return self.snrthreshold[traceID]
|
||||||
|
|
||||||
def getRecCoordlist(self):
|
# def getRecCoordlist(self):
|
||||||
if self.recCoordlist is None:
|
# if self.recCoordlist is None:
|
||||||
coordlist = open(self.getRecfile(), 'r').readlines()
|
# coordlist = open(self.getRecfile(), 'r').readlines()
|
||||||
# print 'Reading receiver coordinates from %s' %(self.getRecfile())
|
# # print 'Reading receiver coordinates from %s' %(self.getRecfile())
|
||||||
self.recCoordlist = coordlist
|
# self.recCoordlist = coordlist
|
||||||
return self.recCoordlist
|
# return self.recCoordlist
|
||||||
|
|
||||||
def getSrcCoordlist(self):
|
# def getSrcCoordlist(self):
|
||||||
if self.srcCoordlist is None:
|
# if self.srcCoordlist is None:
|
||||||
coordlist = open(self.getSourcefile(), 'r').readlines()
|
# coordlist = open(self.getSourcefile(), 'r').readlines()
|
||||||
# print 'Reading shot coordinates from %s' %(self.getSourcefile())
|
# # print 'Reading shot coordinates from %s' %(self.getSourcefile())
|
||||||
self.srcCoordlist = coordlist
|
# self.srcCoordlist = coordlist
|
||||||
return self.srcCoordlist
|
# return self.srcCoordlist
|
||||||
|
|
||||||
def getTimeArray(self, traceID):
|
def getTimeArray(self, traceID):
|
||||||
return self.timeArray[traceID]
|
return self.timeArray[traceID]
|
||||||
@ -484,13 +478,7 @@ class SeismicShot(object):
|
|||||||
if traceID == 0: # artificial traceID 0 with pick at t = 0
|
if traceID == 0: # artificial traceID 0 with pick at t = 0
|
||||||
return self.getSrcLoc()
|
return self.getSrcLoc()
|
||||||
|
|
||||||
coordlist = self.getRecCoordlist()
|
return self.getReceiverCoords()[traceID]
|
||||||
for i in range(0, len(coordlist)):
|
|
||||||
if int(coordlist[i].split()[0]) == traceID:
|
|
||||||
x = coordlist[i].split()[1]
|
|
||||||
y = coordlist[i].split()[2]
|
|
||||||
z = coordlist[i].split()[3]
|
|
||||||
return float(x), float(y), float(z)
|
|
||||||
|
|
||||||
raise ValueError("traceID %s not found" % traceID)
|
raise ValueError("traceID %s not found" % traceID)
|
||||||
|
|
||||||
@ -499,14 +487,7 @@ class SeismicShot(object):
|
|||||||
Returns the location (x, y, z) of the shot.
|
Returns the location (x, y, z) of the shot.
|
||||||
SOURCE FILE MUST BE SET FIRST, TO BE IMPROVED.
|
SOURCE FILE MUST BE SET FIRST, TO BE IMPROVED.
|
||||||
'''
|
'''
|
||||||
coordlist = self.getSrcCoordlist()
|
return self.getSourceCoords()
|
||||||
for i in range(0, len(coordlist)):
|
|
||||||
if coordlist[i].split()[0] == self.paras['shotnumber']:
|
|
||||||
x = coordlist[i].split()[1]
|
|
||||||
y = coordlist[i].split()[2]
|
|
||||||
z = coordlist[i].split()[3]
|
|
||||||
return float(x), float(y), float(z)
|
|
||||||
# return float(self.getSingleStream(traceID)[0].stats.seg2['SOURCE_LOCATION'])
|
|
||||||
|
|
||||||
def getTraceIDs4Dist(self, distance=0,
|
def getTraceIDs4Dist(self, distance=0,
|
||||||
distancebin=(0, 0)): ########## nur fuer 2D benutzt, 'distance bins' ##########
|
distancebin=(0, 0)): ########## nur fuer 2D benutzt, 'distance bins' ##########
|
||||||
|
Loading…
Reference in New Issue
Block a user