1) Load all of the needed python packages to run this notebook. These include ODM2API, ipython widgets for user interaction, bokeh for interactive plots. ui_utils

In [1]:
import sys
import os
import datetime
import getpass
import utilities.ui_utils as ui_utils
from bokeh.plotting import  figure, show
from IPython.core.display import HTML
from ipywidgets import Layout, HBox
from IPython.display import display
from odm2api.ODMconnection import dbconnection
import odm2api.ODM2.services.readService as odm2
from odm2api.ODM2.models import *
from bokeh.io import output_notebook
from bokeh.models import ColumnDataSource

2) The code below retreives the ODM2 login prompt from ui_utils python code which should be in your utilities folder. This will log directly into SQL.

In [6]:
#print("Enter your ODM2 username") 
container = ui_utils.ODM2LoginPrompt()
container

3) Next we prompt a user for their password.

In [3]:
print("enter your password: ")
p = getpass.getpass()
enter your password: 
········

4) Here we look into the login prompt container. to retrieve the database connection information entered by the user.

5) On the second line, I'm using the ODM2API read service for retrieving result values this should help make retrieving them agnostic to the result type.

In [2]:
session_factory = dbconnection.createConnection('postgresql', container.children[1].value, 
                                                container.children[2].value, 
                                                container.children[0].value, p) 

read = odm2.ReadODM2(session_factory)
DBSession = session_factory.getSession()

6) Next we retreive another UI element for selecting observation actions. Which we will use to filter results. Otherwise the list of results maybe too long.

7) Now we get a UI element for results, for which we would like to display values.

In [3]:
HTML('<style>select, option, dropdown-menu, li, a { width: 50%; !important;}</style>')
actionWidget, awidget = ui_utils.actionWidgetNotPulse(DBSession)
#box = HBox([awidget])
#box.layout.display = 'flex'
#box.layout.align_items = 'stretch'
display(awidget) 
34
In [7]:
#featureaction = 1700
actionid = actionWidget.value
print(actionid)
resultWidget, rwidget = ui_utils.resultWidget(read, actionid)
display(rwidget)
16647

8) Now we create a UI element for entering the dates we would like to filter the time series on.

In [8]:
startdate_enddate_container = ui_utils.startDateEndDateContainer()
startdate_enddate_container

9) Next we read more information about the result, pull the results values for the time frame we specified and create a data dictionary our selection graph can display.

10) Now we create a bokeh (graphing package) ColumnDataSource for our graph, create our plot (also using ui_utils) and display it.

In [13]:
selectedResult = read.getDetailedResultInfo(resultTypeCV = 'Time series coverage',resultID=resultWidget.value)
#resultValues = read.getResultValues(resultid=resultWidget.value, starttime='2016-8-1', 
#                                                 endtime= '2016-8-30')
resultValues = read.getResultValues(resultid=resultWidget.value, starttime=startdate_enddate_container.children[0].value, 
                                                 endtime= startdate_enddate_container.children[1].value)
#print(startdate_enddate_container.children[0].value)
#print(startdate_enddate_container.children[1].value)
data = dict(x=resultValues.ValueDateTime, y= resultValues.DataValue, z=resultValues.ValueID)
#print(data)
In [14]:
s1 = ColumnDataSource(data=data)
plot = ui_utils.selectPlot(s1,selectedResult)
output_notebook()
show(plot)
Loading BokehJS ...
Out[14]:

<Bokeh Notebook handle for In[14]>

11) The code below prints out the selected data points. This can be used for diagnostic purposes and is commented out here.

In [ ]:
# data = zip([s1.data['x'][i] for i in inds],
#    [s1.data['y'][i] for i in inds],
#          [s1.data['z'][i] for i in inds])
# print(data)

12) Next we prompt a user to enter an annotation and annotation code to prompt the user for.

In [10]:
annotationcontainer = ui_utils.annotationContainer()
annotationcontainer
Annoatation : d, Annotation Code: d

13) Using the below drop down list select the data quality code for these records.

In [4]:
dataqualityWidget, qdwidget =ui_utils.dataqualityWidget(DBSession)
qdwidget
#print(qdwidget)
#os.write(1, str(qdwidget))
Bad

14) This creates the actual annotation database record and the associated result value annotations. This links each result value to the annotation.

In [5]:
print(dataqualityWidget.value)
Bad
In [17]:
annotation_type =  DBSession.query(CVAnnotationType).filter_by(Name="Time series result value annotation").one() 
author =  DBSession.query(People).filter_by(PersonFirstName="Miguel").one()
citation =  DBSession.query(Citations).filter_by(CitationID=327).one() 
print(annotation_type.Name)
print(author.PersonFirstName)
print(citation.Title)
tsrvavalueids = []
annotation = Annotations(AnnotationTypeCV=annotation_type.Name,
                           AnnotationCode = annotationcontainer.children[0].value,
                           AnnotationText = annotationcontainer.children[1].value,
                           AnnotationDateTime = datetime.datetime.now(),
                           AnnotationUTCOffset = 0,
                           AnnotationLink = 'test',
                           AnnotatorID = 1,
                           CitationID =327)
print(annotation)
DBSession.add(annotation)
DBSession.commit()
annotationid = annotation.AnnotationID
print(annotation)
for i in inds:
    valueid = s1.data['z'][i]
    tsrvAnnotation = TimeSeriesResultValueAnnotations(ValueID = valueid,
                                                     AnnotationID =annotationid)
    DBSession.add(tsrvAnnotation)
    DBSession.commit()
    tsrvavalueids.append(tsrvAnnotation.BridgeID)
for i in inds:
    valueid = s1.data['z'][i]
    tsrv = DBSession.query(TimeSeriesResultValues).filter_by(ValueID=valueid).one()
    tsrv.QualityCodeCV = dataqualityWidget.value
DBSession.commit()    
Time series result value annotation
Miguel
Lithological Influences on Contemporary and Long-Term Regolith Weathering at the Luquillo Critical Zone Observatory

Buss, H.L., Lara Chapela M., Moore, O.W., Kurtz A.C., Schulz, M.S., White A.F.
<odm2api.ODM2.models.Annotations object at 0x7f03ed866b90>
<odm2api.ODM2.models.Annotations object at 0x7f03ed866b90>

1) This will last block of code will delete the values back out of the database.

In [ ]:
#print(tsrvavalueids)
time_series_values_annotations = DBSession.query(TimeSeriesResultValueAnnotations).filter(
        TimeSeriesResultValueAnnotations.BridgeID.in_(tsrvavalueids))
for time_series_value_annotation in time_series_values_annotations:
    DBSession.delete(time_series_value_annotation)
DBSession.commit()

DBSession.delete(annotation)
DBSession.commit()
In [19]:
print(tsrvavalueids)
[21, 22, 23, 24, 25, 26, 27]
In [ ]: