From 9e3f3b29d2b974ad0474dc438857c057a72ad316 Mon Sep 17 00:00:00 2001 From: Marcel Paffrath Date: Tue, 28 Jun 2016 14:57:48 +0200 Subject: [PATCH] changed general structure of seisarray and survey. survey object can now be generated by using a seismic array (also in GUI). --- pylot/core/active/ActiveSeismoPick3D_GUI.py | 43 ++++++++-- pylot/core/active/activeSeismoPick.py | 68 ++++++++++++--- pylot/core/active/asp3d_layout.py | 2 +- pylot/core/active/fmtomo_parameters_layout.py | 2 +- .../core/active/generate_seisarray_layout.py | 10 +-- pylot/core/active/generate_survey_layout.py | 6 +- .../core/active/picking_parameters_layout.py | 2 +- pylot/core/active/seismicArrayPreparation.py | 28 +++--- pylot/core/active/seismicshot.py | 85 +++++++------------ 9 files changed, 154 insertions(+), 92 deletions(-) diff --git a/pylot/core/active/ActiveSeismoPick3D_GUI.py b/pylot/core/active/ActiveSeismoPick3D_GUI.py index cf704f02..b6a48568 100755 --- a/pylot/core/active/ActiveSeismoPick3D_GUI.py +++ b/pylot/core/active/ActiveSeismoPick3D_GUI.py @@ -9,6 +9,7 @@ from PySide import QtCore, QtGui, QtCore from asp3d_layout import * from fmtomo_parameters_layout import * from generate_survey_layout import * +from generate_survey_layout_minimal import * from generate_seisarray_layout import * from picking_parameters_layout import * from pylot.core.active import activeSeismoPick, surveyUtils, fmtomoUtils, seismicArrayPreparation @@ -85,6 +86,34 @@ class gui_control(object): if self.checkSurveyState(): if not self.continueDialogExists('Survey'): 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) ui = Ui_generate_survey() ui.setupUi(qdialog) @@ -96,11 +125,8 @@ class gui_control(object): obsdir = self.gen_new_survey.lineEdit_obs.text() self.survey = activeSeismoPick.Survey(obsdir, srcfile, recfile, 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) + return True def addArrayPlot(self): self.seisArrayFigure = Figure() @@ -182,6 +208,7 @@ class gui_control(object): pass self.survey.seisarray = self.seisarray self.setConnected2SurveyState(True) + self.survey._initiate_SRfiles() print('Connected Seismic Array to active Survey object.') def getMaxCPU(self): @@ -393,7 +420,7 @@ class gui_control(object): if self.checkSurveyState(): self.statFigure_left.clf() self.statFigure_right.clf() - self.mainUI.comboBox.setEnabled(True) + self.mainUI.comboBox.setEnabled(False) self.survey.picked = False 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_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): 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) @@ -481,6 +511,9 @@ class gui_control(object): def chooseObsdir(self): 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'): dialog = QtGui.QFileDialog() dialog.setWindowTitle(name) #not working yet diff --git a/pylot/core/active/activeSeismoPick.py b/pylot/core/active/activeSeismoPick.py index b2815192..541e8e33 100644 --- a/pylot/core/active/activeSeismoPick.py +++ b/pylot/core/active/activeSeismoPick.py @@ -13,7 +13,7 @@ def picker(shot): return picks 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 as well as the aquisition geometry and the topography. @@ -24,23 +24,61 @@ class Survey(object): creating plots for all shots. ''' self.data = {} - self.seisarray = None + self.seisarray = seisArray self._topography = None self._recfile = receiverfile self._sourcefile = sourcefile self._obsdir = path self._generateSurvey() - self._initiate_fnames() + self._initiate_SRfiles() if useDefaultParas == True: self.setParametersForAllShots() self._removeAllEmptyTraces() self._updateShots() self.picked = False - def _initiate_fnames(self): - for shot in self.data.values(): - shot.setRecfile(self.getReceiverfile()) - shot.setSourcefile(self.getSourcefile()) + def _coordsFromSeisArray(self): + self._receiverCoords = self.seisarray.getReceiverCoordinates() + self._sourceCoords = self.seisarray.getSourceCoordinates() + + 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): from obspy.core import read @@ -49,8 +87,8 @@ class Survey(object): shotlist = self.getShotlist() for shotnumber in shotlist: # loop over data files # generate filenames and read manual picks to a list - #fileending = '_pickle.dat' - fileending = '.sg2' + fileending = '_pickle.dat' + #fileending = '.sg2' obsfile = os.path.join(self._obsdir, str(shotnumber)) + fileending if obsfile not in shot_dict.keys(): shot_dict[shotnumber] = [] @@ -372,12 +410,17 @@ class Survey(object): ''' 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() srcfile = open(filename, 'r') shotlist = [] for line in srcfile.readlines(): line = line.split() - shotlist.append(line[0]) + shotlist.append(int(line[0])) return shotlist @@ -385,6 +428,11 @@ class Survey(object): ''' 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() recfile = open(filename, 'r') reclist = [] diff --git a/pylot/core/active/asp3d_layout.py b/pylot/core/active/asp3d_layout.py index fe85b039..a1830674 100644 --- a/pylot/core/active/asp3d_layout.py +++ b/pylot/core/active/asp3d_layout.py @@ -2,7 +2,7 @@ # 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 # # WARNING! All changes made in this file will be lost! diff --git a/pylot/core/active/fmtomo_parameters_layout.py b/pylot/core/active/fmtomo_parameters_layout.py index 9ba8f5ec..1c11112b 100644 --- a/pylot/core/active/fmtomo_parameters_layout.py +++ b/pylot/core/active/fmtomo_parameters_layout.py @@ -2,7 +2,7 @@ # 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 # # WARNING! All changes made in this file will be lost! diff --git a/pylot/core/active/generate_seisarray_layout.py b/pylot/core/active/generate_seisarray_layout.py index be785a97..0d6d75e1 100644 --- a/pylot/core/active/generate_seisarray_layout.py +++ b/pylot/core/active/generate_seisarray_layout.py @@ -2,7 +2,7 @@ # 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 # # WARNING! All changes made in this file will be lost! @@ -99,9 +99,9 @@ class Ui_generate_seisarray(object): "\n" -"

Load receiver input file. The input file must be in the following format:

\n" +"

Load measured receiver input file. The input file must be in the following format:

\n" "

\n" -"

Containing in each line, seperated by spaces:

\n" +"

Containing in each line, separated by spaces:

\n" "

\n" "

[trace ID (int)] [receiver line ID (int)] [number of the geophone on receiver line (int)] [X (float)] [Y (float)] [Z (float)]

\n" "

\n" @@ -117,7 +117,7 @@ class Ui_generate_seisarray(object): "\n" "

Load measured sources input file to improve interpolation precision. The input file must be in the following format:

\n" "

\n" -"

Containing in each line, seperated by spaces:

\n" +"

Containing in each line, separated by spaces:

\n" "

\n" "

[source ID (int)] [X (float)] [Y (float)] [Z (float)]

\n" "

\n" @@ -133,7 +133,7 @@ class Ui_generate_seisarray(object): "\n" "

Load measured points input file to improve interpolation precision. The input file must be in the following format:

\n" "

\n" -"

Containing in each line, seperated by spaces:

\n" +"

Containing in each line, separated by spaces:

\n" "

\n" "

[point ID (int)] [X (float)] [Y (float)] [Z (float)]

\n" "

\n" diff --git a/pylot/core/active/generate_survey_layout.py b/pylot/core/active/generate_survey_layout.py index f2c8c992..ad197771 100644 --- a/pylot/core/active/generate_survey_layout.py +++ b/pylot/core/active/generate_survey_layout.py @@ -2,7 +2,7 @@ # 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 # # WARNING! All changes made in this file will be lost! @@ -68,7 +68,7 @@ class Ui_generate_survey(object): "\n" "

Load receiver input file. The input file must be in the following format:

\n" "

\n" -"

Containing in each line, seperated by spaces:

\n" +"

Containing in each line, separated by spaces:

\n" "

\n" "

[trace ID (int)] [X (float)] [Y (float)] [Z (float)]

\n" "

\n" @@ -99,7 +99,7 @@ class Ui_generate_survey(object): "\n" "

Load sources input file. The input file must be in the following format:

\n" "

\n" -"

Containing in each line, seperated by spaces:

\n" +"

Containing in each line, separated by spaces:

\n" "

\n" "

[trace ID (int)] [X (float)] [Y (float)] [Z (float)]

\n" "

