In [1]:
import urllib2
import xmltodict
import pandas as pd
from datetime import datetime 
from httplib import BadStatusLine
import matplotlib.pyplot as plt
import numpy as np
import requests
import wellapplication as wa
%matplotlib inline

In [2]:
drive = 'E:'
raw_archive_folder = drive + '/PROJECTS/Snake Valley Water/Transducer Data/Raw_data_archive'
folder = raw_archive_folder + '/2016/2016 q2/'
enteredFolder = folder + '/entered/'
checkFolder = folder + '/toCheck/'
wellinfofile = drive + raw_archive_folder + '/well table 2015-03-23.csv'

In [3]:
inputfile = "E:/PROJECTS/Snake Valley Water/Transducer Data/Raw_data_archive/2016/2016 q2/ag13c 2016-08-02.xle"
manualwls = raw_archive_folder + '/All tape measurements.csv'
manual = pd.read_csv(manualwls, index_col="DateTime", engine="python")
barofile = raw_archive_folder + '/baro.csv'
baro = pd.read_csv(barofile,index_col=0, parse_dates=True)
wellinfo = pd.read_csv(folder + '/wellinfo4.csv')

In [14]:
g, drift, wellname = wa.imp_new_well(inputfile, wellinfo, manual, baro)


Well = ag13c
Efficiency = 0.35
Max Drift = 1.0855

In [19]:
df = wa.new_xle_imp(inputfile)
    
jf = wa.jumpfix(df, 'Level', threashold=0.005)
jf['newVal'][-1] > 10


                     Temperature    Level              name  deltaLevel  \
