From 0659b4f00f4c8f3512707d89fde0d8f4270437e9 Mon Sep 17 00:00:00 2001 From: jkl <sagitta1618@gmail.com> Date: Tue, 17 Oct 2023 14:49:14 +0200 Subject: [PATCH] Add simple 2D inversion using ResIPy to OhmPi --- dev/test_inv.py | 12 ++++++ html/index-mqtt.html | 1 - ohmpi/ohmpi.py | 98 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 dev/test_inv.py diff --git a/dev/test_inv.py b/dev/test_inv.py new file mode 100644 index 00000000..b212d585 --- /dev/null +++ b/dev/test_inv.py @@ -0,0 +1,12 @@ + +# +from ohmpi.utils import change_config +change_config('../configs/config_mb_2023.py', verbose=False) + +from ohmpi.ohmpi import OhmPi +k = OhmPi() +k.run_inversion(['measurement_20220206T194552.csv']) + + +# restore default config +change_config('../configs/config_default.py', verbose=False) diff --git a/html/index-mqtt.html b/html/index-mqtt.html index 070d4fe1..7c121aea 100755 --- a/html/index-mqtt.html +++ b/html/index-mqtt.html @@ -59,7 +59,6 @@ <!-- Additional buttons --> <button id="downloadBtn" type="button" class="btn btn-primary">Download data</button> - <!-- <button id="invertBtn" type="button" class="btn btn-primary">Invert</button> --> <a id="download"></a> <!-- Modal for configuration --> diff --git a/ohmpi/ohmpi.py b/ohmpi/ohmpi.py index 905acb8e..2035c81d 100644 --- a/ohmpi/ohmpi.py +++ b/ohmpi/ohmpi.py @@ -917,6 +917,104 @@ class OhmPi(object): return status + def run_inversion(self, survey_names=[], elec_spacing=1, **kwargs): + """Run a simple 2D inversion using ResIPy. + + Parameters + ---------- + survey_names : list of string, optional + Filenames of the survey to be inverted (including extension). + elec_spacing : float (optional) + Electrode spacing in meters. We assume same electrode spacing everywhere. + kwargs : optional + Additiona keyword arguments passed to `resipy.Project.invert()`. For instance + `reg_mode` == 0 for batch inversion, `reg_mode == 2` for time-lapse inversion. + See ResIPy document for more information on options available + (https://hkex.gitlab.io/resipy/). + + Returns + ------- + xzv : list of dict + Each dictionnary with key 'x' and 'z' for the centroid of the elements and 'v' + for the values in resistivity of the elements. + """ + # check if we have any files to be inverted + if len(survey_names) == 0: + self.exec_logger('No file to invert') + return [] + + # check if user didn't provide a single string instead of a list + if isinstance(survey_names, str): + survey_names = [survey_names] + + # check kwargs for reg_mode + if 'reg_mode' in kwargs: + reg_mode = kwargs['reg_mode'] + else: + reg_mode = 0 + kwargs['reg_mode'] = 0 + + pdir = os.path.dirname(__file__) + # import resipy if available + try: + import pandas as pd + import sys + sys.path.append(os.path.join(pdir, '../../resipy/src/')) + from resipy import Project + except Exception as e: + self.exec_logger.error('Cannot import ResIPy or Pandas, error: ' + str(e)) + return [] + + # get absolule filename + fnames = [] + for survey_name in survey_names: + fname = os.path.join(pdir, '../data', survey_name) + if os.path.exists(fname): + fnames.append(fname) + else: + self.exec_logger.warning(fname + ' not found') + + # define a parser for the "ohmpi" format + def ohmpiParser(fname): + df = pd.read_csv(fname) + df = df.rename(columns={'A':'a', 'B':'b', 'M':'m', 'N':'n'}) + df['vp'] = df['Vmn [mV]'] + df['i'] = df['I [mA]'] + df['resist'] = df['vp']/df['i'] + df['ip'] = np.nan + emax = np.max(df[['a', 'b', 'm', 'n']].values) + elec = np.zeros((emax, 3)) + elec[:, 0] = np.arange(emax) * elec_spacing + return elec, df[['a','b','m','n','vp','i','resist','ip']] + + # run inversion + self.exec_logger.info('ResIPy: import surveys') + k = Project(typ='R2') # invert in a temporary directory that will be erased afterwards + if len(survey_names) == 1: + k.createSurvey(fnames[0], parser=ohmpiParser) + elif len(survey_names) > 0 and reg_mode == 0: + k.createBatchSurvey(fnames, parser=ohmpiParser) + elif len(survey_names) > 0 and reg_mode > 0: + k.createTimeLapseSurvey(fnames, parser=ohmpiParser) + self.exec_logger.info('ResIPy: generate mesh') + k.createMesh('trian') + self.exec_logger.info('ResIPy: invert survey') + k.invert(param=kwargs) + + # read data + self.exec_logger.info('Reading inverted surveys') + k.getResults() + xzv = [] + for m in k.meshResults: + df = m.df + xzv.append({ + 'x': df['X'].values.tolist(), + 'z': df['Z'].values.tolist(), + 'rho': df['Resistivity(ohm.m)'].values.tolist(), + }) + + return xzv + # Properties @property def sequence(self): -- GitLab