diff --git a/examples/dokk/config.py b/examples/dokk/config.py index 0323a34613db55427c16022f672ce468c61f49f8..18f40d53dfcc4b7b017ead849d426f30a287d47c 100644 --- a/examples/dokk/config.py +++ b/examples/dokk/config.py @@ -3,18 +3,96 @@ import string class Config: def __init__(self, path): + self._path = path + self.UpdateValues() + + def UpdateValues(self): config = ConfigParser.ConfigParser() - config.read(path) - - self.values = dict() + config.read(self._path) + self._values = dict() for section in config.sections(): section_dict = dict() for option in config.options(section): section_dict[str(option).upper()]=config.get(section, option) - self.values[str(section).lower()]=section_dict + self._values[str(section).lower()]=section_dict def __getattr__(self, item): item = str(item).lower() - if self.values.has_key(item): - return self.values[item] + if self._values.has_key(item): + return self._values[item] raise AttributeError(item) + + def Get(self, item): + return self.__getattr__(item) + +class MutableConfig(Config): + def __init__(self,path): + Config.__init__(self, path) + + def Set(self, section, key, value): + if not self._values.has_key(section): + self._values[section] = dict() + section_dict = self._values[section] + section_dict[key] = value + self.__save() + + def __save(self): + config = ConfigParser.ConfigParser() + file = open(self._path,"w") + for section, values in self._values.iteritems(): + config.add_section(section) + for k, v in values.iteritems(): + config.set(section, k, v) + config.write(file) + + +class TopTen(): + def __init__(self,path): + self._config = MutableConfig(path) + + + def IsTopTen(self,score): + self._config.UpdateValues() + try: + if score < float(self._config.str(10)["SCORE"]): + return True + except AttributeError: + return True + return False + + def GetDiff(self, score): + rank = self.GetRank(score) -1 + if(rank > 0): + return abs(score - float(self._config.Get(str(rank))["SCORE"])) + elif(rank == 0): + return 0 + else: + return abs(score - float(self._config.Get(str(10))["SCORE"])) + + def GetRank(self, score): + if self.IsTopTen(score): + for i in range(1,11): + try: + tt_score = float(self._config.Get(str(i))["SCORE"]) + if score < tt_score: + return i + except AttributeError: + return i + return -1 + + def SetValue(self, name, score): + rank = self.GetRank(score) + if rank > 0: + finish = False + for i in range(rank,11): + try: + old_name = self._config.Get(str(i))["NAME"] + old_score = self._config.Get(str(i))["SCORE"] + except AttributeError: + finish = True + self._config.Set(str(i), "NAME", name) + self._config.Set(str(i), "SCORE", score) + if finish: + break + name = old_name + score = old_score diff --git a/examples/dokk/datafiles/thrombin/level.ini b/examples/dokk/datafiles/thrombin/level.ini index be8587705ad072c830017fa2cdba7fab9fe08039..db9c259725016b202e8ea7331bfd61b4febcf99a 100644 --- a/examples/dokk/datafiles/thrombin/level.ini +++ b/examples/dokk/datafiles/thrombin/level.ini @@ -1,6 +1,7 @@ [Level] NAME: Thrombin DIFFICULTY: Medium +TIME: 60000 [Intro] TEXTTIME: 3000 @@ -53,6 +54,55 @@ TEXTCOLORGREEN9: 255 TEXTCOLORBLUE9: 0 TEXTSIZE9: 130 +[NTT] +TEXTTIME: 200 +TEXTCOLORRED: 255 +TEXTCOLORGREEN: 0 +TEXTCOLORBLUE: 0 +TEXTSIZE: 16 +TEXT_COUNT: 2 + +TEXT1: Leider haben Sie es nicht bis in die Top 10 geschafft. + Ihre Score ist um $DIFFERENCE zu hoch. +TEXTTIME1: 4000 +TEXTCOLORRED1: 255 +TEXTCOLORGREEN1: 64 +TEXTCOLORBLUE1: 0 +TEXTSIZE1: 50 + +TEXT2: RMSD: $RMSD + Zeitmalus: $TIMEMALUS + Endergebnis: $SCORE +TEXTTIME2: 8000 +TEXTCOLORRED2: 0 +TEXTCOLORGREEN2: 255 +TEXTCOLORBLUE2: 0 +TEXTSIZE2: 100 + +[TT] +TEXTTIME: 200 +TEXTCOLORRED: 255 +TEXTCOLORGREEN: 0 +TEXTCOLORBLUE: 0 +TEXTSIZE: 16 +TEXT_COUNT: 2 + +TEXT1: Bravo, sie wurden $RANKer! +TEXTTIME1: 4000 +TEXTCOLORRED1: 0 +TEXTCOLORGREEN1: 255 +TEXTCOLORBLUE1: 64 +TEXTSIZE1: 100 + +TEXT2: RMSD: $RMSD + Zeitmalus: $TIMEMALUS + Endergebnis: $SCORE +TEXTTIME2: 8000 +TEXTCOLORRED2: 0 +TEXTCOLORGREEN2: 255 +TEXTCOLORBLUE2: 0 +TEXTSIZE2: 100 + [Box] XMIN:-25 XMAX:40 @@ -71,7 +121,7 @@ ROTY:0.25 ROTZ:0.3 [Score] -FRAMESKIP: 20 +FRAMESKIP: 12 [Goal] RMSD: 0 diff --git a/examples/dokk/datafiles/thrombin/top_ten.ini b/examples/dokk/datafiles/thrombin/top_ten.ini new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/examples/dokk/datafiles/thrombinNoH/level.ini b/examples/dokk/datafiles/thrombinNoH/level.ini new file mode 100644 index 0000000000000000000000000000000000000000..1a7bc30886728ccc77481a03c4e6896a6fdd3e00 --- /dev/null +++ b/examples/dokk/datafiles/thrombinNoH/level.ini @@ -0,0 +1,113 @@ +[Level] +NAME: Thrombin +DIFFICULTY: Medium +TIME: 60000 + +[Intro] +TEXTTIME: 3000 +TEXTCOLORRED: 255 +TEXTCOLORGREEN: 255 +TEXTCOLORBLUE: 255 +TEXTSIZE: 16 +TEXT_COUNT: 4 + +TEXT1: 3 +TEXTTIME1: 150 +TEXTCOLORRED1: 255 +TEXTCOLORGREEN1: 0 +TEXTCOLORBLUE1: 0 +TEXTSIZE1: 40 + +TEXT2: 2 +TEXTTIME2: 150 +TEXTCOLORRED2: 255 +TEXTCOLORGREEN2: 165 +TEXTCOLORBLUE2: 0 +TEXTSIZE2: 70 + +TEXT3: 1 +TEXTTIME3: 150 +TEXTCOLORRED3: 255 +TEXTCOLORGREEN3: 255 +TEXTCOLORBLUE3: 0 +TEXTSIZE3: 100 + +TEXT4: LOS! +TEXTTIME4: 200 +TEXTCOLORRED4: 0 +TEXTCOLORGREEN4: 255 +TEXTCOLORBLUE4: 0 +TEXTSIZE4: 130 + +[NTT] +TEXTTIME: 200 +TEXTCOLORRED: 255 +TEXTCOLORGREEN: 0 +TEXTCOLORBLUE: 0 +TEXTSIZE: 16 +TEXT_COUNT: 2 + +TEXT1: Leider haben Sie es nicht bis in die Top 10 geschafft. + Ihre Score ist um $DIFFERENCE zu hoch. +TEXTTIME1: 4000 +TEXTCOLORRED1: 255 +TEXTCOLORGREEN1: 64 +TEXTCOLORBLUE1: 0 +TEXTSIZE1: 50 + +TEXT2: RMSD: $RMSD + Zeitmalus: $TIMEMALUS + Endergebnis: $SCORE +TEXTTIME2: 8000 +TEXTCOLORRED2: 0 +TEXTCOLORGREEN2: 255 +TEXTCOLORBLUE2: 0 +TEXTSIZE2: 100 + +[TT] +TEXTTIME: 200 +TEXTCOLORRED: 255 +TEXTCOLORGREEN: 0 +TEXTCOLORBLUE: 0 +TEXTSIZE: 16 +TEXT_COUNT: 2 + +TEXT1: Bravo, sie wurden $RANKer! +TEXTTIME1: 4000 +TEXTCOLORRED1: 0 +TEXTCOLORGREEN1: 255 +TEXTCOLORBLUE1: 64 +TEXTSIZE1: 100 + +TEXT2: RMSD: $RMSD + Zeitmalus: $TIMEMALUS + Endergebnis: $SCORE +TEXTTIME2: 8000 +TEXTCOLORRED2: 0 +TEXTCOLORGREEN2: 255 +TEXTCOLORBLUE2: 0 +TEXTSIZE2: 100 + +[Box] +XMIN:-25 +XMAX:40 +YMIN:-21 +YMAX:25 +ZMIN:-20 +ZMAX:100 + +[Start] +POSX:10.0 +POSY:-2.0 +POSZ:60.0 + +ROTX:-2.0 +ROTY:0.25 +ROTZ:0.3 + +[Score] +FRAMESKIP: 5 + +[Goal] +RMSD: 0 +SAVE: True diff --git a/examples/dokk/datafiles/thrombinNoH/top_ten.ini b/examples/dokk/datafiles/thrombinNoH/top_ten.ini new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/examples/dokk/dokk.py b/examples/dokk/dokk.py index a9c146944332da434727f6277707b670abb1b55a..aa14132326b05e9176d78cb98477e3baf31283c9 100644 --- a/examples/dokk/dokk.py +++ b/examples/dokk/dokk.py @@ -1,4 +1,5 @@ import glwin +import level class Dokk(object): def __new__(type, *args): @@ -9,19 +10,40 @@ class Dokk(object): def __init__(self): if not '_ready' in dir(self): self.gl_win=glwin.DokkGLWin(self) + self._levels = list() + self._current_index = -1 + self._current_level = None self._ready = True - def SetLevel(self,level): - self.gl_win.SetLevel(level) - self.level_ = level - + def SetLevels(self,levels): + self._current_index = -1 + if isinstance(levels, list): + self.levels_ = levels + def NextLevel(self): - self.level_.Close() + self._current_index += 1 + if(self._current_index < len(self.levels_)): + self._LoadLevel() + else: + self._current_index -=1 + + def PreviousLevel(self): + self._current_index -= 1 + if(self._current_index >= 0): + self._LoadLevel() + else: + self._current_index +=1 def GetLevel(self): - return self.level_ + return self._current_level def Start(self, args): + self.NextLevel() self.gl_win.Show(fullscreen=('--fullscreen' in args)) - + def _LoadLevel(self): + if self._current_level is not None: + self._current_level.Close() + self._current_level = level.Level(self.levels_[self._current_index]) + self.gl_win.ClearHUDObjects() + self.gl_win.SetLevel(self._current_level) diff --git a/examples/dokk/hud.py b/examples/dokk/hud.py index 4677124db28d80b864d7811e93f3a3fee40be990..d5ad7a7d223f30db68d2c53d11ee244f8172ee09 100644 --- a/examples/dokk/hud.py +++ b/examples/dokk/hud.py @@ -6,10 +6,8 @@ from PyQt4.QtCore import * from PyQt4.QtOpenGL import * class HUD(QObject): - def __init__(self, level, parent=None): + def __init__(self, parent=None): QObject.__init__(self,parent) - self.level = level - level.hud = self self.objects = list() def Add(self, hud_object): @@ -28,6 +26,9 @@ class HUD(QObject): for hud_object in self.objects: hud_object.Paint(painter) + def Clear(self): + del(self.objects[:]) + class HUDObject(QObject): def __init__(self, time, parent=None): QObject.__init__(self, parent) @@ -62,15 +63,6 @@ class TextHUDObject(HUDObject): self.color = color self.font = font - #def __init__(self, text, rect, time, align=Qt.AlignCenter, color=QColor(255,255,255), font=QFont("Verdana"), parent=None): - # HUDObject.__init__(self,time,parent) - #self.text = text - #self.pos = None - #self.rect = rect - #self.align = align - #self.color = color - #self.font = font - def Paint(self, painter): rem_time = (self.endtime-float(time.time()))*1000.0 if rem_time > 0: diff --git a/examples/dokk/level_intro.py b/examples/dokk/level_intro.py deleted file mode 100644 index b3c99134cbb58178e6884548b8300ebb67de6ba1..0000000000000000000000000000000000000000 --- a/examples/dokk/level_intro.py +++ /dev/null @@ -1,62 +0,0 @@ -from PyQt4 import QtCore, QtGui -from dokk import Dokk -from hud import TextHUDObject -from hud import RectHUDObject -from hud import RectTextHUDObject -class LevelIntro(QtCore.QObject): - def __init__(self, level, parent=None): - QtCore.QObject.__init__(self,parent) - self.level = level - text_count = int(level.config.Intro["TEXT_COUNT"]) - self.text_list = list() - default_time = int(level.config.Intro["TEXTTIME"]) - default_color = QtGui.QColor(int(level.config.Intro["TEXTCOLORRED"]), - int(level.config.Intro["TEXTCOLORGREEN"]), - int(level.config.Intro["TEXTCOLORBLUE"])) - default_size = int(level.config.Intro["TEXTSIZE"]) - self.total_time = 0 - for i in range(1,text_count+1): - try: - time = int(level.config.Intro["TEXTTIME%s"%i]) - except: - time = default_time - try: - color = QtGui.QColor(int(level.config.Intro["TEXTCOLORRED%s"%i]), - int(level.config.Intro["TEXTCOLORGREEN%s"%i]), - int(level.config.Intro["TEXTCOLORBLUE%s"%i])) - except: - color = default_color - try: - size = int(level.config.Intro["TEXTSIZE%s"%i]) - except: - size = default_size - self.text_list.append([level.config.Intro["TEXT%s"%i], time, color, size]) - self.total_time += time - - self.cur_text = 0 - - def Start(self): - dokk = Dokk() - font = QtGui.QFont("Verdana", 15); - rect = QtCore.QRect(QtCore.QPoint(60, 60), QtCore.QSize(dokk.gl_win.Width()-120, dokk.gl_win.Height()-120)) - self.text = RectTextHUDObject(text="", rect=rect, time=0, font=font) - QtCore.QObject.connect(self.text, QtCore.SIGNAL("Finished()"), self.NextMessage) - self.bg = RectHUDObject(self.total_time,rect, bg_color=QtGui.QColor(128,128,128,200)) - self.level.AddHUDObject(self.bg) - self.level.AddHUDObject(self.text) - - def Reset(self): - self.cur_text = 0 - - def NextMessage(self): - if self.cur_text >=0 and self.cur_text < len(self.text_list): - dokk = Dokk() - self.text.text=self.text_list[self.cur_text][0] - self.text.time=self.text_list[self.cur_text][1] - self.text.color=self.text_list[self.cur_text][2] - self.text.font.setPointSize(self.text_list[self.cur_text][3]) - self.text.Reset() - print (dokk.gl_win.Width()/2.0) - (len(self.text.text)*10) - else: - self.cur_text = -1 - self.cur_text+=1 \ No newline at end of file diff --git a/examples/dokk/level_messages.py b/examples/dokk/level_messages.py new file mode 100644 index 0000000000000000000000000000000000000000..01136e2c76d9b27460a0ca0cab7ad49b3dcd311c --- /dev/null +++ b/examples/dokk/level_messages.py @@ -0,0 +1,93 @@ +from PyQt4 import QtCore, QtGui +from dokk import Dokk +from hud import RectHUDObject +from hud import RectTextHUDObject + +class LevelMessages(QtCore.QObject): + def __init__(self, config_map, parent=None): + QtCore.QObject.__init__(self,parent) + text_count = int(config_map["TEXT_COUNT"]) + self.text_list = list() + default_time = int(config_map["TEXTTIME"]) + default_color = QtGui.QColor(int(config_map["TEXTCOLORRED"]), + int(config_map["TEXTCOLORGREEN"]), + int(config_map["TEXTCOLORBLUE"])) + default_size = int(config_map["TEXTSIZE"]) + self.total_time = 0 + for i in range(1,text_count+1): + try: + time = int(config_map["TEXTTIME%s"%i]) + except: + time = default_time + + try: + color = QtGui.QColor(int(config_map["TEXTCOLORRED%s"%i]), + int(config_map["TEXTCOLORGREEN%s"%i]), + int(config_map["TEXTCOLORBLUE%s"%i])) + except: + color = default_color + + try: + size = int(config_map["TEXTSIZE%s"%i]) + except: + size = default_size + + self.text_list.append([config_map["TEXT%s"%i], time, color, size]) + self.total_time += time + + self.cur_text = 0 + + def Start(self): + self.Reset() + dokk = Dokk() + font = QtGui.QFont("Verdana", 15); + rect = QtCore.QRect(QtCore.QPoint(60, 60), QtCore.QSize(dokk.gl_win.Width()-120, dokk.gl_win.Height()-120)) + self.text = RectTextHUDObject(text="", rect=rect, time=0, font=font) + QtCore.QObject.connect(self.text, QtCore.SIGNAL("Finished()"), self.NextMessage) + self.bg = RectHUDObject(self.total_time,rect, bg_color=QtGui.QColor(128,128,128,200)) + dokk.gl_win.AddHUDObject(self.bg) + dokk.gl_win.AddHUDObject(self.text) + + def Stop(self): + self.cur_text = -1 + + def Reset(self): + self.cur_text = 0 + + def NextMessage(self): + if self.cur_text >=0 and self.cur_text < len(self.text_list): + dokk = Dokk() + self.text.text=self.text_list[self.cur_text][0] + self.text.time=self.text_list[self.cur_text][1] + self.text.color=self.text_list[self.cur_text][2] + self.text.font.setPointSize(self.text_list[self.cur_text][3]) + self.text.Reset() + else: + self.emit(QtCore.SIGNAL('Finished()')) + self.cur_text = -1 + self.cur_text+=1 + +class LevelIntro(LevelMessages): + def __init__(self, config, parent=None): + LevelMessages.__init__(self,config.INTRO, parent) + +class LevelEnd(LevelMessages): + def __init__(self, messages, parent=None): + LevelMessages.__init__(self,messages, parent) + + def NextMessage(self): + if self.cur_text >=0 and self.cur_text < len(self.text_list): + self.text.text=self.text_list[self.cur_text][0].replace("$SCORE","%.2f"% Dokk().GetLevel().GetScore()) + self.text.text=self.text.text.replace("$TIMEMALUS","%.2f"% Dokk().GetLevel().GetTimeMalus()) + self.text.text=self.text.text.replace("$RMSD","%.2f"% Dokk().GetLevel().GetRMSD()) + self.text.text=self.text.text.replace("$RANK","%i"% Dokk().GetLevel().GetRank()) + self.text.text=self.text.text.replace("$DIFFERENCE","%.2f"% Dokk().GetLevel().GetTTDiff()) + self.text.time=self.text_list[self.cur_text][1] + self.text.color=self.text_list[self.cur_text][2] + self.text.font.setPointSize(self.text_list[self.cur_text][3]) + self.text.Reset() + else: + self.emit(QtCore.SIGNAL('Finished()')) + self.cur_text = -1 + self.cur_text+=1 + diff --git a/examples/dokk/ligand.py b/examples/dokk/ligand.py index 8bcff90bfcb38ed0a2a813bb41fa7d456198b5e1..b10d0b138a3ad309f38239c621f1942402fd7c5e 100644 --- a/examples/dokk/ligand.py +++ b/examples/dokk/ligand.py @@ -5,7 +5,7 @@ class Ligand: def __init__(self, ligand, config=None): self.handle=ligand self.the_solution_=ligand.Copy().CreateFullView() - self.go=gfx.Entity("Ligand", gfx.CUSTOM, self.handle) + self.go=gfx.Entity("Ligand", gfx.CPK, self.handle) self.go.SetColor(gfx.GREEN, 'ele=C') gfx.Scene().Add(self.go) gfx.Scene().SetCenter(self.go.center) diff --git a/examples/dokk/score_updater.py b/examples/dokk/score_updater.py index b968d35b980f2cc68c1c1513d4b14a09c94bd46a..7422dc2ae1bb4fde5035fe7db282e4e430b98191 100644 --- a/examples/dokk/score_updater.py +++ b/examples/dokk/score_updater.py @@ -1,19 +1,27 @@ import os, threading from PyQt4 import QtCore, QtGui -from ost import qa +from ost import mol, qa class ScoreUpdater(QtCore.QObject): def __init__(self, level, parent=None): QtCore.QObject.__init__(self, parent) self.level = level - + self.old_atoms = list() def UpdateScores(self): + for atom in self.old_atoms: + atom.SetGenericFloatProperty('clash', 0) + ligand = self.level.ligand - prot_within=self.level.protein.handle.FindWithin(ligand.GetCenter(), - ligand.radius) + prot_within = list() + ligand_atoms = ligand.handle.atoms + for ligand_atom in ligand_atoms: + within=self.level.protein.handle.FindWithin(ligand_atom.GetPos(), 3) + for atom in within: + prot_within.append(atom) lig_view=ligand.handle.CreateFullView() for a in prot_within: score=qa.ClashScore(a, lig_view) a.SetGenericFloatProperty('clash', score) self.level.surface.go.ReapplyColorOps() + self.old_atoms = prot_within diff --git a/examples/dokk/spnav_input.py b/examples/dokk/spnav_input.py index bdb85549f15f0eb979c061c29713552430424a67..f50ce7da68d570c7d667af8fdf2d829679bc095f 100644 --- a/examples/dokk/spnav_input.py +++ b/examples/dokk/spnav_input.py @@ -1,3 +1,4 @@ +import dokk from PyQt4 import QtCore, QtGui from hud import TextHUDObject from ost import mol, geom, gfx, gui @@ -17,20 +18,22 @@ class SpnavInputDevice(QtCore.QObject): self.trans = True self.rot = True + self._lock_input = False + self.score_scip = 0 def SetLevel(self, level): self.level=level self.trans_hud = TextHUDObject("Translation Enabled: %s"%self.trans, QtCore.QPoint(10,50), 0) self.rot_hud = TextHUDObject("Rotation Enabled: %s"%self.rot, QtCore.QPoint(10,70), 0) - self.level.AddHUDObject(self.trans_hud) - self.level.AddHUDObject(self.rot_hud) + dokk.Dokk().gl_win.AddHUDObject(self.trans_hud) + dokk.Dokk().gl_win.AddHUDObject(self.rot_hud) try: self.refresh_rate_ = int(level.config.Score["FRAMESKIP"]) except: pass def InputChanged(self, tx,ty,tz,rx,ry,rz): - if self.level is not None: + if (not self._lock_input) and (self.level is not None): ligand = self.level.ligand transf = mol.Transform() if(self.trans): @@ -49,26 +52,35 @@ class SpnavInputDevice(QtCore.QObject): self.score_scip += 1 gfx.Scene().RequestRedraw() + def SetLockInput(self, lock): + self._lock_input = lock + def ToggleInputMode(self, button): - print button - if button == 0: - self.trans = not self.trans - self.trans_hud.text= "Translation Enabled: %s"%self.trans - self.trans_hud.time = 2000 - self.trans_hud.Reset() - elif button == 1: - self.rot = not self.rot - self.rot_hud.text= "Rotation Enabled: %s"%self.rot - self.rot_hud.time = 2000 - self.rot_hud.Reset() - elif button == 2: + if button == 2: self.level.Begin() + elif button == 3: + dokk.Dokk().PreviousLevel() elif button == 4: - self.gfx_win.dokk.NextLevel() + dokk.Dokk().NextLevel() elif button == 6: QtGui.QApplication.exit() - elif button == 10: - self.level.Reset() - elif button == 11: - self.level.Solve() - + + if (not self._lock_input): + if button == 0: + self.trans = not self.trans + self.trans_hud.text= "Translation Enabled: %s"%self.trans + self.trans_hud.time = 2000 + self.trans_hud.Reset() + elif button == 1: + self.rot = not self.rot + self.rot_hud.text= "Rotation Enabled: %s"%self.rot + self.rot_hud.time = 2000 + self.rot_hud.Reset() + elif button == 10: + self.level.Finished() + elif button == 11: + self.level.Finished() + elif button == 12: + self.level.Solve() + elif button == 13: + self.level.Reset() diff --git a/examples/dokk/start_dokk.py b/examples/dokk/start_dokk.py index 0350c55732861df955a4c8a653c776d201dccfcf..bd13f442133091a3ec126ea32fd6bf43b9d0e31f 100644 --- a/examples/dokk/start_dokk.py +++ b/examples/dokk/start_dokk.py @@ -1,6 +1,6 @@ from level import Level from dokk import Dokk dokk=Dokk() -dokk.SetLevel(Level('thrombin')) +dokk.SetLevels(['thrombin','thrombinNoH']) dokk.Start(sys.argv)