DateTime                                                                  
2016-05-03 12:00:00       12.712  18.6353  ag13c 2016-08-02     -0.0080   
2016-05-03 17:00:00       12.707  18.6251  ag13c 2016-08-02     -0.0099   
2016-05-03 20:00:00       12.707  18.6137  ag13c 2016-08-02     -0.0088   
2016-05-03 23:00:00       12.707  18.5989  ag13c 2016-08-02     -0.0108   
2016-05-04 00:00:00       12.707  18.6042  ag13c 2016-08-02      0.0053   
2016-05-04 03:00:00       12.707  18.6196  ag13c 2016-08-02      0.0067   
2016-05-04 04:00:00       12.706  18.6099  ag13c 2016-08-02     -0.0097   
2016-05-04 05:00:00       12.706  18.6039  ag13c 2016-08-02     -0.0060   
2016-05-04 06:00:00       12.707  18.6117  ag13c 2016-08-02      0.0078   
2016-05-04 07:00:00       12.706  18.6227  ag13c 2016-08-02      0.0110   
2016-05-04 08:00:00       12.707  18.6143  ag13c 2016-08-02     -0.0084   
2016-05-04 09:00:00       12.707  18.6078  ag13c 2016-08-02     -0.0065   
2016-05-04 10:00:00       12.707  18.5997  ag13c 2016-08-02     -0.0081   
2016-05-04 13:00:00       12.706  18.5904  ag13c 2016-08-02     -0.0066   
2016-05-04 14:00:00       12.707  18.5962  ag13c 2016-08-02      0.0058   
2016-05-04 15:00:00       12.706  18.5910  ag13c 2016-08-02     -0.0052   
2016-05-04 16:00:00       12.705  18.5981  ag13c 2016-08-02      0.0071   
2016-05-04 17:00:00       12.706  18.5830  ag13c 2016-08-02     -0.0151   
2016-05-04 19:00:00       12.706  18.5729  ag13c 2016-08-02     -0.0098   
2016-05-04 20:00:00       12.706  18.5559  ag13c 2016-08-02     -0.0170   
2016-05-04 21:00:00       12.706  18.5438  ag13c 2016-08-02     -0.0121   
2016-05-04 22:00:00       12.707  18.5329  ag13c 2016-08-02     -0.0109   
2016-05-04 23:00:00       12.707  18.5183  ag13c 2016-08-02     -0.0146   
2016-05-05 01:00:00       12.707  18.5070  ag13c 2016-08-02     -0.0068   
2016-05-05 03:00:00       12.707  18.5010  ag13c 2016-08-02     -0.0058   
2016-05-05 05:00:00       12.707  18.4887  ag13c 2016-08-02     -0.0089   
2016-05-05 08:00:00       12.707  18.4796  ag13c 2016-08-02     -0.0089   
2016-05-05 09:00:00       12.706  18.4691  ag13c 2016-08-02     -0.0105   
2016-05-05 10:00:00       12.706  18.5088  ag13c 2016-08-02      0.0397   
2016-05-05 12:00:00       12.706  18.5233  ag13c 2016-08-02      0.0152   
...                          ...      ...               ...         ...   
2016-08-01 02:00:00       12.686  13.3468  ag13c 2016-08-02     -0.0068   
2016-08-01 03:00:00       12.686  13.3396  ag13c 2016-08-02     -0.0072   
2016-08-01 04:00:00       12.686  13.3338  ag13c 2016-08-02     -0.0058   
2016-08-01 05:00:00       12.687  13.3032  ag13c 2016-08-02     -0.0306   
2016-08-01 06:00:00       12.687  13.2737  ag13c 2016-08-02     -0.0295   
2016-08-01 07:00:00       12.686  13.2934  ag13c 2016-08-02      0.0197   
2016-08-01 08:00:00       12.686  13.3129  ag13c 2016-08-02      0.0195   
2016-08-01 09:00:00       12.686  13.3078  ag13c 2016-08-02     -0.0051   
2016-08-01 10:00:00       12.686  13.2769  ag13c 2016-08-02     -0.0309   
2016-08-01 11:00:00       12.687  13.2412  ag13c 2016-08-02     -0.0357   
2016-08-01 12:00:00       12.687  13.1951  ag13c 2016-08-02     -0.0461   
2016-08-01 13:00:00       12.686  13.1404  ag13c 2016-08-02     -0.0547   
2016-08-01 14:00:00       12.687  13.0986  ag13c 2016-08-02     -0.0418   
2016-08-01 15:00:00       12.686  13.0515  ag13c 2016-08-02     -0.0471   
2016-08-01 16:00:00       12.687  13.0157  ag13c 2016-08-02     -0.0358   
2016-08-01 17:00:00       12.686  12.9833  ag13c 2016-08-02     -0.0324   
2016-08-01 18:00:00       12.686  12.9464  ag13c 2016-08-02     -0.0369   
2016-08-01 19:00:00       12.687  12.9138  ag13c 2016-08-02     -0.0326   
2016-08-01 20:00:00       12.686  12.8742  ag13c 2016-08-02     -0.0396   
2016-08-01 21:00:00       12.687  12.8352  ag13c 2016-08-02     -0.0390   
2016-08-01 22:00:00       12.687  12.8015  ag13c 2016-08-02     -0.0337   
2016-08-01 23:00:00       12.687  12.7542  ag13c 2016-08-02     -0.0473   
2016-08-02 00:00:00       12.686  12.7180  ag13c 2016-08-02     -0.0362   
2016-08-02 01:00:00       12.686  12.6871  ag13c 2016-08-02     -0.0309   
2016-08-02 02:00:00       12.687  12.6672  ag13c 2016-08-02     -0.0199   
2016-08-02 03:00:00       12.686  12.6518  ag13c 2016-08-02     -0.0154   
2016-08-02 04:00:00       12.686  12.6247  ag13c 2016-08-02     -0.0271   
2016-08-02 05:00:00       12.686  12.5777  ag13c 2016-08-02     -0.0470   
2016-08-02 06:00:00       12.686  12.5428  ag13c 2016-08-02     -0.0349   
2016-08-02 09:00:00       12.686  12.5249  ag13c 2016-08-02     -0.0193   

                      cumul  
DateTime                     
2016-05-03 12:00:00 -0.0080  
2016-05-03 17:00:00 -0.0179  
2016-05-03 20:00:00 -0.0267  
2016-05-03 23:00:00 -0.0375  
2016-05-04 00:00:00 -0.0322  
2016-05-04 03:00:00 -0.0255  
2016-05-04 04:00:00 -0.0352  
2016-05-04 05:00:00 -0.0412  
2016-05-04 06:00:00 -0.0334  
2016-05-04 07:00:00 -0.0224  
2016-05-04 08:00:00 -0.0308  
2016-05-04 09:00:00 -0.0373  
2016-05-04 10:00:00 -0.0454  
2016-05-04 13:00:00 -0.0520  
2016-05-04 14:00:00 -0.0462  
2016-05-04 15:00:00 -0.0514  
2016-05-04 16:00:00 -0.0443  
2016-05-04 17:00:00 -0.0594  
2016-05-04 19:00:00 -0.0692  
2016-05-04 20:00:00 -0.0862  
2016-05-04 21:00:00 -0.0983  
2016-05-04 22:00:00 -0.1092  
2016-05-04 23:00:00 -0.1238  
2016-05-05 01:00:00 -0.1306  
2016-05-05 03:00:00 -0.1364  
2016-05-05 05:00:00 -0.1453  
2016-05-05 08:00:00 -0.1542  
2016-05-05 09:00:00 -0.1647  
2016-05-05 10:00:00 -0.1250  
2016-05-05 12:00:00 -0.1098  
...                     ...  
2016-08-01 02:00:00 -5.1304  
2016-08-01 03:00:00 -5.1376  
2016-08-01 04:00:00 -5.1434  
2016-08-01 05:00:00 -5.1740  
2016-08-01 06:00:00 -5.2035  
2016-08-01 07:00:00 -5.1838  
2016-08-01 08:00:00 -5.1643  
2016-08-01 09:00:00 -5.1694  
2016-08-01 10:00:00 -5.2003  
2016-08-01 11:00:00 -5.2360  
2016-08-01 12:00:00 -5.2821  
2016-08-01 13:00:00 -5.3368  
2016-08-01 14:00:00 -5.3786  
2016-08-01 15:00:00 -5.4257  
2016-08-01 16:00:00 -5.4615  
2016-08-01 17:00:00 -5.4939  
2016-08-01 18:00:00 -5.5308  
2016-08-01 19:00:00 -5.5634  
2016-08-01 20:00:00 -5.6030  
2016-08-01 21:00:00 -5.6420  
2016-08-01 22:00:00 -5.6757  
2016-08-01 23:00:00 -5.7230  
2016-08-02 00:00:00 -5.7592  
2016-08-02 01:00:00 -5.7901  
2016-08-02 02:00:00 -5.8100  
2016-08-02 03:00:00 -5.8254  
2016-08-02 04:00:00 -5.8525  
2016-08-02 05:00:00 -5.8995  
2016-08-02 06:00:00 -5.9344  
2016-08-02 09:00:00 -5.9537  

[1803 rows x 5 columns]
Out[19]:
18.478599999999982

In [12]:
xle = inputfile
xle_df = wa.new_xle_imp(xle)
manual35 = manual[manual['WellID']==35]
manual35['dt'] = pd.to_datetime(manual35.index)
manual_35 = manual35.reset_index()
manual_35.set_index('dt',inplace=True)

fd = wa.fix_drift(xle_df, manual_35, meas='Level', manmeas='MeasuredDTW', outcolname='DriftCorrection')
'DriftCorrection' in list(fd[0].columns)


c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\ipykernel\__main__.py:4: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\pandas\core\indexing.py:296: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self.obj[key] = _infer_fill_value(value)
c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\pandas\core\indexing.py:476: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self.obj[item] = s
Out[12]:
True

In [9]:
manual

In [10]:
test_fix_drift(xle_df, manual)


---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-10-b0f551b1d340> in <module>()
----> 1 test_fix_drift(xle_df, manual)

<ipython-input-9-458384ffb970> in test_fix_drift(xle_df, manual)
      1 def test_fix_drift(xle_df, manual):
----> 2     fd = wa.fix_drift(xle_df, manual, meas='Level', manmeas='MeasuredDTW', outcolname='DriftCorrection')
      3     assert 'DriftCorrection' in list(fd[0].columns)

c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\wellapplication\transport.pyc in fix_drift(well, manualfile, meas, manmeas, outcolname)
    116 
    117     for i in range(len(manualfile)):
--> 118         breakpoints.append(fcl(well, pd.to_datetime(manualfile.index)[i]).name)
    119     breakpoints = sorted(list(set(breakpoints)))
    120 

c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\pandas\util\decorators.pyc in wrapper(*args, **kwargs)
     89                 else:
     90                     kwargs[new_arg_name] = new_arg_value
---> 91             return func(*args, **kwargs)
     92         return wrapper
     93     return _deprecate_kwarg

c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\pandas\tseries\tools.pyc in to_datetime(arg, errors, dayfirst, yearfirst, utc, box, format, exact, coerce, unit, infer_datetime_format)
    424         return _assemble_from_unit_mappings(arg, errors=errors)
    425     elif isinstance(arg, ABCIndexClass):
