190 likes | 485 Views
Object-oriented application development with MeVisLab and Python. Frank Heckel Michael Schwier Heinz-Otto Peitgen. What I am going to talk about. Development of (medical) software assistants Issues in multilevel development approaches (MeVisLab) Object-oriented programming.
E N D
Object-oriented application development with MeVisLab and Python Frank Heckel Michael Schwier Heinz-Otto Peitgen
What I am goingto talk about • Development of (medical) software assistants • Issues in multilevel development approaches (MeVisLab) • Object-oriented programming
Rapid ApplicationPrototypingwith MeVisLab • Visual development environment for medical image processing and visualization
Multilevel Development Approach • Application Level • GUI design • Application logic • Network Level • Image processing and visualization processes • Based on library of modules • Module • Low-level algorithm implementation Script Visual C++
Module/C++ Level Network Level Script Level C++ Module Int Float String Image
The typical script level problem • They form a global layer upon the network • Practically no access limitations • No scope bound to a subnetwork or modules • Initial intention was to use it for short code snippets • Convenience (no need to get back to C++/recompile/restart) • Short conditional logic • Since it’s so easy … • Developers put more and more logic and processing into the script • Applications naturally need a lot of code upon the network • Controlling the data flow • Interaction • … • Programmers tend to take Script programming not so serious
Let‘sbuild an application • Load a BL and/or FU dataset that have been specified in the GUI • Switch to a proper GUI configuration if successful
Example LoadData_filename baselineFilename filename LoadData_valid valid followupFilename loadButton Import
Call-Chain baselineFilename LoadData_filename filename followupFilename LoadData_valid valid loadButton • GUI • LoadData • DataProcessing Connection Connection Event Set Set Event Event defloadButtonPressed(field): ifctx.field(“baselineFilename”).value != “” ... state = “BL_AND_FU” ... GlobalState deffilenameChanged(field): # loading stuff ... ifloadSuccessful: ctx.field(“valid”).value = True else: ctx.field(“valid”).value = False defbaseline_LoadDataDone(field): if state == “BL_AND_FU”: ifnot successful: ... IMPLICIT
Networks can get complex and confusing Can you imagine the network script?
Join Script and Module • Module • Module
Concept DataProcessing LoadData GUI context: Network parent: Reference … context: Network parent: Reference dataProcessing: Reference … context: Network parent: Reference loadData: Reference … init (ctx: Network, child: Reference): void setParent (parent: Reference): void getField (field: String): String/Int/Float loadFile (filename: String): Boolean DataProcessing GUI LoadData init (ctx: Network, child: Reference): void setParent (parent: Reference): void getField (field: String): String/Int/Float loadFile (filename: String): Boolean init (ctx: Network, child: Reference): void setParent (parent: Reference): void getField (field: String): String/Int/Float loadFile (filename: String): Boolean
Integration in MeVisLab DataProcessing Init context: Network parent: Reference loadData: Reference … ## global reference to this modules instance this = None ## access method to the global this object defgetThis(): global this return this ## the init method creates the global object ## (one class instance per module instance) definit(ctx): global this loadData = ctx.module(“LoadData”).call(“getThis”) this = DataProcessing(ctx, loadData) return init (ctx: Network, child: Reference): void setParent (parent: Reference): void getField (field: String): String/Int/Float loadFile (filename: String): Boolean DataProcessing
Integration in MeVisLab ## global reference to this modules instance this = None ## access method to the global this object defgetThis(): global this return this ## the init method creates the global object ## (one class instance per module instance) definit(ctx): global this loadData= ctx.module(“LoadData”).call(“getThis”) this = DataProcessing(ctx, loadData) return DataProcessing Init context: Network parent: Reference loadData: Reference … ## global reference to this modules instance this = None ## access method to the global this object defgetThis(): global this return this ## the init method creates the global object ## (one class instance per module instance) definit(ctx): global this loadData = ctx.module(“LoadData”).call(“getThis”) this = DataProcessing(ctx, loadData) return init (ctx: Network, child: Reference): void setParent (parent: Reference): void getField (field: String): String/Int/Float loadFile (filename: String): Boolean DataProcessing
Call chain baselineFilename followupFilename loadButton • GUI • LoadData • DataProcessing Event defloadData(self): ifself.getfield("baselineFilename").value != ""andself.getfield("follo... ifself.baselineScan.loadFile( self.getfield("baselineFilename").value ): ifself.followupScan.loadFile( self.getfield("followupFilename").value ): # switch to bl+fu layout... else: ... defloadFile(self, filename): # loading stuff ... returnloadSuccessful defloadFile(self, filename): returnloadData.loadFile(filename) Call Call EXPLICIT
The Essence Use object oriented programming (wisely) … … even if it‘s tempting not to do it!
The Essence Use object oriented programming (wisely) … … even if it‘s tempting not to do it! The users/clinicians will profit.