aboutsummaryrefslogtreecommitdiff
path: root/wqflask/utility
diff options
context:
space:
mode:
Diffstat (limited to 'wqflask/utility')
-rw-r--r--wqflask/utility/Plot.py251
-rw-r--r--wqflask/utility/TDCell.py6
-rw-r--r--wqflask/utility/THCell.py8
-rw-r--r--wqflask/utility/__init__.py14
-rw-r--r--wqflask/utility/after.py1
-rw-r--r--wqflask/utility/authentication_tools.py1
-rw-r--r--wqflask/utility/benchmark.py16
-rw-r--r--wqflask/utility/chunks.py2
-rw-r--r--wqflask/utility/corestats.py9
-rw-r--r--wqflask/utility/elasticsearch_tools.py19
-rw-r--r--wqflask/utility/external.py3
-rw-r--r--wqflask/utility/gen_geno_ob.py35
-rw-r--r--wqflask/utility/genofile_parser.py153
-rw-r--r--wqflask/utility/helper_functions.py61
-rw-r--r--wqflask/utility/logger.py38
-rw-r--r--wqflask/utility/pillow_utils.py6
-rw-r--r--wqflask/utility/redis_tools.py9
-rw-r--r--wqflask/utility/startup_config.py15
-rw-r--r--wqflask/utility/svg.py723
-rw-r--r--wqflask/utility/temp_data.py5
-rw-r--r--wqflask/utility/tools.py148
-rw-r--r--wqflask/utility/type_checking.py11
-rw-r--r--wqflask/utility/webqtlUtil.py65
23 files changed, 891 insertions, 708 deletions
diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py
index 61f408d2..9b2c6735 100644
--- a/wqflask/utility/Plot.py
+++ b/wqflask/utility/Plot.py
@@ -34,7 +34,7 @@ import utility.corestats as corestats
from base import webqtlConfig
from utility.pillow_utils import draw_rotated_text
import utility.logger
-logger = utility.logger.getLogger(__name__ )
+logger = utility.logger.getLogger(__name__)
# ---- Define common colours ---- #
BLUE = ImageColor.getrgb("blue")
@@ -47,6 +47,7 @@ COUR_FILE = "./wqflask/static/fonts/courbd.ttf"
TAHOMA_FILE = "./wqflask/static/fonts/tahoma.ttf"
# ---- END: FONT FILES ---- #
+
def cformat(d, rank=0):
'custom string format'
strD = "%2.6f" % d
@@ -68,22 +69,24 @@ def cformat(d, rank=0):
strD = '0.0'
return strD
+
def frange(start, end=None, inc=1.0):
"A faster range-like function that does accept float increments..."
if end == None:
end = start + 0.0
start = 0.0
else:
- start += 0.0 # force it to be a float
+ start += 0.0 # force it to be a float
count = int((end - start) / inc)
if start + count * inc != end:
- # Need to adjust the count. AFAICT, it always comes up one short.
+ # Need to adjust the count. AFAICT, it always comes up one short.
count += 1
L = [start] * count
for i in range(1, count):
L[i] = start + i * inc
return L
+
def find_outliers(vals):
"""Calculates the upper and lower bounds of a set of sample/case values
@@ -119,154 +122,163 @@ def find_outliers(vals):
# parameter: data is either object returned by reaper permutation function (called by MarkerRegressionPage.py)
# or the first object returned by direct (pair-scan) permu function (called by DirectPlotPage.py)
-def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1):
+
+
+def plotBar(canvas, data, barColor=BLUE, axesColor=BLACK, labelColor=BLACK, XLabel=None, YLabel=None, title=None, offset=(60, 20, 40, 40), zoom=1):
im_drawer = ImageDraw.Draw(canvas)
xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset
plotWidth = canvas.size[0] - xLeftOffset - xRightOffset
plotHeight = canvas.size[1] - yTopOffset - yBottomOffset
- if plotHeight<=0 or plotWidth<=0:
- return
+ if plotHeight <= 0 or plotWidth <= 0:
+ return
if len(data) < 2:
- return
+ return
max_D = max(data)
min_D = min(data)
- #add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong
- if max_D == float('inf') or max_D>webqtlConfig.MAXLRS:
- max_D=webqtlConfig.MAXLRS #maximum LRS value
+ # add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong
+ if max_D == float('inf') or max_D > webqtlConfig.MAXLRS:
+ max_D = webqtlConfig.MAXLRS # maximum LRS value
xLow, xTop, stepX = detScale(min_D, max_D)
- #reduce data
- #ZS: Used to determine number of bins for permutation output
- step = ceil((xTop-xLow)/50.0)
+ # reduce data
+ # ZS: Used to determine number of bins for permutation output
+ step = ceil((xTop - xLow) / 50.0)
j = xLow
dataXY = []
Count = []
while j <= xTop:
- dataXY.append(j)
- Count.append(0)
- j += step
+ dataXY.append(j)
+ Count.append(0)
+ j += step
for i, item in enumerate(data):
- if item == float('inf') or item>webqtlConfig.MAXLRS:
- item = webqtlConfig.MAXLRS #maximum LRS value
- j = int((item-xLow)/step)
- Count[j] += 1
+ if item == float('inf') or item > webqtlConfig.MAXLRS:
+ item = webqtlConfig.MAXLRS # maximum LRS value
+ j = int((item - xLow) / step)
+ Count[j] += 1
- yLow, yTop, stepY=detScale(0, max(Count))
+ yLow, yTop, stepY = detScale(0, max(Count))
- #draw data
- xScale = plotWidth/(xTop-xLow)
- yScale = plotHeight/(yTop-yLow)
- barWidth = xScale*step
+ # draw data
+ xScale = plotWidth / (xTop - xLow)
+ yScale = plotHeight / (yTop - yLow)
+ barWidth = xScale * step
for i, count in enumerate(Count):
- if count:
- xc = (dataXY[i]-xLow)*xScale+xLeftOffset
- yc =-(count-yLow)*yScale+yTopOffset+plotHeight
- im_drawer.rectangle(
- xy=((xc+2, yc), (xc+barWidth-2, yTopOffset+plotHeight)),
- outline=barColor, fill=barColor)
-
- #draw drawing region
+ if count:
+ xc = (dataXY[i] - xLow) * xScale + xLeftOffset
+ yc = -(count - yLow) * yScale + yTopOffset + plotHeight
+ im_drawer.rectangle(
+ xy=((xc + 2, yc), (xc + barWidth - 2, yTopOffset + plotHeight)),
+ outline=barColor, fill=barColor)
+
+ # draw drawing region
im_drawer.rectangle(
- xy=((xLeftOffset, yTopOffset), (xLeftOffset+plotWidth, yTopOffset+plotHeight))
+ xy=((xLeftOffset, yTopOffset),
+ (xLeftOffset + plotWidth, yTopOffset + plotHeight))
)
- #draw scale
- scaleFont=ImageFont.truetype(font=COUR_FILE, size=11)
- x=xLow
- for i in range(int(stepX)+1):
- xc=xLeftOffset+(x-xLow)*xScale
- im_drawer.line(
- xy=((xc, yTopOffset+plotHeight), (xc, yTopOffset+plotHeight+5)),
- fill=axesColor)
- strX = cformat(d=x, rank=0)
- im_drawer.text(
- text=strX,
- xy=(xc-im_drawer.textsize(strX, font=scaleFont)[0]/2,
- yTopOffset+plotHeight+14), font=scaleFont)
- x+= (xTop - xLow)/stepX
-
- y=yLow
- for i in range(int(stepY)+1):
- yc=yTopOffset+plotHeight-(y-yLow)*yScale
- im_drawer.line(xy=((xLeftOffset, yc), (xLeftOffset-5, yc)), fill=axesColor)
- strY = "%d" %y
- im_drawer.text(
- text=strY,
- xy=(xLeftOffset-im_drawer.textsize(strY, font=scaleFont)[0]-6, yc+5),
- font=scaleFont)
- y+= (yTop - yLow)/stepY
-
- #draw label
- labelFont=ImageFont.truetype(font=TAHOMA_FILE, size=17)
+ # draw scale
+ scaleFont = ImageFont.truetype(font=COUR_FILE, size=11)
+ x = xLow
+ for i in range(int(stepX) + 1):
+ xc = xLeftOffset + (x - xLow) * xScale
+ im_drawer.line(
+ xy=((xc, yTopOffset + plotHeight),
+ (xc, yTopOffset + plotHeight + 5)),
+ fill=axesColor)
+ strX = cformat(d=x, rank=0)
+ im_drawer.text(
+ text=strX,
+ xy=(xc - im_drawer.textsize(strX, font=scaleFont)[0] / 2,
+ yTopOffset + plotHeight + 14), font=scaleFont)
+ x += (xTop - xLow) / stepX
+
+ y = yLow
+ for i in range(int(stepY) + 1):
+ yc = yTopOffset + plotHeight - (y - yLow) * yScale
+ im_drawer.line(
+ xy=((xLeftOffset, yc), (xLeftOffset - 5, yc)), fill=axesColor)
+ strY = "%d" % y
+ im_drawer.text(
+ text=strY,
+ xy=(xLeftOffset - im_drawer.textsize(strY,
+ font=scaleFont)[0] - 6, yc + 5),
+ font=scaleFont)
+ y += (yTop - yLow) / stepY
+
+ # draw label
+ labelFont = ImageFont.truetype(font=TAHOMA_FILE, size=17)
if XLabel:
- im_drawer.text(
- text=XLabel,
- xy=(xLeftOffset+(
- plotWidth-im_drawer.textsize(XLabel, font=labelFont)[0])/2.0,
- yTopOffset+plotHeight+yBottomOffset-10),
- font=labelFont, fill=labelColor)
+ im_drawer.text(
+ text=XLabel,
+ xy=(xLeftOffset + (
+ plotWidth - im_drawer.textsize(XLabel, font=labelFont)[0]) / 2.0,
+ yTopOffset + plotHeight + yBottomOffset - 10),
+ font=labelFont, fill=labelColor)
if YLabel:
draw_rotated_text(canvas, text=YLabel,
xy=(19,
- yTopOffset+plotHeight-(
- plotHeight-im_drawer.textsize(
- YLabel, font=labelFont)[0])/2.0),
+ yTopOffset + plotHeight - (
+ plotHeight - im_drawer.textsize(
+ YLabel, font=labelFont)[0]) / 2.0),
font=labelFont, fill=labelColor, angle=90)
- labelFont=ImageFont.truetype(font=VERDANA_FILE, size=16)
+ labelFont = ImageFont.truetype(font=VERDANA_FILE, size=16)
if title:
- im_drawer.text(
- text=title,
- xy=(xLeftOffset+(plotWidth-im_drawer.textsize(
- title, font=labelFont)[0])/2.0,
- 20),
- font=labelFont, fill=labelColor)
+ im_drawer.text(
+ text=title,
+ xy=(xLeftOffset + (plotWidth - im_drawer.textsize(
+ title, font=labelFont)[0]) / 2.0,
+ 20),
+ font=labelFont, fill=labelColor)
# This function determines the scale of the plot
+
+
def detScaleOld(min, max):
- if min>=max:
+ if min >= max:
return None
elif min == -1.0 and max == 1.0:
return [-1.2, 1.2, 12]
else:
- a=max-min
- b=floor(log10(a))
- c=pow(10.0, b)
- if a < c*5.0:
- c/=2.0
- #print a,b,c
- low=c*floor(min/c)
- high=c*ceil(max/c)
- return [low, high, round((high-low)/c)]
-
-def detScale(min=0,max=0):
-
- if min>=max:
+ a = max - min
+ b = floor(log10(a))
+ c = pow(10.0, b)
+ if a < c * 5.0:
+ c /= 2.0
+ # print a,b,c
+ low = c * floor(min / c)
+ high = c * ceil(max / c)
+ return [low, high, round((high - low) / c)]
+
+
+def detScale(min=0, max=0):
+
+ if min >= max:
return None
elif min == -1.0 and max == 1.0:
return [-1.2, 1.2, 12]
else:
- a=max-min
+ a = max - min
if max != 0:
- max += 0.1*a
+ max += 0.1 * a
if min != 0:
- if min > 0 and min < 0.1*a:
+ if min > 0 and min < 0.1 * a:
min = 0.0
else:
- min -= 0.1*a
- a=max-min
- b=floor(log10(a))
- c=pow(10.0, b)
- low=c*floor(min/c)
- high=c*ceil(max/c)
- n = round((high-low)/c)
+ min -= 0.1 * a
+ a = max - min
+ b = floor(log10(a))
+ c = pow(10.0, b)
+ low = c * floor(min / c)
+ high = c * ceil(max / c)
+ n = round((high - low) / c)
div = 2.0
while n < 5 or n > 15:
if n < 5:
@@ -274,23 +286,27 @@ def detScale(min=0,max=0):
else:
c *= div
if div == 2.0:
- div =5.0
+ div = 5.0
else:
- div =2.0
- low=c*floor(min/c)
- high=c*ceil(max/c)
- n = round((high-low)/c)
+ div = 2.0
+ low = c * floor(min / c)
+ high = c * ceil(max / c)
+ n = round((high - low) / c)
return [low, high, n]
+
def bluefunc(x):
- return 1.0 / (1.0 + exp(-10*(x-0.6)))
+ return 1.0 / (1.0 + exp(-10 * (x - 0.6)))
+
def redfunc(x):
- return 1.0 / (1.0 + exp(10*(x-0.5)))
+ return 1.0 / (1.0 + exp(10 * (x - 0.5)))
+
def greenfunc(x):
- return 1 - pow(redfunc(x+0.2), 2) - bluefunc(x-0.3)
+ return 1 - pow(redfunc(x + 0.2), 2) - bluefunc(x - 0.3)
+
def colorSpectrum(n=100):
multiple = 10
@@ -303,26 +319,27 @@ def colorSpectrum(n=100):
return [ImageColor.getrgb("rgb(100%,0%,0%)"),
ImageColor.getrgb("rgb(0%,100%,0%)"),
ImageColor.getrgb("rgb(0%,0%,100%)")]
- N = n*multiple
- out = [None]*N;
+ N = n * multiple
+ out = [None] * N
for i in range(N):
- x = float(i)/N
+ x = float(i) / N
out[i] = ImageColor.getrgb("rgb({}%,{}%,{}%".format(
- *[int(i*100) for i in (
+ *[int(i * 100) for i in (
redfunc(x), greenfunc(x), bluefunc(x))]))
out2 = [out[0]]
- step = N/float(n-1)
+ step = N / float(n - 1)
j = 0
- for i in range(n-2):
+ for i in range(n - 2):
j += step
out2.append(out[int(j)])
out2.append(out[-1])
return out2
+
def _test():
import doctest
doctest.testmod()
-if __name__=="__main__":
+if __name__ == "__main__":
_test()
diff --git a/wqflask/utility/TDCell.py b/wqflask/utility/TDCell.py
index 8de8e050..4b0f4b1d 100644
--- a/wqflask/utility/TDCell.py
+++ b/wqflask/utility/TDCell.py
@@ -33,9 +33,9 @@
class TDCell:
def __init__(self, html="", text="", val=0.0):
- self.html = html #html, for web page
- self.text = text #text value, for output to a text file
- self.val = val #sort by value
+ self.html = html # html, for web page
+ self.text = text # text value, for output to a text file
+ self.val = val # sort by value
def __str__(self):
return self.text
diff --git a/wqflask/utility/THCell.py b/wqflask/utility/THCell.py
index dde221b5..f533dcb8 100644
--- a/wqflask/utility/THCell.py
+++ b/wqflask/utility/THCell.py
@@ -33,10 +33,10 @@
class THCell:
def __init__(self, html="", text="", sort=1, idx=-1):
- self.html = html #html, for web page
- self.text = text #Column text value
- self.sort = sort #0: not sortable, 1: yes
- self.idx = idx #sort by value
+ self.html = html # html, for web page
+ self.text = text # Column text value
+ self.sort = sort # 0: not sortable, 1: yes
+ self.idx = idx # sort by value
def __str__(self):
return self.text
diff --git a/wqflask/utility/__init__.py b/wqflask/utility/__init__.py
index 204ff59a..25273fa0 100644
--- a/wqflask/utility/__init__.py
+++ b/wqflask/utility/__init__.py
@@ -2,16 +2,18 @@ from pprint import pformat as pf
# Todo: Move these out of __init__
-class Bunch(object):
+
+class Bunch:
"""Like a dictionary but using object notation"""
- def __init__(self, **kw):
- self.__dict__ = kw
+
+ def __init__(self, **kw):
+ self.__dict__ = kw
def __repr__(self):
return pf(self.__dict__)
-class Struct(object):
+class Struct:
'''The recursive class for building and representing objects with.
From http://stackoverflow.com/a/6573827/1175849
@@ -30,6 +32,4 @@ class Struct(object):
def __repr__(self):
return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for
- (k, v) in list(self.__dict__.items())))
-
-
+ (k, v) in list(self.__dict__.items())))
diff --git a/wqflask/utility/after.py b/wqflask/utility/after.py
index 06091ecb..2b560e48 100644
--- a/wqflask/utility/after.py
+++ b/wqflask/utility/after.py
@@ -7,6 +7,7 @@ from flask import g
from wqflask import app
+
def after_this_request(f):
if not hasattr(g, 'after_request_callbacks'):
g.after_request_callbacks = []
diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py
index 672b36d5..57dbf8ba 100644
--- a/wqflask/utility/authentication_tools.py
+++ b/wqflask/utility/authentication_tools.py
@@ -11,6 +11,7 @@ from utility.redis_tools import (get_redis_conn,
add_resource)
Redis = get_redis_conn()
+
def check_resource_availability(dataset, trait_id=None):
# At least for now assume temporary entered traits are accessible
if type(dataset) == str or dataset.type == "Temp":
diff --git a/wqflask/utility/benchmark.py b/wqflask/utility/benchmark.py
index ea5a0ab6..6ece2f21 100644
--- a/wqflask/utility/benchmark.py
+++ b/wqflask/utility/benchmark.py
@@ -4,9 +4,10 @@ import time
from utility.tools import LOG_BENCH
from utility.logger import getLogger
-logger = getLogger(__name__ )
+logger = getLogger(__name__)
-class Bench(object):
+
+class Bench:
entries = collections.OrderedDict()
def __init__(self, name=None, write_output=LOG_BENCH):
@@ -18,7 +19,8 @@ class Bench(object):
if self.name:
logger.debug("Starting benchmark: %s" % (self.name))
else:
- logger.debug("Starting benchmark at: %s [%i]" % (inspect.stack()[1][3], inspect.stack()[1][2]))
+ logger.debug("Starting benchmark at: %s [%i]" % (
+ inspect.stack()[1][3], inspect.stack()[1][2]))
self.start_time = time.time()
def __exit__(self, type, value, traceback):
@@ -32,14 +34,16 @@ class Bench(object):
logger.info(" %s took: %f seconds" % (name, (time_taken)))
if self.name:
- Bench.entries[self.name] = Bench.entries.get(self.name, 0) + time_taken
+ Bench.entries[self.name] = Bench.entries.get(
+ self.name, 0) + time_taken
@classmethod
def report(cls):
- total_time = sum((time_taken for time_taken in list(cls.entries.values())))
+ total_time = sum(
+ (time_taken for time_taken in list(cls.entries.values())))
print("\nTiming report\n")
for name, time_taken in list(cls.entries.items()):
- percent = int(round((time_taken/total_time) * 100))
+ percent = int(round((time_taken / total_time) * 100))
print("[{}%] {}: {}".format(percent, name, time_taken))
print()
diff --git a/wqflask/utility/chunks.py b/wqflask/utility/chunks.py
index 9a7db102..484b5de6 100644
--- a/wqflask/utility/chunks.py
+++ b/wqflask/utility/chunks.py
@@ -26,6 +26,6 @@ def divide_into_chunks(the_list, number_chunks):
chunks = []
for counter in range(0, length, chunksize):
- chunks.append(the_list[counter:counter+chunksize])
+ chunks.append(the_list[counter:counter + chunksize])
return chunks
diff --git a/wqflask/utility/corestats.py b/wqflask/utility/corestats.py
index 67ca3ad3..da0a21db 100644
--- a/wqflask/utility/corestats.py
+++ b/wqflask/utility/corestats.py
@@ -15,7 +15,9 @@
import sys
-#ZS: Should switch to using some third party library for this; maybe scipy has an equivalent
+# ZS: Should switch to using some third party library for this; maybe scipy has an equivalent
+
+
class Stats:
def __init__(self, sequence):
@@ -63,7 +65,8 @@ class Stats:
if len(self.sequence) < 1:
value = None
elif (percentile >= 100):
- sys.stderr.write('ERROR: percentile must be < 100. you supplied: %s\n'% percentile)
+ sys.stderr.write(
+ 'ERROR: percentile must be < 100. you supplied: %s\n' % percentile)
value = None
else:
element_idx = int(len(self.sequence) * (percentile / 100.0))
@@ -80,4 +83,4 @@ class Stats:
# stats = corestats.Stats(sequence)
# print stats.avg()
# print stats.percentile(90)
-# ------------------------------------------- \ No newline at end of file
+# -------------------------------------------
diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py
index a5580811..eae3ba03 100644
--- a/wqflask/utility/elasticsearch_tools.py
+++ b/wqflask/utility/elasticsearch_tools.py
@@ -47,11 +47,14 @@ logger = getLogger(__name__)
from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT
+
def test_elasticsearch_connection():
- es = Elasticsearch(['http://'+ELASTICSEARCH_HOST+":"+str(ELASTICSEARCH_PORT)+'/'], verify_certs=True)
+ es = Elasticsearch(['http://' + ELASTICSEARCH_HOST + \
+ ":" + str(ELASTICSEARCH_PORT) + '/'], verify_certs=True)
if not es.ping():
logger.warning("Elasticsearch is DOWN")
+
def get_elasticsearch_connection(for_user=True):
"""Return a connection to ES. Returns None on failure"""
logger.info("get_elasticsearch_connection")
@@ -77,6 +80,7 @@ def get_elasticsearch_connection(for_user=True):
return es
+
def setup_users_index(es_connection):
if es_connection:
index_settings = {
@@ -85,20 +89,24 @@ def setup_users_index(es_connection):
"type": "keyword"}}}
es_connection.indices.create(index='users', ignore=400)
- es_connection.indices.put_mapping(body=index_settings, index="users", doc_type="local")
+ es_connection.indices.put_mapping(
+ body=index_settings, index="users", doc_type="local")
+
def get_user_by_unique_column(es, column_name, column_value, index="users", doc_type="local"):
return get_item_by_unique_column(es, column_name, column_value, index=index, doc_type=doc_type)
+
def save_user(es, user, user_id):
es_save_data(es, "users", "local", user, user_id)
+
def get_item_by_unique_column(es, column_name, column_value, index, doc_type):
item_details = None
try:
response = es.search(
- index = index, doc_type = doc_type, body = {
- "query": { "match": { column_name: column_value } }
+ index=index, doc_type=doc_type, body={
+ "query": {"match": {column_name: column_value}}
})
if len(response["hits"]["hits"]) > 0:
item_details = response["hits"]["hits"][0]["_source"]
@@ -106,7 +114,8 @@ def get_item_by_unique_column(es, column_name, column_value, index, doc_type):
pass
return item_details
+
def es_save_data(es, index, doc_type, data_item, data_id,):
from time import sleep
es.create(index, doc_type, body=data_item, id=data_id)
- sleep(1) # Delay 1 second to allow indexing
+ sleep(1) # Delay 1 second to allow indexing
diff --git a/wqflask/utility/external.py b/wqflask/utility/external.py
index 50afea08..805d2ffe 100644
--- a/wqflask/utility/external.py
+++ b/wqflask/utility/external.py
@@ -4,6 +4,7 @@ import os
import sys
import subprocess
+
def shell(command):
if subprocess.call(command, shell=True) != 0:
- raise Exception("ERROR: failed on "+command)
+ raise Exception("ERROR: failed on " + command)
diff --git a/wqflask/utility/gen_geno_ob.py b/wqflask/utility/gen_geno_ob.py
index 81085ffe..e619b7b6 100644
--- a/wqflask/utility/gen_geno_ob.py
+++ b/wqflask/utility/gen_geno_ob.py
@@ -1,7 +1,8 @@
import utility.logger
-logger = utility.logger.getLogger(__name__ )
+logger = utility.logger.getLogger(__name__)
-class genotype(object):
+
+class genotype:
"""
Replacement for reaper.Dataset so we can remove qtlreaper use while still generating mapping output figure
"""
@@ -18,7 +19,7 @@ class genotype(object):
self.filler = False
self.mb_exists = False
- #ZS: This is because I'm not sure if some files switch the column that contains Mb/cM positions; might be unnecessary
+ # ZS: This is because I'm not sure if some files switch the column that contains Mb/cM positions; might be unnecessary
self.cm_column = 2
self.mb_column = 3
@@ -36,14 +37,16 @@ class genotype(object):
return len(self.chromosomes)
def read_rdata_output(self, qtl_results):
- #ZS: This is necessary because R/qtl requires centimorgan marker positions, which it normally gets from the .geno file, but that doesn't exist for HET3-ITP (which only has RData), so it needs to read in the marker cM positions from the results
- self.chromosomes = [] #ZS: Overwriting since the .geno file's contents are just placeholders
+ # ZS: This is necessary because R/qtl requires centimorgan marker positions, which it normally gets from the .geno file, but that doesn't exist for HET3-ITP (which only has RData), so it needs to read in the marker cM positions from the results
+ # ZS: Overwriting since the .geno file's contents are just placeholders
+ self.chromosomes = []
- this_chr = "" #ZS: This is so it can track when the chromosome changes as it iterates through markers
+ this_chr = "" # ZS: This is so it can track when the chromosome changes as it iterates through markers
chr_ob = None
for marker in qtl_results:
locus = Locus(self)
- if (str(marker['chr']) != this_chr) and this_chr != "X": #ZS: This is really awkward but works as a temporary fix
+ # ZS: This is really awkward but works as a temporary fix
+ if (str(marker['chr']) != this_chr) and this_chr != "X":
if this_chr != "":
self.chromosomes.append(chr_ob)
this_chr = str(marker['chr'])
@@ -68,7 +71,7 @@ class genotype(object):
with open(filename, 'r') as geno_file:
lines = geno_file.readlines()
- this_chr = "" #ZS: This is so it can track when the chromosome changes as it iterates through markers
+ this_chr = "" # ZS: This is so it can track when the chromosome changes as it iterates through markers
chr_ob = None
for line in lines:
if line[0] == "#":
@@ -119,7 +122,8 @@ class genotype(object):
self.chromosomes.append(chr_ob)
-class Chr(object):
+
+class Chr:
def __init__(self, name, geno_ob):
self.name = name
self.loci = []
@@ -140,8 +144,9 @@ class Chr(object):
def add_marker(self, marker_row):
self.loci.append(Locus(self.geno_ob, marker_row))
-class Locus(object):
- def __init__(self, geno_ob, marker_row = None):
+
+class Locus:
+ def __init__(self, geno_ob, marker_row=None):
self.chr = None
self.name = None
self.cM = None
@@ -153,9 +158,11 @@ class Locus(object):
try:
self.cM = float(marker_row[geno_ob.cm_column])
except:
- self.cM = float(marker_row[geno_ob.mb_column]) if geno_ob.mb_exists else 0
+ self.cM = float(
+ marker_row[geno_ob.mb_column]) if geno_ob.mb_exists else 0
try:
- self.Mb = float(marker_row[geno_ob.mb_column]) if geno_ob.mb_exists else None
+ self.Mb = float(
+ marker_row[geno_ob.mb_column]) if geno_ob.mb_exists else None
except:
self.Mb = self.cM
@@ -175,5 +182,5 @@ class Locus(object):
for allele in marker_row[start_pos:]:
if allele in list(geno_table.keys()):
self.genotype.append(geno_table[allele])
- else: #ZS: Some genotype appears that isn't specified in the metadata, make it unknown
+ else: # ZS: Some genotype appears that isn't specified in the metadata, make it unknown
self.genotype.append("U")
diff --git a/wqflask/utility/genofile_parser.py b/wqflask/utility/genofile_parser.py
index 0b736176..86d9823e 100644
--- a/wqflask/utility/genofile_parser.py
+++ b/wqflask/utility/genofile_parser.py
@@ -12,88 +12,89 @@ import simplejson as json
from pprint import pformat as pf
-class Marker(object):
- def __init__(self):
- self.name = None
- self.chr = None
- self.cM = None
- self.Mb = None
- self.genotypes = []
+class Marker:
+ def __init__(self):
+ self.name = None
+ self.chr = None
+ self.cM = None
+ self.Mb = None
+ self.genotypes = []
-class ConvertGenoFile(object):
- def __init__(self, input_file):
- self.mb_exists = False
- self.cm_exists = False
- self.markers = []
+class ConvertGenoFile:
- self.latest_row_pos = None
- self.latest_col_pos = None
+ def __init__(self, input_file):
+ self.mb_exists = False
+ self.cm_exists = False
+ self.markers = []
- self.latest_row_value = None
- self.latest_col_value = None
- self.input_fh = open(input_file)
- print("!!!!!!!!!!!!!!!!PARSER!!!!!!!!!!!!!!!!!!")
- self.haplotype_notation = {
- '@mat': "1",
- '@pat': "2",
- '@het': "-999",
- '@unk': "-999"
- }
- self.configurations = {}
+ self.latest_row_pos = None
+ self.latest_col_pos = None
- def process_rows(self):
- for self.latest_row_pos, row in enumerate(self.input_fh):
- self.latest_row_value = row
- # Take care of headers
- if not row.strip():
- continue
- if row.startswith('#'):
- continue
- if row.startswith('Chr'):
- if 'Mb' in row.split():
- self.mb_exists = True
- if 'cM' in row.split():
- self.cm_exists = True
- skip = 2 + self.cm_exists + self.mb_exists
- self.individuals = row.split()[skip:]
- continue
- if row.startswith('@'):
- key, _separater, value = row.partition(':')
- key = key.strip()
- value = value.strip()
- if key in self.haplotype_notation:
- self.configurations[value] = self.haplotype_notation[key]
- continue
- if not len(self.configurations):
- raise EmptyConfigurations
- yield row
+ self.latest_row_value = None
+ self.latest_col_value = None
+ self.input_fh = open(input_file)
+ print("!!!!!!!!!!!!!!!!PARSER!!!!!!!!!!!!!!!!!!")
+ self.haplotype_notation = {
+ '@mat': "1",
+ '@pat': "2",
+ '@het': "-999",
+ '@unk': "-999"
+ }
+ self.configurations = {}
- def process_csv(self):
- for row in self.process_rows():
- row_items = row.split("\t")
+ def process_rows(self):
+ for self.latest_row_pos, row in enumerate(self.input_fh):
+ self.latest_row_value = row
+ # Take care of headers
+ if not row.strip():
+ continue
+ if row.startswith('#'):
+ continue
+ if row.startswith('Chr'):
+ if 'Mb' in row.split():
+ self.mb_exists = True
+ if 'cM' in row.split():
+ self.cm_exists = True
+ skip = 2 + self.cm_exists + self.mb_exists
+ self.individuals = row.split()[skip:]
+ continue
+ if row.startswith('@'):
+ key, _separater, value = row.partition(':')
+ key = key.strip()
+ value = value.strip()
+ if key in self.haplotype_notation:
+ self.configurations[value] = self.haplotype_notation[key]
+ continue
+ if not len(self.configurations):
+ raise EmptyConfigurations
+ yield row
- this_marker = Marker()
- this_marker.name = row_items[1]
- this_marker.chr = row_items[0]
- if self.cm_exists and self.mb_exists:
- this_marker.cM = row_items[2]
- this_marker.Mb = row_items[3]
- genotypes = row_items[4:]
- elif self.cm_exists:
- this_marker.cM = row_items[2]
- genotypes = row_items[3:]
- elif self.mb_exists:
- this_marker.Mb = row_items[2]
- genotypes = row_items[3:]
- else:
- genotypes = row_items[2:]
- for item_count, genotype in enumerate(genotypes):
- if genotype.upper().strip() in self.configurations:
- this_marker.genotypes.append(self.configurations[genotype.upper().strip()])
- else:
- print("WARNING:", genotype.upper())
- this_marker.genotypes.append("NA")
- self.markers.append(this_marker.__dict__)
+ def process_csv(self):
+ for row in self.process_rows():
+ row_items = row.split("\t")
+ this_marker = Marker()
+ this_marker.name = row_items[1]
+ this_marker.chr = row_items[0]
+ if self.cm_exists and self.mb_exists:
+ this_marker.cM = row_items[2]
+ this_marker.Mb = row_items[3]
+ genotypes = row_items[4:]
+ elif self.cm_exists:
+ this_marker.cM = row_items[2]
+ genotypes = row_items[3:]
+ elif self.mb_exists:
+ this_marker.Mb = row_items[2]
+ genotypes = row_items[3:]
+ else:
+ genotypes = row_items[2:]
+ for item_count, genotype in enumerate(genotypes):
+ if genotype.upper().strip() in self.configurations:
+ this_marker.genotypes.append(
+ self.configurations[genotype.upper().strip()])
+ else:
+ print("WARNING:", genotype.upper())
+ this_marker.genotypes.append("NA")
+ self.markers.append(this_marker.__dict__)
diff --git a/wqflask/utility/helper_functions.py b/wqflask/utility/helper_functions.py
index 46eeb35d..ecc075ae 100644
--- a/wqflask/utility/helper_functions.py
+++ b/wqflask/utility/helper_functions.py
@@ -4,20 +4,23 @@ from base.species import TheSpecies
from utility import hmac
-from flask import Flask, g
+from flask import g
import logging
-logger = logging.getLogger(__name__ )
+logger = logging.getLogger(__name__)
+
def get_species_dataset_trait(self, start_vars):
- #assert type(read_genotype) == type(bool()), "Expecting boolean value for read_genotype"
if "temp_trait" in list(start_vars.keys()):
- if start_vars['temp_trait'] == "True":
- self.dataset = data_set.create_dataset(dataset_name = "Temp", dataset_type = "Temp", group_name = start_vars['group'])
- else:
- self.dataset = data_set.create_dataset(start_vars['dataset'])
+ if start_vars['temp_trait'] == "True":
+ self.dataset = data_set.create_dataset(
+ dataset_name="Temp",
+ dataset_type="Temp",
+ group_name=start_vars['group'])
+ else:
+ self.dataset = data_set.create_dataset(start_vars['dataset'])
else:
- self.dataset = data_set.create_dataset(start_vars['dataset'])
+ self.dataset = data_set.create_dataset(start_vars['dataset'])
logger.debug("After creating dataset")
self.species = TheSpecies(dataset=self.dataset)
logger.debug("After creating species")
@@ -27,9 +30,6 @@ def get_species_dataset_trait(self, start_vars):
get_qtl_info=True)
logger.debug("After creating trait")
- #if read_genotype:
- #self.dataset.group.read_genotype_file()
- #self.genotype = self.dataset.group.genotype
def get_trait_db_obs(self, trait_db_list):
if isinstance(trait_db_list, str):
@@ -39,31 +39,32 @@ def get_trait_db_obs(self, trait_db_list):
for trait in trait_db_list:
data, _separator, hmac_string = trait.rpartition(':')
data = data.strip()
- assert hmac_string==hmac.hmac_creation(data), "Data tampering?"
+ assert hmac_string == hmac.hmac_creation(data), "Data tampering?"
trait_name, dataset_name = data.split(":")[:2]
if dataset_name == "Temp":
- dataset_ob = data_set.create_dataset(dataset_name=dataset_name, dataset_type="Temp", group_name=trait_name.split("_")[2])
+ dataset_ob = data_set.create_dataset(
+ dataset_name=dataset_name, dataset_type="Temp",
+ group_name=trait_name.split("_")[2])
else:
dataset_ob = data_set.create_dataset(dataset_name)
trait_ob = create_trait(dataset=dataset_ob,
- name=trait_name,
- cellid=None)
+ name=trait_name,
+ cellid=None)
if trait_ob:
self.trait_list.append((trait_ob, dataset_ob))
-def get_species_groups():
-
- species_query = "SELECT SpeciesId, MenuName FROM Species"
- species_ids_and_names = g.db.execute(species_query).fetchall()
-
- species_and_groups = []
- for species_id, species_name in species_ids_and_names:
- this_species_groups = {}
- this_species_groups['species'] = species_name
- groups_query = "SELECT InbredSetName FROM InbredSet WHERE SpeciesId = %s" % (species_id)
- groups = [group[0] for group in g.db.execute(groups_query).fetchall()]
-
- this_species_groups['groups'] = groups
- species_and_groups.append(this_species_groups)
- return species_and_groups
+def get_species_groups():
+ """Group each species into a group"""
+ _menu = {}
+ for species, group_name in g.db.execute(
+ "SELECT s.MenuName, i.InbredSetName FROM InbredSet i "
+ "INNER JOIN Species s ON s.SpeciesId = i.SpeciesId "
+ "ORDER BY i.SpeciesId ASC, i.Name ASC").fetchall():
+ if _menu.get(species):
+ _menu = _menu[species].append(group_name)
+ else:
+ _menu[species] = [group_name]
+ return [{"species": key,
+ "groups": value} for key, value in
+ list(_menu.items())]
diff --git a/wqflask/utility/logger.py b/wqflask/utility/logger.py
index e904eb94..d706e32a 100644
--- a/wqflask/utility/logger.py
+++ b/wqflask/utility/logger.py
@@ -35,6 +35,7 @@ import datetime
from utility.tools import LOG_LEVEL, LOG_LEVEL_DEBUG, LOG_SQL
+
class GNLogger:
"""A logger class with some additional functionality, such as
multiple parameter logging, SQL logging, timing, colors, and lazy
@@ -49,14 +50,14 @@ class GNLogger:
"""Set the undelying log level"""
self.logger.setLevel(value)
- def debug(self,*args):
+ def debug(self, *args):
"""Call logging.debug for multiple args. Use (lazy) debugf and
level=num to filter on LOG_LEVEL_DEBUG.
"""
self.collect(self.logger.debug, *args)
- def debug20(self,*args):
+ def debug20(self, *args):
"""Call logging.debug for multiple args. Use level=num to filter on
LOG_LEVEL_DEBUG (NYI).
@@ -65,29 +66,29 @@ LOG_LEVEL_DEBUG (NYI).
if self.logger.getEffectiveLevel() < 20:
self.collect(self.logger.debug, *args)
- def info(self,*args):
+ def info(self, *args):
"""Call logging.info for multiple args"""
self.collect(self.logger.info, *args)
- def warning(self,*args):
+ def warning(self, *args):
"""Call logging.warning for multiple args"""
self.collect(self.logger.warning, *args)
# self.logger.warning(self.collect(*args))
- def error(self,*args):
+ def error(self, *args):
"""Call logging.error for multiple args"""
now = datetime.datetime.utcnow()
time_str = now.strftime('%H:%M:%S UTC %Y%m%d')
- l = [time_str]+list(args)
+ l = [time_str] + list(args)
self.collect(self.logger.error, *l)
- def infof(self,*args):
+ def infof(self, *args):
"""Call logging.info for multiple args lazily"""
# only evaluate function when logging
if self.logger.getEffectiveLevel() < 30:
self.collectf(self.logger.debug, *args)
- def debugf(self,level=0,*args):
+ def debugf(self, level=0, *args):
"""Call logging.debug for multiple args lazily and handle
LOG_LEVEL_DEBUG correctly
@@ -97,7 +98,7 @@ LOG_LEVEL_DEBUG (NYI).
if self.logger.getEffectiveLevel() < 20:
self.collectf(self.logger.debug, *args)
- def sql(self, sqlcommand, fun = None):
+ def sql(self, sqlcommand, fun=None):
"""Log SQL command, optionally invoking a timed fun"""
if LOG_SQL:
caller = stack()[1][3]
@@ -110,11 +111,11 @@ LOG_LEVEL_DEBUG (NYI).
self.info(result)
return result
- def collect(self,fun,*args):
+ def collect(self, fun, *args):
"""Collect arguments and use fun to output"""
- out = "."+stack()[2][3]
+ out = "." + stack()[2][3]
for a in args:
- if len(out)>1:
+ if len(out) > 1:
out += ": "
if isinstance(a, str):
out = out + a
@@ -122,11 +123,11 @@ LOG_LEVEL_DEBUG (NYI).
out = out + pf(a, width=160)
fun(out)
- def collectf(self,fun,*args):
+ def collectf(self, fun, *args):
"""Collect arguments and use fun to output one by one"""
- out = "."+stack()[2][3]
+ out = "." + stack()[2][3]
for a in args:
- if len(out)>1:
+ if len(out) > 1:
out += ": "
if isfunction(a):
out += a()
@@ -139,7 +140,9 @@ LOG_LEVEL_DEBUG (NYI).
# Get the module logger. You can override log levels at the
# module level
-def getLogger(name, level = None):
+
+
+def getLogger(name, level=None):
gnlogger = GNLogger(name)
logger = gnlogger.logger
@@ -148,5 +151,6 @@ def getLogger(name, level = None):
else:
logger.setLevel(LOG_LEVEL)
- logger.info("Log level of "+name+" set to "+logging.getLevelName(logger.getEffectiveLevel()))
+ logger.info("Log level of " + name + " set to " + \
+ logging.getLevelName(logger.getEffectiveLevel()))
return gnlogger
diff --git a/wqflask/utility/pillow_utils.py b/wqflask/utility/pillow_utils.py
index c486abba..5713e155 100644
--- a/wqflask/utility/pillow_utils.py
+++ b/wqflask/utility/pillow_utils.py
@@ -3,12 +3,14 @@ from PIL import Image, ImageColor, ImageDraw, ImageFont
from utility.tools import TEMPDIR
import utility.logger
-logger = utility.logger.getLogger(__name__ )
+logger = utility.logger.getLogger(__name__)
BLACK = ImageColor.getrgb("black")
WHITE = ImageColor.getrgb("white")
# def draw_rotated_text(canvas: Image, text: str, font: ImageFont, xy: tuple, fill: ImageColor=BLACK, angle: int=-90):
+
+
def draw_rotated_text(canvas, text, font, xy, fill=BLACK, angle=-90):
# type: (Image, str, ImageFont, tuple, ImageColor, int)
"""Utility function draw rotated text"""
@@ -20,6 +22,8 @@ def draw_rotated_text(canvas, text, font, xy, fill=BLACK, angle=-90):
canvas.paste(im=tmp_img2, box=tuple([int(i) for i in xy]))
# def draw_open_polygon(canvas: Image, xy: tuple, fill: ImageColor=WHITE, outline: ImageColor=BLACK):
+
+
def draw_open_polygon(canvas, xy, fill=None, outline=BLACK, width=0):
# type: (Image, tuple, ImageColor, ImageColor)
draw_ctx = ImageDraw.Draw(canvas)
diff --git a/wqflask/utility/redis_tools.py b/wqflask/utility/redis_tools.py
index 8052035f..96a4be12 100644
--- a/wqflask/utility/redis_tools.py
+++ b/wqflask/utility/redis_tools.py
@@ -133,8 +133,10 @@ def get_user_groups(user_id):
for key in groups_list:
try:
group_ob = json.loads(groups_list[key])
- group_admins = set([this_admin.encode('utf-8') if this_admin else None for this_admin in group_ob['admins']])
- group_members = set([this_member.encode('utf-8') if this_member else None for this_member in group_ob['members']])
+ group_admins = set([this_admin.encode(
+ 'utf-8') if this_admin else None for this_admin in group_ob['admins']])
+ group_members = set([this_member.encode(
+ 'utf-8') if this_member else None for this_member in group_ob['members']])
if user_id in group_admins:
admin_group_ids.append(group_ob['id'])
elif user_id in group_members:
@@ -203,7 +205,8 @@ def get_groups_like_unique_column(column_name, column_value):
if column_value in group_info[column_name]:
matched_groups.append(group_info)
else:
- matched_groups.append(load_json_from_redis(group_list, column_value))
+ matched_groups.append(
+ load_json_from_redis(group_list, column_value))
return matched_groups
diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py
index f1aaebb6..6ef759e0 100644
--- a/wqflask/utility/startup_config.py
+++ b/wqflask/utility/startup_config.py
@@ -3,12 +3,13 @@ from wqflask import app
from utility.tools import WEBSERVER_MODE, show_settings, get_setting_int, get_setting, get_setting_bool
import utility.logger
-logger = utility.logger.getLogger(__name__ )
+logger = utility.logger.getLogger(__name__)
-BLUE = '\033[94m'
+BLUE = '\033[94m'
GREEN = '\033[92m'
-BOLD = '\033[1m'
-ENDC = '\033[0m'
+BOLD = '\033[1m'
+ENDC = '\033[0m'
+
def app_config():
app.config['SESSION_TYPE'] = 'filesystem'
@@ -27,7 +28,8 @@ def app_config():
port = get_setting_int("SERVER_PORT")
if get_setting_bool("USE_GN_SERVER"):
- print(("GN2 API server URL is ["+BLUE+get_setting("GN_SERVER_URL")+ENDC+"]"))
+ print(
+ ("GN2 API server URL is [" + BLUE + get_setting("GN_SERVER_URL") + ENDC + "]"))
import requests
page = requests.get(get_setting("GN_SERVER_URL"))
if page.status_code != 200:
@@ -36,4 +38,5 @@ def app_config():
# import utility.elasticsearch_tools as es
# es.test_elasticsearch_connection()
- print(("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE, str(port), ENDC, get_setting("WEBSERVER_URL"))))
+ print(("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" %
+ (BLUE, str(port), ENDC, get_setting("WEBSERVER_URL"))))
diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py
index b92cc2d1..eddb97da 100644
--- a/wqflask/utility/svg.py
+++ b/wqflask/utility/svg.py
@@ -172,7 +172,7 @@ def _viewboxlist(a):
"""formats a tuple"""
s = ''
for e in a:
- s += str(e)+' '
+ s += str(e) + ' '
return s
@@ -189,7 +189,7 @@ class pathdata:
def __init__(self, x=None, y=None):
self.path = []
if x is not None and y is not None:
- self.path.append('M '+str(x)+' '+str(y))
+ self.path.append('M ' + str(x) + ' ' + str(y))
def closepath(self):
"""ends the path"""
@@ -197,79 +197,83 @@ class pathdata:
def move(self, x, y):
"""move to absolute"""
- self.path.append('M '+str(x)+' '+str(y))
+ self.path.append('M ' + str(x) + ' ' + str(y))
def relmove(self, x, y):
"""move to relative"""
- self.path.append('m '+str(x)+' '+str(y))
+ self.path.append('m ' + str(x) + ' ' + str(y))
def line(self, x, y):
"""line to absolute"""
- self.path.append('L '+str(x)+' '+str(y))
+ self.path.append('L ' + str(x) + ' ' + str(y))
def relline(self, x, y):
"""line to relative"""
- self.path.append('l '+str(x)+' '+str(y))
+ self.path.append('l ' + str(x) + ' ' + str(y))
def hline(self, x):
"""horizontal line to absolute"""
- self.path.append('H'+str(x))
+ self.path.append('H' + str(x))
def relhline(self, x):
"""horizontal line to relative"""
- self.path.append('h'+str(x))
+ self.path.append('h' + str(x))
def vline(self, y):
"""verical line to absolute"""
- self.path.append('V'+str(y))
+ self.path.append('V' + str(y))
def relvline(self, y):
"""vertical line to relative"""
- self.path.append('v'+str(y))
+ self.path.append('v' + str(y))
def bezier(self, x1, y1, x2, y2, x, y):
"""bezier with xy1 and xy2 to xy absolut"""
- self.path.append('C'+str(x1)+','+str(y1)+' '+str(x2) +
- ','+str(y2)+' '+str(x)+','+str(y))
+ self.path.append('C' + str(x1) + ',' + str(y1) + ' ' + str(x2)
+ + ',' + str(y2) + ' ' + str(x) + ',' + str(y))
def relbezier(self, x1, y1, x2, y2, x, y):
"""bezier with xy1 and xy2 to xy relative"""
- self.path.append('c'+str(x1)+','+str(y1)+' '+str(x2) +
- ','+str(y2)+' '+str(x)+','+str(y))
+ self.path.append('c' + str(x1) + ',' + str(y1) + ' ' + str(x2)
+ + ',' + str(y2) + ' ' + str(x) + ',' + str(y))
def smbezier(self, x2, y2, x, y):
"""smooth bezier with xy2 to xy absolut"""
- self.path.append('S'+str(x2)+','+str(y2)+' '+str(x)+','+str(y))
+ self.path.append('S' + str(x2) + ',' + str(y2) + \
+ ' ' + str(x) + ',' + str(y))
def relsmbezier(self, x2, y2, x, y):
"""smooth bezier with xy2 to xy relative"""
- self.path.append('s'+str(x2)+','+str(y2)+' '+str(x)+','+str(y))
+ self.path.append('s' + str(x2) + ',' + str(y2) + \
+ ' ' + str(x) + ',' + str(y))
def qbezier(self, x1, y1, x, y):
"""quadratic bezier with xy1 to xy absolut"""
- self.path.append('Q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y))
+ self.path.append('Q' + str(x1) + ',' + str(y1) + \
+ ' ' + str(x) + ',' + str(y))
def relqbezier(self, x1, y1, x, y):
"""quadratic bezier with xy1 to xy relative"""
- self.path.append('q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y))
+ self.path.append('q' + str(x1) + ',' + str(y1) + \
+ ' ' + str(x) + ',' + str(y))
def smqbezier(self, x, y):
"""smooth quadratic bezier to xy absolut"""
- self.path.append('T'+str(x)+','+str(y))
+ self.path.append('T' + str(x) + ',' + str(y))
def relsmqbezier(self, x, y):
"""smooth quadratic bezier to xy relative"""
- self.path.append('t'+str(x)+','+str(y))
+ self.path.append('t' + str(x) + ',' + str(y))
def ellarc(self, rx, ry, xrot, laf, sf, x, y):
"""elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy absolut"""
- self.path.append('A'+str(rx)+','+str(ry)+' '+str(xrot) +
- ' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y))
+ self.path.append('A' + str(rx) + ',' + str(ry) + ' ' + str(xrot)
+ + ' ' + str(laf) + ' ' + str(sf) + ' ' + str(x) + ' ' + str(y))
def relellarc(self, rx, ry, xrot, laf, sf, x, y):
"""elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy relative"""
- self.path.append('a'+str(rx)+','+str(ry)+' '+str(xrot) +
- ' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y))
+ self.path.append('a' + str(rx) + ',' + str(ry) + ' ' + str(xrot)
+ + ' ' + str(laf) + ' ' + str(sf) + ' ' + str(x) + ' ' + str(y))
def __repr__(self):
return ' '.join(self.path)
@@ -312,36 +316,36 @@ class SVGelement:
self.elements.append(SVGelement)
def toXml(self, level, f):
- f.write('\t'*level)
- f.write('<'+self.type)
+ f.write('\t' * level)
+ f.write('<' + self.type)
for attkey in list(self.attributes.keys()):
- f.write(' '+_escape(str(attkey))+'=' +
- _quoteattr(str(self.attributes[attkey])))
+ f.write(' ' + _escape(str(attkey)) + '='
+ + _quoteattr(str(self.attributes[attkey])))
if self.namespace:
- f.write(' xmlns="' + _escape(str(self.namespace)) +
- '" xmlns:xlink="http://www.w3.org/1999/xlink"')
+ f.write(' xmlns="' + _escape(str(self.namespace))
+ + '" xmlns:xlink="http://www.w3.org/1999/xlink"')
if self.elements or self.text or self.cdata:
f.write('>')
if self.elements:
f.write('\n')
for element in self.elements:
- element.toXml(level+1, f)
+ element.toXml(level + 1, f)
if self.cdata:
- f.write('\n'+'\t'*(level+1)+'<![CDATA[')
+ f.write('\n' + '\t' * (level + 1) + '<![CDATA[')
for line in self.cdata.splitlines():
- f.write('\n'+'\t'*(level+2)+line)
- f.write('\n'+'\t'*(level+1)+']]>\n')
+ f.write('\n' + '\t' * (level + 2) + line)
+ f.write('\n' + '\t' * (level + 1) + ']]>\n')
if self.text:
if isinstance(self.text, type('')): # If the text is only text
f.write(_escape(str(self.text)))
else: # If the text is a spannedtext class
f.write(str(self.text))
if self.elements:
- f.write('\t'*level+'</'+self.type+'>\n')
+ f.write('\t' * level + '</' + self.type + '>\n')
elif self.text:
- f.write('</'+self.type+'>\n')
+ f.write('</' + self.type + '>\n')
elif self.cdata:
- f.write('\t'*level+'</'+self.type+'>\n')
+ f.write('\t' * level + '</' + self.type + '>\n')
else:
f.write('/>\n')
@@ -447,38 +451,41 @@ class rect(SVGelement):
if width == None or height == None:
raise ValueError('both height and width are required')
- SVGelement.__init__(self, 'rect', {'width':width,'height':height}, **args)
- if x!=None:
- self.attributes['x']=x
- if y!=None:
- self.attributes['y']=y
- if fill!=None:
- self.attributes['fill']=fill
- if stroke!=None:
- self.attributes['stroke']=stroke
- if stroke_width!=None:
- self.attributes['stroke-width']=stroke_width
+ SVGelement.__init__(
+ self, 'rect', {'width': width, 'height': height}, **args)
+ if x != None:
+ self.attributes['x'] = x
+ if y != None:
+ self.attributes['y'] = y
+ if fill != None:
+ self.attributes['fill'] = fill
+ if stroke != None:
+ self.attributes['stroke'] = stroke
+ if stroke_width != None:
+ self.attributes['stroke-width'] = stroke_width
+
class ellipse(SVGelement):
"""e=ellipse(rx,ry,x,y,fill,stroke,stroke_width,**args)
an ellipse is defined as a center and a x and y radius.
"""
- def __init__(self,cx=None,cy=None,rx=None,ry=None,fill=None,stroke=None,stroke_width=None,**args):
- if rx==None or ry== None:
+
+ def __init__(self, cx=None, cy=None, rx=None, ry=None, fill=None, stroke=None, stroke_width=None, **args):
+ if rx == None or ry == None:
raise ValueError('both rx and ry are required')
- SVGelement.__init__(self, 'ellipse', {'rx':rx,'ry':ry}, **args)
- if cx!=None:
- self.attributes['cx']=cx
- if cy!=None:
- self.attributes['cy']=cy
- if fill!=None:
- self.attributes['fill']=fill
- if stroke!=None:
- self.attributes['stroke']=stroke
- if stroke_width!=None:
- self.attributes['stroke-width']=stroke_width
+ SVGelement.__init__(self, 'ellipse', {'rx': rx, 'ry': ry}, **args)
+ if cx != None:
+ self.attributes['cx'] = cx
+ if cy != None:
+ self.attributes['cy'] = cy
+ if fill != None:
+ self.attributes['fill'] = fill
+ if stroke != None:
+ self.attributes['stroke'] = stroke
+ if stroke_width != None:
+ self.attributes['stroke-width'] = stroke_width
class circle(SVGelement):
@@ -486,20 +493,22 @@ class circle(SVGelement):
The circle creates an element using a x, y and radius values eg
"""
- def __init__(self,cx=None,cy=None,r=None,fill=None,stroke=None,stroke_width=None,**args):
- if r==None:
+
+ def __init__(self, cx=None, cy=None, r=None, fill=None, stroke=None, stroke_width=None, **args):
+ if r == None:
raise ValueError('r is required')
- SVGelement.__init__(self, 'circle', {'r':r}, **args)
- if cx!=None:
- self.attributes['cx']=cx
- if cy!=None:
- self.attributes['cy']=cy
- if fill!=None:
- self.attributes['fill']=fill
- if stroke!=None:
- self.attributes['stroke']=stroke
- if stroke_width!=None:
- self.attributes['stroke-width']=stroke_width
+ SVGelement.__init__(self, 'circle', {'r': r}, **args)
+ if cx != None:
+ self.attributes['cx'] = cx
+ if cy != None:
+ self.attributes['cy'] = cy
+ if fill != None:
+ self.attributes['fill'] = fill
+ if stroke != None:
+ self.attributes['stroke'] = stroke
+ if stroke_width != None:
+ self.attributes['stroke-width'] = stroke_width
+
class point(circle):
"""p=point(x,y,color)
@@ -507,72 +516,83 @@ class point(circle):
A point is defined as a circle with a size 1 radius. It may be more efficient to use a
very small rectangle if you use many points because a circle is difficult to render.
"""
- def __init__(self,x,y,fill='black',**args):
+
+ def __init__(self, x, y, fill='black', **args):
circle.__init__(self, x, y, 1, fill, **args)
+
class line(SVGelement):
"""l=line(x1,y1,x2,y2,stroke,stroke_width,**args)
A line is defined by a begin x,y pair and an end x,y pair
"""
- def __init__(self,x1=None,y1=None,x2=None,y2=None,stroke=None,stroke_width=None,**args):
+
+ def __init__(self, x1=None, y1=None, x2=None, y2=None, stroke=None, stroke_width=None, **args):
SVGelement.__init__(self, 'line', **args)
- if x1!=None:
- self.attributes['x1']=x1
- if y1!=None:
- self.attributes['y1']=y1
- if x2!=None:
- self.attributes['x2']=x2
- if y2!=None:
- self.attributes['y2']=y2
- if stroke_width!=None:
- self.attributes['stroke-width']=stroke_width
- if stroke!=None:
- self.attributes['stroke']=stroke
+ if x1 != None:
+ self.attributes['x1'] = x1
+ if y1 != None:
+ self.attributes['y1'] = y1
+ if x2 != None:
+ self.attributes['x2'] = x2
+ if y2 != None:
+ self.attributes['y2'] = y2
+ if stroke_width != None:
+ self.attributes['stroke-width'] = stroke_width
+ if stroke != None:
+ self.attributes['stroke'] = stroke
+
class polyline(SVGelement):
"""pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args)
a polyline is defined by a list of xy pairs
"""
- def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args):
- SVGelement.__init__(self, 'polyline', {'points':_xypointlist(points)}, **args)
- if fill!=None:
- self.attributes['fill']=fill
- if stroke_width!=None:
- self.attributes['stroke-width']=stroke_width
- if stroke!=None:
- self.attributes['stroke']=stroke
+
+ def __init__(self, points, fill=None, stroke=None, stroke_width=None, **args):
+ SVGelement.__init__(self, 'polyline', {
+ 'points': _xypointlist(points)}, **args)
+ if fill != None:
+ self.attributes['fill'] = fill
+ if stroke_width != None:
+ self.attributes['stroke-width'] = stroke_width
+ if stroke != None:
+ self.attributes['stroke'] = stroke
+
class polygon(SVGelement):
"""pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args)
a polygon is defined by a list of xy pairs
"""
- def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args):
- SVGelement.__init__(self, 'polygon', {'points':_xypointlist(points)}, **args)
- if fill!=None:
- self.attributes['fill']=fill
- if stroke_width!=None:
- self.attributes['stroke-width']=stroke_width
- if stroke!=None:
- self.attributes['stroke']=stroke
+
+ def __init__(self, points, fill=None, stroke=None, stroke_width=None, **args):
+ SVGelement.__init__(
+ self, 'polygon', {'points': _xypointlist(points)}, **args)
+ if fill != None:
+ self.attributes['fill'] = fill
+ if stroke_width != None:
+ self.attributes['stroke-width'] = stroke_width
+ if stroke != None:
+ self.attributes['stroke'] = stroke
+
class path(SVGelement):
"""p=path(path,fill,stroke,stroke_width,**args)
a path is defined by a path object and optional width, stroke and fillcolor
"""
- def __init__(self,pathdata,fill=None,stroke=None,stroke_width=None,id=None,**args):
- SVGelement.__init__(self, 'path', {'d':str(pathdata)}, **args)
- if stroke!=None:
- self.attributes['stroke']=stroke
- if fill!=None:
- self.attributes['fill']=fill
- if stroke_width!=None:
- self.attributes['stroke-width']=stroke_width
- if id!=None:
- self.attributes['id']=id
+
+ def __init__(self, pathdata, fill=None, stroke=None, stroke_width=None, id=None, **args):
+ SVGelement.__init__(self, 'path', {'d': str(pathdata)}, **args)
+ if stroke != None:
+ self.attributes['stroke'] = stroke
+ if fill != None:
+ self.attributes['fill'] = fill
+ if stroke_width != None:
+ self.attributes['stroke-width'] = stroke_width
+ if id != None:
+ self.attributes['id'] = id
class text(SVGelement):
@@ -580,20 +600,21 @@ class text(SVGelement):
a text element can bge used for displaying text on the screen
"""
- def __init__(self,x=None,y=None,text=None,font_size=None,font_family=None,text_anchor=None,**args):
+
+ def __init__(self, x=None, y=None, text=None, font_size=None, font_family=None, text_anchor=None, **args):
SVGelement.__init__(self, 'text', **args)
- if x!=None:
- self.attributes['x']=x
- if y!=None:
- self.attributes['y']=y
- if font_size!=None:
- self.attributes['font-size']=font_size
- if font_family!=None:
- self.attributes['font-family']=font_family
- if text!=None:
- self.text=text
- if text_anchor!=None:
- self.attributes['text-anchor']=text_anchor
+ if x != None:
+ self.attributes['x'] = x
+ if y != None:
+ self.attributes['y'] = y
+ if font_size != None:
+ self.attributes['font-size'] = font_size
+ if font_family != None:
+ self.attributes['font-family'] = font_family
+ if text != None:
+ self.text = text
+ if text_anchor != None:
+ self.attributes['text-anchor'] = text_anchor
class textpath(SVGelement):
@@ -601,10 +622,12 @@ class textpath(SVGelement):
a textpath places a text on a path which is referenced by a link.
"""
- def __init__(self,link,text=None,**args):
- SVGelement.__init__(self, 'textPath', {'xlink:href':link}, **args)
- if text!=None:
- self.text=text
+
+ def __init__(self, link, text=None, **args):
+ SVGelement.__init__(self, 'textPath', {'xlink:href': link}, **args)
+ if text != None:
+ self.text = text
+
class pattern(SVGelement):
"""p=pattern(x,y,width,height,patternUnits,**args)
@@ -613,18 +636,20 @@ class pattern(SVGelement):
graphic object which can be replicated ("tiled") at fixed intervals
in x and y to cover the areas to be painted.
"""
- def __init__(self,x=None,y=None,width=None,height=None,patternUnits=None,**args):
+
+ def __init__(self, x=None, y=None, width=None, height=None, patternUnits=None, **args):
SVGelement.__init__(self, 'pattern', **args)
- if x!=None:
- self.attributes['x']=x
- if y!=None:
- self.attributes['y']=y
- if width!=None:
- self.attributes['width']=width
- if height!=None:
- self.attributes['height']=height
- if patternUnits!=None:
- self.attributes['patternUnits']=patternUnits
+ if x != None:
+ self.attributes['x'] = x
+ if y != None:
+ self.attributes['y'] = y
+ if width != None:
+ self.attributes['width'] = width
+ if height != None:
+ self.attributes['height'] = height
+ if patternUnits != None:
+ self.attributes['patternUnits'] = patternUnits
+
class title(SVGelement):
"""t=title(text,**args)
@@ -632,10 +657,12 @@ class title(SVGelement):
a title is a text element. The text is displayed in the title bar
add at least one to the root svg element
"""
- def __init__(self,text=None,**args):
+
+ def __init__(self, text=None, **args):
SVGelement.__init__(self, 'title', **args)
- if text!=None:
- self.text=text
+ if text != None:
+ self.text = text
+
class description(SVGelement):
"""d=description(text,**args)
@@ -643,10 +670,12 @@ class description(SVGelement):
a description can be added to any element and is used for a tooltip
Add this element before adding other elements.
"""
- def __init__(self,text=None,**args):
+
+ def __init__(self, text=None, **args):
SVGelement.__init__(self, 'desc', **args)
- if text!=None:
- self.text=text
+ if text != None:
+ self.text = text
+
class lineargradient(SVGelement):
"""lg=lineargradient(x1,y1,x2,y2,id,**args)
@@ -654,18 +683,20 @@ class lineargradient(SVGelement):
defines a lineargradient using two xy pairs.
stop elements van be added to define the gradient colors.
"""
- def __init__(self,x1=None,y1=None,x2=None,y2=None,id=None,**args):
+
+ def __init__(self, x1=None, y1=None, x2=None, y2=None, id=None, **args):
SVGelement.__init__(self, 'linearGradient', **args)
- if x1!=None:
- self.attributes['x1']=x1
- if y1!=None:
- self.attributes['y1']=y1
- if x2!=None:
- self.attributes['x2']=x2
- if y2!=None:
- self.attributes['y2']=y2
- if id!=None:
- self.attributes['id']=id
+ if x1 != None:
+ self.attributes['x1'] = x1
+ if y1 != None:
+ self.attributes['y1'] = y1
+ if x2 != None:
+ self.attributes['x2'] = x2
+ if y2 != None:
+ self.attributes['y2'] = y2
+ if id != None:
+ self.attributes['id'] = id
+
class radialgradient(SVGelement):
"""rg=radialgradient(cx,cy,r,fx,fy,id,**args)
@@ -673,38 +704,43 @@ class radialgradient(SVGelement):
defines a radial gradient using a outer circle which are defined by a cx,cy and r and by using a focalpoint.
stop elements van be added to define the gradient colors.
"""
- def __init__(self,cx=None,cy=None,r=None,fx=None,fy=None,id=None,**args):
+
+ def __init__(self, cx=None, cy=None, r=None, fx=None, fy=None, id=None, **args):
SVGelement.__init__(self, 'radialGradient', **args)
- if cx!=None:
- self.attributes['cx']=cx
- if cy!=None:
- self.attributes['cy']=cy
- if r!=None:
- self.attributes['r']=r
- if fx!=None:
- self.attributes['fx']=fx
- if fy!=None:
- self.attributes['fy']=fy
- if id!=None:
- self.attributes['id']=id
+ if cx != None:
+ self.attributes['cx'] = cx
+ if cy != None:
+ self.attributes['cy'] = cy
+ if r != None:
+ self.attributes['r'] = r
+ if fx != None:
+ self.attributes['fx'] = fx
+ if fy != None:
+ self.attributes['fy'] = fy
+ if id != None:
+ self.attributes['id'] = id
+
class stop(SVGelement):
"""st=stop(offset,stop_color,**args)
Puts a stop color at the specified radius
"""
- def __init__(self,offset,stop_color=None,**args):
- SVGelement.__init__(self, 'stop', {'offset':offset}, **args)
- if stop_color!=None:
- self.attributes['stop-color']=stop_color
+
+ def __init__(self, offset, stop_color=None, **args):
+ SVGelement.__init__(self, 'stop', {'offset': offset}, **args)
+ if stop_color != None:
+ self.attributes['stop-color'] = stop_color
+
class style(SVGelement):
"""st=style(type,cdata=None,**args)
Add a CDATA element to this element for defing in line stylesheets etc..
"""
- def __init__(self,type,cdata=None,**args):
- SVGelement.__init__(self, 'style', {'type':type}, cdata=cdata, **args)
+
+ def __init__(self, type, cdata=None, **args):
+ SVGelement.__init__(self, 'style', {'type': type}, cdata=cdata, **args)
class image(SVGelement):
@@ -712,22 +748,26 @@ class image(SVGelement):
adds an image to the drawing. Supported formats are .png, .jpg and .svg.
"""
- def __init__(self,url,x=None,y=None,width=None,height=None,**args):
- if width==None or height==None:
+
+ def __init__(self, url, x=None, y=None, width=None, height=None, **args):
+ if width == None or height == None:
raise ValueError('both height and width are required')
- SVGelement.__init__(self, 'image', {'xlink:href':url,'width':width,'height':height}, **args)
- if x!=None:
- self.attributes['x']=x
- if y!=None:
- self.attributes['y']=y
+ SVGelement.__init__(
+ self, 'image', {'xlink:href': url, 'width': width, 'height': height}, **args)
+ if x != None:
+ self.attributes['x'] = x
+ if y != None:
+ self.attributes['y'] = y
+
class cursor(SVGelement):
"""c=cursor(url,**args)
defines a custom cursor for a element or a drawing
"""
- def __init__(self,url,**args):
- SVGelement.__init__(self, 'cursor', {'xlink:href':url}, **args)
+
+ def __init__(self, url, **args):
+ SVGelement.__init__(self, 'cursor', {'xlink:href': url}, **args)
class marker(SVGelement):
@@ -736,20 +776,22 @@ class marker(SVGelement):
defines a marker which can be used as an endpoint for a line or other pathtypes
add an element to it which should be used as a marker.
"""
- def __init__(self,id=None,viewBox=None,refx=None,refy=None,markerWidth=None,markerHeight=None,**args):
+
+ def __init__(self, id=None, viewBox=None, refx=None, refy=None, markerWidth=None, markerHeight=None, **args):
SVGelement.__init__(self, 'marker', **args)
- if id!=None:
- self.attributes['id']=id
- if viewBox!=None:
- self.attributes['viewBox']=_viewboxlist(viewBox)
- if refx!=None:
- self.attributes['refX']=refx
- if refy!=None:
- self.attributes['refY']=refy
- if markerWidth!=None:
- self.attributes['markerWidth']=markerWidth
- if markerHeight!=None:
- self.attributes['markerHeight']=markerHeight
+ if id != None:
+ self.attributes['id'] = id
+ if viewBox != None:
+ self.attributes['viewBox'] = _viewboxlist(viewBox)
+ if refx != None:
+ self.attributes['refX'] = refx
+ if refy != None:
+ self.attributes['refY'] = refy
+ if markerWidth != None:
+ self.attributes['markerWidth'] = markerWidth
+ if markerHeight != None:
+ self.attributes['markerHeight'] = markerHeight
+
class group(SVGelement):
"""g=group(id,**args)
@@ -757,10 +799,12 @@ class group(SVGelement):
a group is defined by an id and is used to contain elements
g.addElement(SVGelement)
"""
- def __init__(self,id=None,**args):
+
+ def __init__(self, id=None, **args):
SVGelement.__init__(self, 'g', **args)
- if id!=None:
- self.attributes['id']=id
+ if id != None:
+ self.attributes['id'] = id
+
class symbol(SVGelement):
"""sy=symbol(id,viewbox,**args)
@@ -771,21 +815,24 @@ class symbol(SVGelement):
sy.addElement(SVGelement)
"""
- def __init__(self,id=None,viewBox=None,**args):
+ def __init__(self, id=None, viewBox=None, **args):
SVGelement.__init__(self, 'symbol', **args)
- if id!=None:
- self.attributes['id']=id
- if viewBox!=None:
- self.attributes['viewBox']=_viewboxlist(viewBox)
+ if id != None:
+ self.attributes['id'] = id
+ if viewBox != None:
+ self.attributes['viewBox'] = _viewboxlist(viewBox)
+
class defs(SVGelement):
"""d=defs(**args)
container for defining elements
"""
- def __init__(self,**args):
+
+ def __init__(self, **args):
SVGelement.__init__(self, 'defs', **args)
+
class switch(SVGelement):
"""sw=switch(**args)
@@ -793,7 +840,8 @@ class switch(SVGelement):
requiredFeatures, requiredExtensions and systemLanguage.
Refer to the SVG specification for details.
"""
- def __init__(self,**args):
+
+ def __init__(self, **args):
SVGelement.__init__(self, 'switch', **args)
@@ -802,17 +850,18 @@ class use(SVGelement):
references a symbol by linking to its id and its position, height and width
"""
- def __init__(self,link,x=None,y=None,width=None,height=None,**args):
- SVGelement.__init__(self, 'use', {'xlink:href':link}, **args)
- if x!=None:
- self.attributes['x']=x
- if y!=None:
- self.attributes['y']=y
- if width!=None:
- self.attributes['width']=width
- if height!=None:
- self.attributes['height']=height
+ def __init__(self, link, x=None, y=None, width=None, height=None, **args):
+ SVGelement.__init__(self, 'use', {'xlink:href': link}, **args)
+ if x != None:
+ self.attributes['x'] = x
+ if y != None:
+ self.attributes['y'] = y
+
+ if width != None:
+ self.attributes['width'] = width
+ if height != None:
+ self.attributes['height'] = height
class link(SVGelement):
@@ -821,17 +870,21 @@ class link(SVGelement):
a link is defined by a hyperlink. add elements which have to be linked
a.addElement(SVGelement)
"""
- def __init__(self,link='',**args):
- SVGelement.__init__(self, 'a', {'xlink:href':link}, **args)
+
+ def __init__(self, link='', **args):
+ SVGelement.__init__(self, 'a', {'xlink:href': link}, **args)
+
class view(SVGelement):
"""v=view(id,**args)
a view can be used to create a view with different attributes"""
- def __init__(self,id=None,**args):
+
+ def __init__(self, id=None, **args):
SVGelement.__init__(self, 'view', **args)
- if id!=None:
- self.attributes['id']=id
+ if id != None:
+ self.attributes['id'] = id
+
class script(SVGelement):
"""sc=script(type,type,cdata,**args)
@@ -839,78 +892,94 @@ class script(SVGelement):
adds a script element which contains CDATA to the SVG drawing
"""
- def __init__(self,type,cdata=None,**args):
- SVGelement.__init__(self, 'script', {'type':type}, cdata=cdata, **args)
+
+ def __init__(self, type, cdata=None, **args):
+ SVGelement.__init__(
+ self, 'script', {'type': type}, cdata=cdata, **args)
+
class animate(SVGelement):
"""an=animate(attribute,from,to,during,**args)
animates an attribute.
"""
- def __init__(self,attribute,fr=None,to=None,dur=None,**args):
- SVGelement.__init__(self, 'animate', {'attributeName':attribute}, **args)
- if fr!=None:
- self.attributes['from']=fr
- if to!=None:
- self.attributes['to']=to
- if dur!=None:
- self.attributes['dur']=dur
+
+ def __init__(self, attribute, fr=None, to=None, dur=None, **args):
+ SVGelement.__init__(
+ self, 'animate', {'attributeName': attribute}, **args)
+ if fr != None:
+ self.attributes['from'] = fr
+ if to != None:
+ self.attributes['to'] = to
+ if dur != None:
+ self.attributes['dur'] = dur
+
class animateMotion(SVGelement):
"""an=animateMotion(pathdata,dur,**args)
animates a SVGelement over the given path in dur seconds
"""
- def __init__(self,pathdata,dur,**args):
+
+ def __init__(self, pathdata, dur, **args):
SVGelement.__init__(self, 'animateMotion', **args)
- if pathdata!=None:
- self.attributes['path']=str(pathdata)
- if dur!=None:
- self.attributes['dur']=dur
+ if pathdata != None:
+ self.attributes['path'] = str(pathdata)
+ if dur != None:
+ self.attributes['dur'] = dur
+
class animateTransform(SVGelement):
"""antr=animateTransform(type,from,to,dur,**args)
transform an element from and to a value.
"""
- def __init__(self,type=None,fr=None,to=None,dur=None,**args):
- SVGelement.__init__(self, 'animateTransform', {'attributeName':'transform'}, **args)
+
+ def __init__(self, type=None, fr=None, to=None, dur=None, **args):
+ SVGelement.__init__(self, 'animateTransform', {
+ 'attributeName': 'transform'}, **args)
# As far as I know the attributeName is always transform
- if type!=None:
- self.attributes['type']=type
- if fr!=None:
- self.attributes['from']=fr
- if to!=None:
- self.attributes['to']=to
- if dur!=None:
- self.attributes['dur']=dur
+ if type != None:
+ self.attributes['type'] = type
+ if fr != None:
+ self.attributes['from'] = fr
+ if to != None:
+ self.attributes['to'] = to
+ if dur != None:
+ self.attributes['dur'] = dur
+
+
class animateColor(SVGelement):
"""ac=animateColor(attribute,type,from,to,dur,**args)
Animates the color of a element
"""
- def __init__(self,attribute,type=None,fr=None,to=None,dur=None,**args):
- SVGelement.__init__(self, 'animateColor', {'attributeName':attribute}, **args)
- if type!=None:
- self.attributes['type']=type
- if fr!=None:
- self.attributes['from']=fr
- if to!=None:
- self.attributes['to']=to
- if dur!=None:
- self.attributes['dur']=dur
+
+ def __init__(self, attribute, type=None, fr=None, to=None, dur=None, **args):
+ SVGelement.__init__(self, 'animateColor', {
+ 'attributeName': attribute}, **args)
+ if type != None:
+ self.attributes['type'] = type
+ if fr != None:
+ self.attributes['from'] = fr
+ if to != None:
+ self.attributes['to'] = to
+ if dur != None:
+ self.attributes['dur'] = dur
+
+
class set(SVGelement):
"""st=set(attribute,to,during,**args)
sets an attribute to a value for a
"""
- def __init__(self,attribute,to=None,dur=None,**args):
- SVGelement.__init__(self, 'set', {'attributeName':attribute}, **args)
- if to!=None:
- self.attributes['to']=to
- if dur!=None:
- self.attributes['dur']=dur
+ def __init__(self, attribute, to=None, dur=None, **args):
+ SVGelement.__init__(self, 'set', {'attributeName': attribute}, **args)
+ if to != None:
+ self.attributes['to'] = to
+ if dur != None:
+ self.attributes['dur'] = dur
class svg(SVGelement):
@@ -928,15 +997,17 @@ class svg(SVGelement):
d.setSVG(s)
d.toXml()
"""
- def __init__(self,viewBox=None, width=None, height=None,**args):
+
+ def __init__(self, viewBox=None, width=None, height=None, **args):
SVGelement.__init__(self, 'svg', **args)
- if viewBox!=None:
- self.attributes['viewBox']=_viewboxlist(viewBox)
- if width!=None:
- self.attributes['width']=width
- if height!=None:
- self.attributes['height']=height
- self.namespace="http://www.w3.org/2000/svg"
+ if viewBox != None:
+ self.attributes['viewBox'] = _viewboxlist(viewBox)
+ if width != None:
+ self.attributes['width'] = width
+ if height != None:
+ self.attributes['height'] = height
+ self.namespace = "http://www.w3.org/2000/svg"
+
class drawing:
"""d=drawing()
@@ -950,29 +1021,32 @@ class drawing:
"""
def __init__(self, entity={}):
- self.svg=None
+ self.svg = None
self.entity = entity
+
def setSVG(self, svg):
- self.svg=svg
+ self.svg = svg
# Voeg een element toe aan de grafiek toe.
- if use_dom_implementation==0:
- def toXml(self, filename='',compress=False):
+ if use_dom_implementation == 0:
+ def toXml(self, filename='', compress=False):
import io
- xml=io.StringIO()
+ xml = io.StringIO()
xml.write("<?xml version='1.0' encoding='UTF-8'?>\n")
- xml.write("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"")
+ xml.write(
+ "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"")
if self.entity:
xml.write(" [\n")
for item in list(self.entity.keys()):
- xml.write("<!ENTITY %s \"%s\">\n" % (item, self.entity[item]))
+ xml.write("<!ENTITY %s \"%s\">\n" %
+ (item, self.entity[item]))
xml.write("]")
xml.write(">\n")
self.svg.toXml(0, xml)
if not filename:
if compress:
import gzip
- f=io.StringIO()
- zf=gzip.GzipFile(fileobj=f, mode='wb')
+ f = io.StringIO()
+ zf = gzip.GzipFile(fileobj=f, mode='wb')
zf.write(xml.getvalue())
zf.close()
f.seek(0)
@@ -980,57 +1054,62 @@ class drawing:
else:
return xml.getvalue()
else:
- if filename[-4:]=='svgz':
+ if filename[-4:] == 'svgz':
import gzip
- f=gzip.GzipFile(filename=filename, mode="wb", compresslevel=9)
+ f = gzip.GzipFile(filename=filename,
+ mode="wb", compresslevel=9)
f.write(xml.getvalue())
f.close()
else:
- f=file(filename, 'w')
+ f = file(filename, 'w')
f.write(xml.getvalue())
f.close()
else:
- def toXml(self,filename='',compress=False):
+ def toXml(self, filename='', compress=False):
"""drawing.toXml() ---->to the screen
drawing.toXml(filename)---->to the file
writes a svg drawing to the screen or to a file
compresses if filename ends with svgz or if compress is true
"""
- doctype = implementation.createDocumentType('svg', "-//W3C//DTD SVG 1.0//EN""", 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ')
+ doctype = implementation.createDocumentType(
+ 'svg', "-//W3C//DTD SVG 1.0//EN""", 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ')
global root
# root is defined global so it can be used by the appender. Its also possible to use it as an arugument but
# that is a bit messy.
- root=implementation.createDocument(None, None, doctype)
+ root = implementation.createDocument(None, None, doctype)
# Create the xml document.
global appender
+
def appender(element, elementroot):
"""This recursive function appends elements to an element and sets the attributes
and type. It stops when alle elements have been appended"""
if element.namespace:
- e=root.createElementNS(element.namespace, element.type)
+ e = root.createElementNS(element.namespace, element.type)
else:
- e=root.createElement(element.type)
+ e = root.createElement(element.type)
if element.text:
- textnode=root.createTextNode(element.text)
+ textnode = root.createTextNode(element.text)
e.appendChild(textnode)
- for attribute in list(element.attributes.keys()): #in element.attributes is supported from python 2.2
- e.setAttribute(attribute, str(element.attributes[attribute]))
+ # in element.attributes is supported from python 2.2
+ for attribute in list(element.attributes.keys()):
+ e.setAttribute(attribute, str(
+ element.attributes[attribute]))
if element.elements:
for el in element.elements:
- e=appender(el, e)
+ e = appender(el, e)
elementroot.appendChild(e)
return elementroot
- root=appender(self.svg, root)
+ root = appender(self.svg, root)
if not filename:
import io
- xml=io.StringIO()
+ xml = io.StringIO()
PrettyPrint(root, xml)
if compress:
import gzip
- f=io.StringIO()
- zf=gzip.GzipFile(fileobj=f, mode='wb')
+ f = io.StringIO()
+ zf = gzip.GzipFile(fileobj=f, mode='wb')
zf.write(xml.getvalue())
zf.close()
f.seek(0)
@@ -1039,63 +1118,67 @@ class drawing:
return xml.getvalue()
else:
try:
- if filename[-4:]=='svgz':
+ if filename[-4:] == 'svgz':
import gzip
import io
- xml=io.StringIO()
+ xml = io.StringIO()
PrettyPrint(root, xml)
- f=gzip.GzipFile(filename=filename, mode='wb', compresslevel=9)
+ f = gzip.GzipFile(filename=filename,
+ mode='wb', compresslevel=9)
f.write(xml.getvalue())
f.close()
else:
- f=open(filename, 'w')
+ f = open(filename, 'w')
PrettyPrint(root, f)
f.close()
except:
print(("Cannot write SVG file: " + filename))
+
def validate(self):
try:
import xml.parsers.xmlproc.xmlval
except:
- raise exceptions.ImportError('PyXml is required for validating SVG')
- svg=self.toXml()
- xv=xml.parsers.xmlproc.xmlval.XMLValidator()
+ raise exceptions.ImportError(
+ 'PyXml is required for validating SVG')
+ svg = self.toXml()
+ xv = xml.parsers.xmlproc.xmlval.XMLValidator()
try:
xv.feed(svg)
except:
raise Exception("SVG is not well formed, see messages above")
else:
print("SVG well formed")
-if __name__=='__main__':
- d=drawing()
- s=svg((0, 0, 100, 100))
- r=rect(-100, -100, 300, 300, 'cyan')
+if __name__ == '__main__':
+
+ d = drawing()
+ s = svg((0, 0, 100, 100))
+ r = rect(-100, -100, 300, 300, 'cyan')
s.addElement(r)
- t=title('SVGdraw Demo')
+ t = title('SVGdraw Demo')
s.addElement(t)
- g=group('animations')
- e=ellipse(0, 0, 5, 2)
+ g = group('animations')
+ e = ellipse(0, 0, 5, 2)
g.addElement(e)
- c=circle(0, 0, 1, 'red')
+ c = circle(0, 0, 1, 'red')
g.addElement(c)
- pd=pathdata(0, -10)
+ pd = pathdata(0, -10)
for i in range(6):
pd.relsmbezier(10, 5, 0, 10)
pd.relsmbezier(-10, 5, 0, 10)
- an=animateMotion(pd, 10)
- an.attributes['rotate']='auto-reverse'
- an.attributes['repeatCount']="indefinite"
+ an = animateMotion(pd, 10)
+ an.attributes['rotate'] = 'auto-reverse'
+ an.attributes['repeatCount'] = "indefinite"
g.addElement(an)
s.addElement(g)
for i in range(20, 120, 20):
- u=use('#animations', i, 0)
+ u = use('#animations', i, 0)
s.addElement(u)
for i in range(0, 120, 20):
for j in range(5, 105, 10):
- c=circle(i, j, 1, 'red', 'black', .5)
+ c = circle(i, j, 1, 'red', 'black', .5)
s.addElement(c)
d.setSVG(s)
diff --git a/wqflask/utility/temp_data.py b/wqflask/utility/temp_data.py
index 4144ae00..07c5a318 100644
--- a/wqflask/utility/temp_data.py
+++ b/wqflask/utility/temp_data.py
@@ -2,7 +2,8 @@ from redis import Redis
import simplejson as json
-class TempData(object):
+
+class TempData:
def __init__(self, temp_uuid):
self.temp_uuid = temp_uuid
@@ -11,7 +12,7 @@ class TempData(object):
def store(self, field, value):
self.redis.hset(self.key, field, value)
- self.redis.expire(self.key, 60*15) # Expire in 15 minutes
+ self.redis.expire(self.key, 60 * 15) # Expire in 15 minutes
def get_all(self):
return self.redis.hgetall(self.key)
diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py
index 65df59c3..e28abb48 100644
--- a/wqflask/utility/tools.py
+++ b/wqflask/utility/tools.py
@@ -9,16 +9,18 @@ from wqflask import app
# Use the standard logger here to avoid a circular dependency
import logging
-logger = logging.getLogger(__name__ )
+logger = logging.getLogger(__name__)
OVERRIDES = {}
+
def app_set(command_id, value):
"""Set application wide value"""
app.config.setdefault(command_id, value)
return value
-def get_setting(command_id,guess=None):
+
+def get_setting(command_id, guess=None):
"""Resolve a setting from the environment or the global settings in
app.config, with valid_path is a function checking whether the
path points to an expected directory and returns the full path to
@@ -54,7 +56,7 @@ def get_setting(command_id,guess=None):
# print("Looking for "+command_id+"\n")
command = value(os.environ.get(command_id))
if command is None or command == "":
- command = OVERRIDES.get(command_id) # currently not in use
+ command = OVERRIDES.get(command_id) # currently not in use
if command is None:
# ---- Check whether setting exists in app
command = value(app.config.get(command_id))
@@ -62,16 +64,19 @@ def get_setting(command_id,guess=None):
command = value(guess)
if command is None or command == "":
# print command
- raise Exception(command_id+' setting unknown or faulty (update default_settings.py?).')
+ raise Exception(
+ command_id + ' setting unknown or faulty (update default_settings.py?).')
# print("Set "+command_id+"="+str(command))
return command
+
def get_setting_bool(id):
v = get_setting(id)
if v not in [0, False, 'False', 'FALSE', None]:
- return True
+ return True
return False
+
def get_setting_int(id):
v = get_setting(id)
if isinstance(v, str):
@@ -80,69 +85,83 @@ def get_setting_int(id):
return 0
return v
+
def valid_bin(bin):
if os.path.islink(bin) or valid_file(bin):
return bin
return None
+
def valid_file(fn):
if os.path.isfile(fn):
return fn
return None
+
def valid_path(dir):
if os.path.isdir(dir):
return dir
return None
+
def js_path(module=None):
"""
Find the JS module in the two paths
"""
- try_gn = get_setting("JS_GN_PATH")+"/"+module
+ try_gn = get_setting("JS_GN_PATH") + "/" + module
if valid_path(try_gn):
return try_gn
- try_guix = get_setting("JS_GUIX_PATH")+"/"+module
+ try_guix = get_setting("JS_GUIX_PATH") + "/" + module
if valid_path(try_guix):
return try_guix
- raise "No JS path found for "+module+" (if not in Guix check JS_GN_PATH)"
+ raise "No JS path found for " + module + \
+ " (if not in Guix check JS_GN_PATH)"
+
def reaper_command(guess=None):
return get_setting("REAPER_COMMAND", guess)
+
def gemma_command(guess=None):
return assert_bin(get_setting("GEMMA_COMMAND", guess))
+
def gemma_wrapper_command(guess=None):
return assert_bin(get_setting("GEMMA_WRAPPER_COMMAND", guess))
+
def plink_command(guess=None):
return assert_bin(get_setting("PLINK_COMMAND", guess))
+
def flat_file_exists(subdir):
base = get_setting("GENENETWORK_FILES")
- return valid_path(base+"/"+subdir)
+ return valid_path(base + "/" + subdir)
+
def flat_files(subdir=None):
base = get_setting("GENENETWORK_FILES")
if subdir:
- return assert_dir(base+"/"+subdir)
+ return assert_dir(base + "/" + subdir)
return assert_dir(base)
+
def assert_bin(fn):
if not valid_bin(fn):
- raise Exception("ERROR: can not find binary "+fn)
+ raise Exception("ERROR: can not find binary " + fn)
return fn
+
def assert_dir(dir):
if not valid_path(dir):
- raise Exception("ERROR: can not find directory "+dir)
+ raise Exception("ERROR: can not find directory " + dir)
return dir
+
def assert_writable_dir(dir):
try:
fn = dir + "/test.txt"
- fh = open( fn, 'w' )
+ fh = open(fn, 'w')
fh.write("I am writing this text to the file\n")
fh.close()
os.remove(fn)
@@ -150,16 +169,19 @@ def assert_writable_dir(dir):
raise Exception('Unable to write test.txt to directory ' + dir)
return dir
+
def assert_file(fn):
if not valid_file(fn):
- raise Exception('Unable to find file '+fn)
+ raise Exception('Unable to find file ' + fn)
return fn
+
def mk_dir(dir):
if not valid_path(dir):
os.makedirs(dir)
return assert_dir(dir)
+
def locate(name, subdir=None):
"""
Locate a static flat file in the GENENETWORK_FILES environment.
@@ -168,19 +190,22 @@ def locate(name, subdir=None):
"""
base = get_setting("GENENETWORK_FILES")
if subdir:
- base = base+"/"+subdir
+ base = base + "/" + subdir
if valid_path(base):
lookfor = base + "/" + name
if valid_file(lookfor):
- logger.info("Found: file "+lookfor+"\n")
+ logger.info("Found: file " + lookfor + "\n")
return lookfor
else:
- raise Exception("Can not locate "+lookfor)
- if subdir: sys.stderr.write(subdir)
- raise Exception("Can not locate "+name+" in "+base)
+ raise Exception("Can not locate " + lookfor)
+ if subdir:
+ sys.stderr.write(subdir)
+ raise Exception("Can not locate " + name + " in " + base)
+
def locate_phewas(name, subdir=None):
- return locate(name, '/phewas/'+subdir)
+ return locate(name, '/phewas/' + subdir)
+
def locate_ignore_error(name, subdir=None):
"""
@@ -191,35 +216,38 @@ def locate_ignore_error(name, subdir=None):
"""
base = get_setting("GENENETWORK_FILES")
if subdir:
- base = base+"/"+subdir
+ base = base + "/" + subdir
if valid_path(base):
lookfor = base + "/" + name
if valid_file(lookfor):
- logger.debug("Found: file "+name+"\n")
+ logger.debug("Found: file " + name + "\n")
return lookfor
- logger.info("WARNING: file "+name+" not found\n")
+ logger.info("WARNING: file " + name + " not found\n")
return None
+
def tempdir():
"""
Get UNIX TMPDIR by default
"""
return valid_path(get_setting("TMPDIR", "/tmp"))
-BLUE = '\033[94m'
+
+BLUE = '\033[94m'
GREEN = '\033[92m'
-BOLD = '\033[1m'
-ENDC = '\033[0m'
+BOLD = '\033[1m'
+ENDC = '\033[0m'
+
def show_settings():
from utility.tools import LOG_LEVEL
- print(("Set global log level to "+BLUE+LOG_LEVEL+ENDC))
+ print(("Set global log level to " + BLUE + LOG_LEVEL + ENDC))
log_level = getattr(logging, LOG_LEVEL.upper())
logging.basicConfig(level=log_level)
logger.info(OVERRIDES)
- logger.info(BLUE+"Mr. Mojo Risin 2"+ENDC)
+ logger.info(BLUE + "Mr. Mojo Risin 2" + ENDC)
keylist = list(app.config.keys())
print("runserver.py: ****** Webserver configuration - k,v pairs from app.config ******")
keylist.sort()
@@ -231,35 +259,35 @@ def show_settings():
# Cached values
-GN_VERSION = get_setting('GN_VERSION')
-HOME = get_setting('HOME')
-SERVER_PORT = get_setting('SERVER_PORT')
-WEBSERVER_MODE = get_setting('WEBSERVER_MODE')
-GN2_BASE_URL = get_setting('GN2_BASE_URL')
-GN2_BRANCH_URL = get_setting('GN2_BRANCH_URL')
-GN_SERVER_URL = get_setting('GN_SERVER_URL')
-SERVER_PORT = get_setting_int('SERVER_PORT')
-SQL_URI = get_setting('SQL_URI')
-LOG_LEVEL = get_setting('LOG_LEVEL')
-LOG_LEVEL_DEBUG = get_setting_int('LOG_LEVEL_DEBUG')
-LOG_SQL = get_setting_bool('LOG_SQL')
-LOG_SQL_ALCHEMY = get_setting_bool('LOG_SQL_ALCHEMY')
-LOG_BENCH = get_setting_bool('LOG_BENCH')
-LOG_FORMAT = "%(message)s" # not yet in use
-USE_REDIS = get_setting_bool('USE_REDIS')
-USE_GN_SERVER = get_setting_bool('USE_GN_SERVER')
-
-GENENETWORK_FILES = get_setting('GENENETWORK_FILES')
-JS_GUIX_PATH = get_setting('JS_GUIX_PATH')
+GN_VERSION = get_setting('GN_VERSION')
+HOME = get_setting('HOME')
+SERVER_PORT = get_setting('SERVER_PORT')
+WEBSERVER_MODE = get_setting('WEBSERVER_MODE')
+GN2_BASE_URL = get_setting('GN2_BASE_URL')
+GN2_BRANCH_URL = get_setting('GN2_BRANCH_URL')
+GN_SERVER_URL = get_setting('GN_SERVER_URL')
+SERVER_PORT = get_setting_int('SERVER_PORT')
+SQL_URI = get_setting('SQL_URI')
+LOG_LEVEL = get_setting('LOG_LEVEL')
+LOG_LEVEL_DEBUG = get_setting_int('LOG_LEVEL_DEBUG')
+LOG_SQL = get_setting_bool('LOG_SQL')
+LOG_SQL_ALCHEMY = get_setting_bool('LOG_SQL_ALCHEMY')
+LOG_BENCH = get_setting_bool('LOG_BENCH')
+LOG_FORMAT = "%(message)s" # not yet in use
+USE_REDIS = get_setting_bool('USE_REDIS')
+USE_GN_SERVER = get_setting_bool('USE_GN_SERVER')
+
+GENENETWORK_FILES = get_setting('GENENETWORK_FILES')
+JS_GUIX_PATH = get_setting('JS_GUIX_PATH')
assert_dir(JS_GUIX_PATH)
-JS_GN_PATH = get_setting('JS_GN_PATH')
+JS_GN_PATH = get_setting('JS_GN_PATH')
# assert_dir(JS_GN_PATH)
GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID')
GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET')
if GITHUB_CLIENT_ID != 'UNKNOWN' and GITHUB_CLIENT_SECRET:
GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id=" + \
- GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET
+ GITHUB_CLIENT_ID + "&client_secret=" + GITHUB_CLIENT_SECRET
GITHUB_API_URL = get_setting('GITHUB_API_URL')
ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID')
@@ -267,7 +295,8 @@ ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET')
ORCID_AUTH_URL = None
if ORCID_CLIENT_ID != 'UNKNOWN' and ORCID_CLIENT_SECRET:
ORCID_AUTH_URL = "https://orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + \
- ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET + "&redirect_uri=" + GN2_BRANCH_URL + "n/login/orcid_oauth2"
+ ORCID_CLIENT_ID + "&client_secret=" + ORCID_CLIENT_SECRET + \
+ "&redirect_uri=" + GN2_BRANCH_URL + "n/login/orcid_oauth2"
ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL')
ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST')
@@ -279,28 +308,29 @@ SMTP_CONNECT = get_setting('SMTP_CONNECT')
SMTP_USERNAME = get_setting('SMTP_USERNAME')
SMTP_PASSWORD = get_setting('SMTP_PASSWORD')
-REAPER_COMMAND = app_set("REAPER_COMMAND", reaper_command())
-GEMMA_COMMAND = app_set("GEMMA_COMMAND", gemma_command())
+REAPER_COMMAND = app_set("REAPER_COMMAND", reaper_command())
+GEMMA_COMMAND = app_set("GEMMA_COMMAND", gemma_command())
assert(GEMMA_COMMAND is not None)
-PLINK_COMMAND = app_set("PLINK_COMMAND", plink_command())
+PLINK_COMMAND = app_set("PLINK_COMMAND", plink_command())
GEMMA_WRAPPER_COMMAND = gemma_wrapper_command()
-TEMPDIR = tempdir() # defaults to UNIX TMPDIR
+TEMPDIR = tempdir() # defaults to UNIX TMPDIR
assert_dir(TEMPDIR)
# ---- Handle specific JS modules
JS_GUIX_PATH = get_setting("JS_GUIX_PATH")
assert_dir(JS_GUIX_PATH)
-assert_dir(JS_GUIX_PATH+'/cytoscape-panzoom')
+assert_dir(JS_GUIX_PATH + '/cytoscape-panzoom')
CSS_PATH = JS_GUIX_PATH # The CSS is bundled together with the JS
# assert_dir(JS_PATH)
-JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH", js_path("javascript-twitter-post-fetcher"))
+JS_TWITTER_POST_FETCHER_PATH = get_setting(
+ "JS_TWITTER_POST_FETCHER_PATH", js_path("javascript-twitter-post-fetcher"))
assert_dir(JS_TWITTER_POST_FETCHER_PATH)
-assert_file(JS_TWITTER_POST_FETCHER_PATH+"/js/twitterFetcher_min.js")
+assert_file(JS_TWITTER_POST_FETCHER_PATH + "/js/twitterFetcher_min.js")
JS_CYTOSCAPE_PATH = get_setting("JS_CYTOSCAPE_PATH", js_path("cytoscape"))
assert_dir(JS_CYTOSCAPE_PATH)
-assert_file(JS_CYTOSCAPE_PATH+'/cytoscape.min.js')
+assert_file(JS_CYTOSCAPE_PATH + '/cytoscape.min.js')
# assert_file(PHEWAS_FILES+"/auwerx/PheWAS_pval_EMMA_norm.RData")
diff --git a/wqflask/utility/type_checking.py b/wqflask/utility/type_checking.py
index 6b029317..00f14ba9 100644
--- a/wqflask/utility/type_checking.py
+++ b/wqflask/utility/type_checking.py
@@ -7,6 +7,7 @@ def is_float(value):
except:
return False
+
def is_int(value):
try:
int(value)
@@ -14,6 +15,7 @@ def is_int(value):
except:
return False
+
def is_str(value):
if value is None:
return False
@@ -23,19 +25,22 @@ def is_str(value):
except:
return False
-def get_float(vars_obj,name,default=None):
+
+def get_float(vars_obj, name, default=None):
if name in vars_obj:
if is_float(vars_obj[name]):
return float(vars_obj[name])
return default
-def get_int(vars_obj,name,default=None):
+
+def get_int(vars_obj, name, default=None):
if name in vars_obj:
if is_int(vars_obj[name]):
return float(vars_obj[name])
return default
-def get_string(vars_obj,name,default=None):
+
+def get_string(vars_obj, name, default=None):
if name in vars_obj:
if not vars_obj[name] is None:
return str(vars_obj[name])
diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py
index 5681fadf..0cb71567 100644
--- a/wqflask/utility/webqtlUtil.py
+++ b/wqflask/utility/webqtlUtil.py
@@ -33,44 +33,46 @@ from math import *
from base import webqtlConfig
# NL, 07/27/2010. moved from webqtlForm.py
-#Dict of Parents and F1 information, In the order of [F1, Mat, Pat]
-ParInfo ={
-'BXH':['BHF1', 'HBF1', 'C57BL/6J', 'C3H/HeJ'],
-'AKXD':['AKF1', 'KAF1', 'AKR/J', 'DBA/2J'],
-'BXD':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
-'C57BL-6JxC57BL-6NJF2':['', '', 'C57BL/6J', 'C57BL/6NJ'],
-'BXD300':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
-'B6BTBRF2':['B6BTBRF1', 'BTBRB6F1', 'C57BL/6J', 'BTBRT<+>tf/J'],
-'BHHBF2':['B6HF2', 'HB6F2', 'C57BL/6J', 'C3H/HeJ'],
-'BHF2':['B6HF2', 'HB6F2', 'C57BL/6J', 'C3H/HeJ'],
-'B6D2F2':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
-'BDF2-1999':['B6D2F2', 'D2B6F2', 'C57BL/6J', 'DBA/2J'],
-'BDF2-2005':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
-'CTB6F2':['CTB6F2', 'B6CTF2', 'C57BL/6J', 'Castaneous'],
-'CXB':['CBF1', 'BCF1', 'C57BL/6ByJ', 'BALB/cByJ'],
-'AXBXA':['ABF1', 'BAF1', 'C57BL/6J', 'A/J'],
-'AXB':['ABF1', 'BAF1', 'C57BL/6J', 'A/J'],
-'BXA':['BAF1', 'ABF1', 'C57BL/6J', 'A/J'],
-'LXS':['LSF1', 'SLF1', 'ISS', 'ILS'],
-'HXBBXH':['SHR_BNF1', 'BN_SHRF1', 'BN-Lx/Cub', 'SHR/OlaIpcv'],
-'BayXSha':['BayXShaF1', 'ShaXBayF1', 'Bay-0', 'Shahdara'],
-'ColXBur':['ColXBurF1', 'BurXColF1', 'Col-0', 'Bur-0'],
-'ColXCvi':['ColXCviF1', 'CviXColF1', 'Col-0', 'Cvi'],
-'SXM':['SMF1', 'MSF1', 'Steptoe', 'Morex'],
-'HRDP':['SHR_BNF1', 'BN_SHRF1', 'BN-Lx/Cub', 'SHR/OlaIpcv']
+# Dict of Parents and F1 information, In the order of [F1, Mat, Pat]
+ParInfo = {
+ 'BXH': ['BHF1', 'HBF1', 'C57BL/6J', 'C3H/HeJ'],
+ 'AKXD': ['AKF1', 'KAF1', 'AKR/J', 'DBA/2J'],
+ 'BXD': ['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
+ 'C57BL-6JxC57BL-6NJF2': ['', '', 'C57BL/6J', 'C57BL/6NJ'],
+ 'BXD300': ['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
+ 'B6BTBRF2': ['B6BTBRF1', 'BTBRB6F1', 'C57BL/6J', 'BTBRT<+>tf/J'],
+ 'BHHBF2': ['B6HF2', 'HB6F2', 'C57BL/6J', 'C3H/HeJ'],
+ 'BHF2': ['B6HF2', 'HB6F2', 'C57BL/6J', 'C3H/HeJ'],
+ 'B6D2F2': ['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
+ 'BDF2-1999': ['B6D2F2', 'D2B6F2', 'C57BL/6J', 'DBA/2J'],
+ 'BDF2-2005': ['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'],
+ 'CTB6F2': ['CTB6F2', 'B6CTF2', 'C57BL/6J', 'Castaneous'],
+ 'CXB': ['CBF1', 'BCF1', 'C57BL/6ByJ', 'BALB/cByJ'],
+ 'AXBXA': ['ABF1', 'BAF1', 'C57BL/6J', 'A/J'],
+ 'AXB': ['ABF1', 'BAF1', 'C57BL/6J', 'A/J'],
+ 'BXA': ['BAF1', 'ABF1', 'C57BL/6J', 'A/J'],
+ 'LXS': ['LSF1', 'SLF1', 'ISS', 'ILS'],
+ 'HXBBXH': ['SHR_BNF1', 'BN_SHRF1', 'BN-Lx/Cub', 'SHR/OlaIpcv'],
+ 'BayXSha': ['BayXShaF1', 'ShaXBayF1', 'Bay-0', 'Shahdara'],
+ 'ColXBur': ['ColXBurF1', 'BurXColF1', 'Col-0', 'Bur-0'],
+ 'ColXCvi': ['ColXCviF1', 'CviXColF1', 'Col-0', 'Cvi'],
+ 'SXM': ['SMF1', 'MSF1', 'Steptoe', 'Morex'],
+ 'HRDP': ['SHR_BNF1', 'BN_SHRF1', 'BN-Lx/Cub', 'SHR/OlaIpcv']
}
#########################################
# Accessory Functions
#########################################
-def genRandStr(prefix = "", length=8, chars=string.ascii_letters+string.digits):
+
+def genRandStr(prefix="", length=8, chars=string.ascii_letters + string.digits):
from random import choice
_str = prefix[:]
for i in range(length):
_str += choice(chars)
return _str
+
def ListNotNull(lst):
'''Obsolete - Use built in function any (or all or whatever)
@@ -83,14 +85,16 @@ def ListNotNull(lst):
return 1
return None
-def readLineCSV(line): ### dcrowell July 2008
+
+def readLineCSV(line): # dcrowell July 2008
"""Parses a CSV string of text and returns a list containing each element as a string.
Used by correlationPage"""
returnList = line.split('","')
- returnList[-1]=returnList[-1][:-2]
- returnList[0]=returnList[0][1:]
+ returnList[-1] = returnList[-1][:-2]
+ returnList[0] = returnList[0][1:]
return returnList
+
def cmpEigenValue(A, B):
try:
if A[0] > B[0]:
@@ -102,12 +106,13 @@ def cmpEigenValue(A, B):
except:
return 0
+
def hasAccessToConfidentialPhenotypeTrait(privilege, userName, authorized_users):
access_to_confidential_phenotype_trait = 0
if webqtlConfig.USERDICT[privilege] > webqtlConfig.USERDICT['user']:
access_to_confidential_phenotype_trait = 1
else:
- AuthorizedUsersList=[x.strip() for x in authorized_users.split(',')]
+ AuthorizedUsersList = [x.strip() for x in authorized_users.split(',')]
if userName in AuthorizedUsersList:
access_to_confidential_phenotype_trait = 1
return access_to_confidential_phenotype_trait