--> 426         return _convert_listlike(arg, box, format, name=arg.name)
    427     elif is_list_like(arg):
    428         return _convert_listlike(arg, box, format)

c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\pandas\tseries\tools.pyc in _convert_listlike(arg, box, format, name, tz)
    399                     dayfirst=dayfirst,
    400                     yearfirst=yearfirst,
--> 401                     require_iso8601=require_iso8601
    402                 )
    403 

pandas\tslib.pyx in pandas.tslib.array_to_datetime (pandas\tslib.c:45739)()

pandas\tslib.pyx in pandas.tslib.array_to_datetime (pandas\tslib.c:43825)()

pandas\tslib.pyx in pandas.tslib.parse_datetime_string (pandas\tslib.c:34252)()

pandas\tslib.pyx in pandas.tslib._parse_dateabbr_string (pandas\tslib.c:36900)()

c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\_strptime.pyc in _strptime(data_string, format)
    296     """Return a time struct based on the input string and the format string."""
    297     global _TimeRE_cache, _regex_cache
--> 298     with _cache_lock:
    299         if _getlang() != _TimeRE_cache.locale_time.lang:
    300             _TimeRE_cache = TimeRE()

KeyboardInterrupt: 

In [21]:
well = wa.new_xle_imp(inputfile)

In [9]:
baro['Level'] = baro['pw03']

In [10]:
wellbaro = wa.well_baro_merge(well, baro)


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-10-19d6546c88e9> in <module>()
----> 1 wellbaro = wa.well_baro_merge(well, baro)

AttributeError: 'module' object has no attribute 'well_baro_merge'

In [22]:
type(well)


Out[22]:
pandas.core.frame.DataFrame

In [31]:
wellbaro[['corrwl','Level']].plot()


Out[31]:
<matplotlib.axes._subplots.AxesSubplot at 0x20e71be0>

In [20]:
def fix_drift(well, manualfile, meas= 'Level', manmeas =  'MeasuredDTW', outcolname = 'DriftCorrection'): 
    """Remove transducer drift from nonvented transducer data.
    Args:
        well (pandas.core.frame.DataFrame):
            Pandas DataFrame of merged water level and barometric data; index must be datetime
        manualfile (pandas.core.frame.DataFrame):
            Pandas DataFrame of manual measurements
        meas (str):
            name of column in well DataFrame containing transducer data to be corrected
        manmeas (str):
            name of column in manualfile Dataframe containing manual measurement data
        outcolname (str):
            name of column resulting from correction
    Returns:
        wellbarofixed (pandas.core.frame.DataFrame):
            corrected water levels with bp removed
        driftinfo (pandas.core.frame.DataFrame):
            dataframe of correction parameters
    """
    #breakpoints = self.get_breakpoints(wellbaro, manualfile)
    breakpoints = []
    
    for i in range(len(manualfile)):
        breakpoints.append(wa.fcl(wellbaro, pd.to_datetime(manualfile.index)[i]).name)
    breakpoints = sorted(list(set(breakpoints)))

    bracketedwls, drift_features = {},{}
    dtnm = wellbaro.index.name
    manualfile['julian'] = manualfile.index.to_julian_date()
    
    for i in range(len(breakpoints) - 1):
        # Break up pandas dataframe time series into pieces based on timing of manual measurements
        bracketedwls[i] = wellbaro.loc[(wellbaro.index.to_datetime() > breakpoints[i]) & (wellbaro.index.to_datetime() < breakpoints[i + 1])]

        if len(bracketedwls[i]) > 0:
            bracketedwls[i].loc[:, 'julian'] = bracketedwls[i].index.to_julian_date()
            
            last_trans = bracketedwls[i].ix[-1, meas] # last transducer measurment
            first_trans = bracketedwls[i].ix[0, meas] # first transducer measurement
            
            last_man = wa.fcl(manualfile, breakpoints[i + 1]) # first manual measurment
            first_man = wa.fcl(manualfile, breakpoints[i]) # last manual mesurement
            
            # intercept of line = value of first manual measurement
            b = first_man[manmeas] - first_trans
            # slope of line = change in difference between manual and transducer over time
            m = ((last_man[manmeas] - last_trans) - (first_man[manmeas]-first_trans)) / (last_man['julian'] - first_man['julian'])
            # datechange = amount of time between manual measurements
            bracketedwls[i].loc[:, 'datechange'] = bracketedwls[i].ix[:, 'julian'] - bracketedwls[i].ix[0, 'julian']
            
            #bracketedwls[i].loc[:, 'wldiff'] = bracketedwls[i].loc[:, meas] - first_trans
            bracketedwls[i].loc[:, outcolname] = bracketedwls[i][['datechange', meas]].apply(lambda x: x[1] + (m * x[0] + b), 1)
            drift_features[i] = {'begining':first_man, 'end':last_man, 'intercept':b, 'slope':m,
                                'first_meas':first_man[manmeas],'last_meas':last_man[manmeas]}
        else:
            pass
    wellbarofixed = pd.concat(bracketedwls)
    wellbarofixed.reset_index(inplace=True)
    wellbarofixed.set_index(dtnm, inplace=True)
    drift_info = pd.DataFrame(drift_features)
    return wellbarofixed, drift_info

In [5]:
manual35 = manual[manual['WellID']==35]
manual35['dt'] = pd.to_datetime(manual35.index)
manual_35 = manual35.reset_index()
manual_35.set_index('dt',inplace=True)


c:\winpython-64bit-2.7.10.3\python-2.7.10.amd64\lib\site-packages\ipykernel\__main__.py:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  from ipykernel import kernelapp as app

In [21]:
fixed= fix_drift_slope(wellbaro, manual_35, 'Level')[0]

In [165]:
fixed[2]


Out[165]:
[Timestamp('2016-05-03 10:00:00', freq='60T'),
 Timestamp('2016-08-02 09:00:00', freq='60T')]

In [145]:
fixed


Out[145]:
level_0 Temperature Level name pw03 pw10 pw19 integr barometer dbp dwl corrwl
DateTime

In [22]:
x = fixed.index
y = fixed['DriftCorrection']

x1 = manual_35.index
y1 = manual_35['MeasuredDTW']

plt.figure()

plt.plot(x,y)
plt.scatter(x1,y1)
plt.xlim('5/1/2016','8/15/2016')


Out[22]:
(736085.0, 736191.0)

In [43]:
wellbaro['dbp'] = wellbaro.barometer.diff()
wellbaro['dwl'] = wellbaro.Level.diff()

In [49]:
wellbaro['dbp'] = wellbaro.barometer.diff()
wellbaro['dwl'] = wellbaro.Level.diff()
wellbaro['corrwl'] = wellbaro[['dbp','dwl']].apply(lambda x: x[1]-x[0],1).cumsum()

In [107]:
wellbaro['corrwl'].plot()


Out[107]:
<matplotlib.axes._subplots.AxesSubplot at 0x25066908>

In [28]:
def well_baro_merge(wellfile, barofile, sampint=60):
    """Remove barometric pressure from nonvented transducers.
    Args:
        wellfile (pandas.core.frame.DataFrame):
            Pandas DataFrame of water level data labeled 'Level'; index must be datetime
        barofile (pandas.core.frame.DataFrame):
            Pandas DataFrame barometric data labeled 'Level'; index must be datetime
        sampint (int):
            sampling interval in minutes; default 60

    Returns:
        wellbaro (Pandas DataFrame):
           corrected water levels with bp removed
    """

    # resample data to make sample interval consistent
    baro = wa.hourly_resample(barofile, 0, sampint)
    well = wa.hourly_resample(wellfile, 0, sampint)

    # reassign `Level` to reduce ambiguity
    if 'Level' in list(baro.columns):
        baro= baro.rename(columns = {'Level':'barometer'})
    # combine baro and well data for easy calculations, graphing, and manipulation
    wellbaro = pd.merge(well, baro, left_index=True, right_index=True, how='inner')
    
    wellbaro['dbp'] = wellbaro.barometer.diff()
    wellbaro['dwl'] = wellbaro.Level.diff()
    first_well = wellbaro.Level[0]

    wellbaro['corrwl'] = wellbaro[['dbp','dwl']].apply(lambda x: x[1]-x[0],1).cumsum()+first_well
    
    return wellbaro