\n" diff --git a/pylot/core/active/picking_parameters_layout.py b/pylot/core/active/picking_parameters_layout.py index eb6c87eb..d3208eab 100644 --- a/pylot/core/active/picking_parameters_layout.py +++ b/pylot/core/active/picking_parameters_layout.py @@ -2,7 +2,7 @@ # 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 # # WARNING! All changes made in this file will be lost! diff --git a/pylot/core/active/seismicArrayPreparation.py b/pylot/core/active/seismicArrayPreparation.py index 84372993..ba391bb0 100644 --- a/pylot/core/active/seismicArrayPreparation.py +++ b/pylot/core/active/seismicArrayPreparation.py @@ -23,7 +23,7 @@ class SeisArray(object): self._receiverCoords = {} self._measuredReceivers = {} self._measuredTopo = {} - self._sourceLocs = {} + self._sourceCoords = {} self._geophoneNumbers = {} self._receiverlist = open(self.recfile, 'r').readlines() self._generateReceiverlines() @@ -79,13 +79,13 @@ class SeisArray(object): return self._receiverCoords[traceID][2] def _getXshot(self, shotnumber): - return self._sourceLocs[shotnumber][0] + return self._sourceCoords[shotnumber][0] def _getYshot(self, shotnumber): - return self._sourceLocs[shotnumber][1] + return self._sourceCoords[shotnumber][1] def _getZshot(self, shotnumber): - return self._sourceLocs[shotnumber][2] + return self._sourceCoords[shotnumber][2] def _getReceiverValue(self, traceID, coordinate): setCoordinate = {'X': self._getXreceiver, @@ -102,8 +102,8 @@ class SeisArray(object): def getMeasuredTopo(self): return self._measuredTopo - def getSourceLocations(self): - return self._sourceLocs + def getSourceCoordinates(self): + return self._sourceCoords def _setXvalue(self, traceID, value): self._checkKey(traceID) @@ -209,7 +209,7 @@ class SeisArray(object): x = float(line[1]) y = float(line[2]) z = float(line[3]) - self._sourceLocs[pointID] = (x, y, z) + self._sourceCoords[pointID] = (x, y, z) def interpZcoords4rec(self, method='linear'): ''' @@ -274,10 +274,10 @@ class SeisArray(object): x = []; y = []; z = [] - for pointID in self.getSourceLocations().keys(): - x.append(self.getSourceLocations()[pointID][0]) - y.append(self.getSourceLocations()[pointID][1]) - z.append(self.getSourceLocations()[pointID][2]) + for pointID in self.getSourceCoordinates().keys(): + x.append(self.getSourceCoordinates()[pointID][0]) + y.append(self.getSourceCoordinates()[pointID][1]) + z.append(self.getSourceCoordinates()[pointID][2]) return x, y, z def getAllMeasuredPointsLists(self): @@ -457,7 +457,7 @@ class SeisArray(object): outfile = open(outfilename, 'w') recx, recy, recz = self.getReceiverLists() - nsrc = len(self.getSourceLocations()) + nsrc = len(self.getSourceCoordinates()) outfile.write('%s\n' % (len(zip(recx, recy, recz)) * nsrc)) for index in range(nsrc): @@ -816,7 +816,7 @@ class SeisArray(object): for traceID in self.getReceiverCoordinates().keys(): ax.annotate((' ' + str(traceID)), xy=(self._getXreceiver(traceID), self._getYreceiver(traceID)), 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)), fontsize='x-small', color='b') @@ -994,7 +994,7 @@ class SeisArray(object): outfile = open(filename, 'w') shotnumbers = [] - for shotnumber in self.getSourceLocations(): + for shotnumber in self.getSourceCoordinates(): shotnumbers.append(shotnumber) nPoints = len(shotnumbers) diff --git a/pylot/core/active/seismicshot.py b/pylot/core/active/seismicshot.py index bc51b4b4..4f42fade 100644 --- a/pylot/core/active/seismicshot.py +++ b/pylot/core/active/seismicshot.py @@ -24,7 +24,6 @@ class SeismicShot(object): ''' SuperClass for a seismic shot object. ''' - def __init__(self, obsfile): ''' Initialize seismic shot object giving an inputfile. @@ -34,8 +33,8 @@ class SeismicShot(object): ''' self.traces = read(obsfile) self.renameChannelIDs() - self.recCoordlist = None - self.srcCoordlist = None + # self.recCoordlist = None + # self.srcCoordlist = None self.traceIDs = None self.picks = {} self.pwindow = {} @@ -55,10 +54,8 @@ class SeismicShot(object): def removeEmptyTraces(self): traceIDs = [] - coordlist = self.getRecCoordlist() removed = [] - for i in range(0, len(coordlist)): - traceIDs.append(int(coordlist[i].split()[0])) + traceIDs = self.getReceiverCoords().keys() for trace in self.traces: try: @@ -110,14 +107,14 @@ class SeismicShot(object): def setTgap(self, tgap): self.setParameters('tgap', tgap) - def setShotnumber(self, shotname): - self.setParameters('shotname', shotname) + def setShotnumber(self, shotnumber): + self.setParameters('shotnumber', shotnumber) - def setRecfile(self, recfile): - self.setParameters('recfile', recfile) + def setReceiverCoords(self, receiver): + self.setParameters('receiverLoc', receiver) - def setSourcefile(self, sourcefile): - self.setParameters('sourcefile', sourcefile) + def setSourceCoords(self, source): + self.setParameters('sourceLoc', source) def setMethod(self, method): self.setParameters('method', method) @@ -159,8 +156,14 @@ class SeismicShot(object): def getParas(self): return self.paras - def getShotname(self): - return self.paras['shotname'] + def getShotnumber(self): + return self.paras['shotnumber'] + + def getSourceCoords(self): + return self.paras['sourceLoc'] + + def getReceiverCoords(self): + return self.paras['receiverLoc'] def getCut(self): return self.paras['cut'] @@ -180,12 +183,6 @@ class SeismicShot(object): def getShotnumber(self): return self.paras['shotnumber'] - def getRecfile(self): - return self.paras['recfile'] - - def getSourcefile(self): - return self.paras['sourcefile'] - def getVmin(self): return self.paras['vmin'] @@ -237,15 +234,12 @@ class SeismicShot(object): def getTraceIDlist(self): ''' - Returns a list containing the traceIDs read from the receiver inputfile. + Returns a list containing the traceIDs. ''' traceIDs = [] if self.traceIDs == None: - recCoordlist = self.getRecCoordlist() - for i in range(0, len(recCoordlist)): - traceIDs.append(int(recCoordlist[i].split()[0])) + traceIDs = self.getReceiverCoords().keys() self.traceIDs = traceIDs - return self.traceIDs def getPickwindow(self, traceID): @@ -262,19 +256,19 @@ class SeismicShot(object): def getSNRthreshold(self, traceID): return self.snrthreshold[traceID] - def getRecCoordlist(self): - if self.recCoordlist is None: - coordlist = open(self.getRecfile(), 'r').readlines() - # print 'Reading receiver coordinates from %s' %(self.getRecfile()) - self.recCoordlist = coordlist - return self.recCoordlist + # def getRecCoordlist(self): + # if self.recCoordlist is None: + # coordlist = open(self.getRecfile(), 'r').readlines() + # # print 'Reading receiver coordinates from %s' %(self.getRecfile()) + # self.recCoordlist = coordlist + # return self.recCoordlist - def getSrcCoordlist(self): - if self.srcCoordlist is None: - coordlist = open(self.getSourcefile(), 'r').readlines() - # print 'Reading shot coordinates from %s' %(self.getSourcefile()) - self.srcCoordlist = coordlist - return self.srcCoordlist + # def getSrcCoordlist(self): + # if self.srcCoordlist is None: + # coordlist = open(self.getSourcefile(), 'r').readlines() + # # print 'Reading shot coordinates from %s' %(self.getSourcefile()) + # self.srcCoordlist = coordlist + # return self.srcCoordlist def getTimeArray(self, traceID): return self.timeArray[traceID] @@ -484,13 +478,7 @@ class SeismicShot(object): if traceID == 0: # artificial traceID 0 with pick at t = 0 return self.getSrcLoc() - coordlist = self.getRecCoordlist() - 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) + return self.getReceiverCoords()[traceID] raise ValueError("traceID %s not found" % traceID) @@ -499,14 +487,7 @@ class SeismicShot(object): Returns the location (x, y, z) of the shot. SOURCE FILE MUST BE SET FIRST, TO BE IMPROVED. ''' - coordlist = self.getSrcCoordlist() - 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']) + return self.getSourceCoords() def getTraceIDs4Dist(self, distance=0, distancebin=(0, 0)): ########## nur fuer 2D benutzt, 'distance bins' ##########