In [12]:
def baro_drift_correct(wellfile, barofile, manualfile, sampint=60, wellelev=4800, stickup=0):
    """Remove barometric pressure and corrects drift.
    Args:
        wellfile (pandas.core.frame.DataFrame):
            Pandas DataFrame of water level data labeled 'Level'; index must be datetime
        barofile (pandas.core.frame.DataFrame):
            Pandas DataFrame barometric data labeled 'Level'; index must be datetime
        manualfile (pandas.core.frame.DataFrame):
            Pandas DataFrame manual level data in the first column after the index; index must be datetime
        sampint (int):
            sampling interval in minutes; default 60
        wellelev (int):
            site ground surface elevation in feet
        stickup (float):
            offset of measure point from ground in feet

    Returns:
        wellbarofinal (Pandas DataFrame):
           corrected water levels
    """
    # Remove dangling ends
    baroclean = dataendclean(barofile, 'Level')
    wellclean = dataendclean(wellfile, 'Level')

    # resample data to make sample interval consistent
    baro = hourly_resample(baroclean, 0, sampint)
    well = hourly_resample(wellclean, 0, sampint)

    # reassign `Level` to reduce ambiguity
    well['abs_feet_above_levelogger'] = well['Level']
    baro['abs_feet_above_barologger'] = baro['Level']

    # combine baro and well data for easy calculations, graphing, and manipulation
    wellbaro = pd.merge(well, baro, left_index=True, right_index=True, how='inner')

    # subtract barometric pressure from total pressure measured by transducer
    wellbaro['adjusted_levelogger'] = wellbaro['abs_feet_above_levelogger'] - wellbaro['abs_feet_above_barologger']

    breakpoints = []
    for i in range(len(manualfile) + 1):
        breakpoints.append(fcl(wellbaro, manualfile.index.to_datetime()[i - 1]).name)

    last_man_wl, first_man_wl, last_tran_wl, driftlen = [], [], [], []
    bracketedwls = {}
    for i in range(len(manualfile) - 1):
        # Break up time series into pieces based on timing of manual measurements
        bracketedwls[i + 1] = wellbaro.loc[(wellbaro.index.to_datetime() > breakpoints[i + 1]) & (wellbaro.index.to_datetime() < breakpoints[i + 2])]
        # get difference in transducer water measurements
        bracketedwls[i + 1]['diff_wls'] = bracketedwls[i + 1]['abs_feet_above_levelogger'].diff()
        # get difference of each depth to water from initial measurement
        bracketedwls[i + 1].loc[:, 'DeltaLevel'] = bracketedwls[i + 1].loc[:, 'adjusted_levelogger'] - \
                                                   bracketedwls[i + 1].ix[0, 'adjusted_levelogger']
        bracketedwls[i + 1].loc[:, 'MeasuredDTW'] = fcl(manualfile, breakpoints[i + 1])[0] - \
                                                    bracketedwls[i + 1].loc[:,'DeltaLevel']
        last_man_wl.append(fcl(manualfile, breakpoints[i + 2])[0])
        first_man_wl.append(fcl(manualfile, breakpoints[i + 1])[0])
        last_tran_wl.append(
            float(bracketedwls[i + 1].loc[max(bracketedwls[i + 1].index.to_datetime()), 'MeasuredDTW']))
        driftlen.append(len(bracketedwls[i + 1].index))
        bracketedwls[i + 1].loc[:, 'last_diff_int'] = np.round((last_tran_wl[i] - last_man_wl[i]), 4) / np.round(
            driftlen[i] - 1.0, 4)
        bracketedwls[i + 1].loc[:, 'DriftCorrection'] = np.round(
            bracketedwls[i + 1].loc[:, 'last_diff_int'].cumsum() - bracketedwls[i + 1].loc[:, 'last_diff_int'], 4)

    wellbarofixed = pd.concat(bracketedwls)
    wellbarofixed.reset_index(inplace=True)
    wellbarofixed.set_index('DateTime', inplace=True)
    # Get Depth to water below casing
    wellbarofixed.loc[:, 'DTWBelowCasing'] = wellbarofixed['MeasuredDTW'] - wellbarofixed['DriftCorrection']

    # subtract casing height from depth to water below casing
    wellbarofixed.loc[:, 'DTWBelowGroundSurface'] = wellbarofixed.loc[:,
                                                    'DTWBelowCasing'] - stickup  # well riser height

    # subtract depth to water below ground surface from well surface elevation
    wellbarofixed.loc[:, 'WaterElevation'] = wellelev - wellbarofixed.loc[:, 'DTWBelowGroundSurface']

    wellbarofinal = smoother(wellbarofixed, 'WaterElevation')

    return wellbarofinal