AUTOMATIC GENERATION OF BIOLOGICAL PATHWAY MODELS IN THE SWIFT PROGRAMMING LANGUAGE A Thesis Presented to the Faculty of the Graduate School of Cornell University in Partial Fulfillment of the Requirements for the Degree of Master of Science by Rohaine Veronica Hsu August 2016 © 2016 Rohaine Veronica Hsu ALL RIGHTS RESERVED ABSTRACT Biological pathways, including signal transduction, gene-regulation, and metabolic pathways, have previously been computationally modeled in various applications. Programming languages such as Python and Java, have been used in applications. In the bioinformatics field, natural language processing has been used in applications, such as GENomics Information Extraction System (GENIES) [17], to extract information from literature related to pathways. By using natural language processing, text files can be used as inputs to model biological pathways. This thesis proposes an application using Swift programming for generating code for biological pathways using a natural language compiler. A front end graphical user interface (GUI) was developed for the desktop on Mac computers, and the Apple iPad to allow users to transfer text files to the compiler. The desktop GUI allowed users to select files directly from their computers, such as from their documents or downloads, to the compiler. For the iPad GUI, two file transferring methods were used to transfer files onto the iPad. One method applied Dropbox by incorporating SwiftyDropbox, the Swift software development kit for Dropbox’s application program interface. The user could grant the application access to the user’s Dropbox account to download and upload files. Another method utilized AirDrop, which enabled content sharing between iOS devices and Mac computers. AirDrop was provided as a selection to share text files directly from the the user’s computer to the iPad, through Wi-Fi and Bluetooth. The user could also create files on the GUI by typing in given text fields for file name, text, and extension. The text files were applied as inputs for a natural language compiler. The compiler would func- tion by parsing through the text, while also returning various status messages to the GUI. If the compiler ran without error, then it would proceed to try outputting model code. Therefore, instead of the user writing code, the user can write simple text files. The application could be used by people that are inexperienced with programming. A programming background would therefore not be needed to create model code for the pathways. BIOGRAPHICAL SKETCH Rohaine Veronica Hsu was born and raised in Southern California. She obtained a Bachelor of Science in Engineering from Harvey Mudd College in May 2014. In Fall 2014, she entered the Master of Engineering program at Cornell University in the department of Chemical and Biomolecular Engineering. She earned a Master of Engineering in Chemical Engineering in May 2015, with a specialization in Medical and Industrial Biotechnology. She then continued at Cornell as a Master of Science student. While at Cornell she was a board member and secretary of the Engineering Graduate Student Association. She also held leadership positions in other organizations. She was the academic chair for the Society for Asian American Graduate Affairs. Moreover, she was the Master of Engineering/Master of Science Representative in the Chemical and Biomolecular Engineering Graduate Women’s Group. iii To my mother, father, brother, and friends Thank you Love you always iv ACKNOWLEDGEMENTS I would like to thank both of my special committee members, Dr. Jeffrey Varner and Dr. Paulette Clancy. I’m thankful towards Dr. Varner, my advisor, for his guidance throughout my time at Cornell, and Dr. Clancy for her support during the school year. Moreover, I would like to thank the James McCormick Family Teaching Excellence Institute for lending equipment for the project. An Apple iPad Air was provided for testing purposes during the application development. I would also like to thank the Cornell Chemical and Biomolecular Engineering faculty, staff, and students. Lastly, thank you to the members of Varner Lab. v TABLE OF CONTENTS Biographical Sketch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Dedication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v Table of Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi List of Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . viii 1 Introduction 1 1.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1.1 Signal Transduction Pathways . . . . . . . . . . . . . . . . 1 1.1.2 Gene Regulation Pathways . . . . . . . . . . . . . . . . . . 2 1.1.3 Metabolic Pathways . . . . . . . . . . . . . . . . . . . . . . 3 1.1.4 Systems Biology Markup Language . . . . . . . . . . . . . 4 1.1.5 Network Motifs . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.2.1 System Architecture . . . . . . . . . . . . . . . . . . . . . . 9 1.2.2 Swift Programming Language . . . . . . . . . . . . . . . . 11 2 Natural Language Processing 13 2.1 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3 Compilers 3.1 Cobol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.1 Scanner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.2 Parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.3 Abstract Syntax Tree . . . . . . . . . . . . . . . . . . . . . . 3.2.4 Visitor Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.5 Strategy Pattern . . . . . . . . . . . . . . . . . . . . . . . . . 17 17 17 18 18 19 21 21 4 Swift Application 4.1 Desktop GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 iPad GUI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 Dropbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.2 AirDrop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.3 GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.4 Mercury . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 22 23 24 25 29 39 40 5 Code Generation 42 5.1 First Generation Grammar Statement Structure . . . . . . . . . . . 42 5.2 Second Generation Grammar Statement Structure . . . . . . . . . 45 5.3 Julia Programming Language . . . . . . . . . . . . . . . . . . . . . 51 5.3.1 Output Files . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 vi 6 Future Work 54 6.1 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.2 Graphical User Interfaces . . . . . . . . . . . . . . . . . . . . . . . 56 6.3 Message Passing Layer . . . . . . . . . . . . . . . . . . . . . . . . . 57 6.4 Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 A Dropbox GUI 61 B AirDrop GUI 101 C GitHub Authorization 116 D Mercury Framework 126 Bibliography 134 vii LIST OF FIGURES 1.1 Signal Transduction pathway example . . . . . . . . . . . . . . . 1.2 Gene Regulation pathway example . . . . . . . . . . . . . . . . . 1.3 Catabolic and Anabolic pathway examples . . . . . . . . . . . . . 1.4 SBML model definition . . . . . . . . . . . . . . . . . . . . . . . . 1.5 Excerpt of example SBML . . . . . . . . . . . . . . . . . . . . . . . 1.6 A. Example motif indicating activation of all pathways B. Exam- ple motif showing repression of P1 to P3, P3 to P2 . . . . . . . . . 1.7 Biological Pathways modeled as Ordinary Differential Equations 1.8 Control rules represented as transfer functions . . . . . . . . . . . 1.9 Proposed system architecture utilizing graphical user interfaces, a message passing layer, and a natural language compiler . . . . 1.10 Process of Swift LLVM compiler . . . . . . . . . . . . . . . . . . . 1 2 3 4 5 6 7 8 10 11 2.1 Components of MedLEE . . . . . . . . . . . . . . . . . . . . . . . 14 2.2 Components of GENIES . . . . . . . . . . . . . . . . . . . . . . . . 15 3.1 Example of tokenization . . . . . . . . . . . . . . . . . . . . . . . . 18 3.2 Example process of recursive descent parsing . . . . . . . . . . . 19 3.3 Example of a concrete syntax tree . . . . . . . . . . . . . . . . . . 20 3.4 Example of an abstract syntax tree . . . . . . . . . . . . . . . . . . 20 4.1 Desktop GUI for selecting input files . . . . . . . . . . . . . . . . 4.2 GitHub Desktop Application Interface . . . . . . . . . . . . . . . 4.3 Sign in window for the user to log into DropBox . . . . . . . . . . 4.4 TextTransfer application verifies with the user for permission to access Dropbox files . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5 Example list of files in a user’s dropbox account . . . . . . . . . . 4.6 TextTransfer graphical user interface . . . . . . . . . . . . . . . . . 4.7 Share icon shortcut menu with AirDrop . . . . . . . . . . . . . . . 4.8 Control click with share with a shortcut menu with AirDrop . . . 4.9 Example recipients to share with on AirDrop . . . . . . . . . . . . 4.10 AirDrop from the Finder menu bar . . . . . . . . . . . . . . . . . 4.11 AirDrop from the desktop Finder window . . . . . . . . . . . . . 4.12 AirDrop Graphical user interface . . . . . . . . . . . . . . . . . . . 4.13 AirDropTest sharing component on the GUI . . . . . . . . . . . . 4.14 User can tap to share files using AirDrop . . . . . . . . . . . . . . 4.15 MacBook users can accept or decline files shared from AirDrop . 4.16 MacBook users can share files back to the iPad using AirDrop . . 4.17 iPad users can decline or accept files shared through AirDrop . . 4.18 If a file is accepted through AirDrop, the user can select the air- droptest application to open the file . . . . . . . . . . . . . . . . . 4.19 GitHub user login screen to allow the application authorization . 4.20 Example of a mediator system . . . . . . . . . . . . . . . . . . . . 22 23 25 26 27 28 29 30 30 31 32 33 34 35 36 36 37 38 39 40 viii 5.1 A. Example motif B. First generation grammar strategies . . . . . 42 5.2 Example of first generation grammar strategies . . . . . . . . . . 44 5.3 Second Generation Grammar Strategies A. Type Assignment Statement Grammar Strategy B. System Transfer Statement Grammar Strategy C. Expression Statement Grammar Strategy . 46 5.4 Second Generation Grammar Strategies A. Metabolic Control Statement Grammar Strategy B. Metabolic Stoichiometry Statement Grammar Strategy . . . . . . . . . . . . . . . . . . . . . . . 48 5.5 Example of second generation grammar strategies . . . . . . . . . 50 ix CHAPTER 1 INTRODUCTION 1.1 Background Biological pathways types include signal transduction, gene regulation, and metabolic pathways. Signal transduction pathways function to send a signal to the cell’s interior from the exterior. Gene-regulation pathways inform genes to turn off and on. Metabolic pathways involve chemical reactions catalyzed by enzymes [22]. Various types of computational modeling for pathways have been done previously. Some models include statistical models, kinetic models, rule-based models, and multi-agent models [10]. To model biological pathways, the system being proposed relies on natural language processing. 1.1.1 Signal Transduction Pathways Figure 1.1: Signal Transduction pathway example [9] 1 An example process of a signal transduction pathway is shown in Figure 1.1. A signal transduction pathway can be categorized in three different steps, reception, transduction, and the response [9]. The first step, reception, focuses on the cell determining if there is a signaling molecule outside of the cell. As shown in Figure 1.1, a signaling molecule is in the extracellular fluid outside of the cell. As the signaling molecule approaches the cell surface, the cell will then be able to detect a signal when it binds to the surface. Therefore, the cell will be able to detect a signal when the signaling molecule, such as a ligand, binds to a receptor protein of the cell. The second step, transduction, is made of up multiple steps where molecules affect the next molecule in a pathway by changing it. The third step, response, is the cellular response that is initiated by the signal. 1.1.2 Gene Regulation Pathways Figure 1.2: Gene Regulation pathway example [32] 2 The gene regulation pathway example shown in Figure 1.2 displays the production of protein being slowed down. While the amount of protein increases, production is slowed down due to the formation of the DNA and protein complex [32]. Figure 1.2 shows multiple parts of a pathway. Transcription from DNA to create mRNA is shown, followed by translation with mRNA and the resulting protein. The resulting protein product causes gene repression by continuously binding to DNA. Transcription is less likely to occur with the unbound DNA due to the DNA bound to protein [32]. 1.1.3 Metabolic Pathways Figure 1.3: Catabolic and Anabolic pathway examples [8] Metabolic pathways can be various types including catabolic and anabolic pathways. From Figure 1.3, the anabolic pathway can be represented as biosynthesis, with small molecules requiring energy to become larger molecules. The catabolic pathway can be represented as degradation, as large molecules break down into smaller molecules while releasing energy [8]. 3 1.1.4 Systems Biology Markup Language The Systems Biology Markup Language(SBML) represents models for biochemical reaction networks using an XML-based format [21]. SBML models can be made up of various components, such as reactants, products, and reaction rates. When a model is defined, it is dependent on lists of the components. However, every list is optional to the model as shown in Figure 1.4 [28]. Figure 1.4: SBML model definition [28] For example, for the reaction E + S kon koff ES kcat E + P, different lists of components could result. The SBML model definition could include species, reactants E, S, ES, and products ES, E, and P. List of species, list of reactants and list of products could then be defined. 4 Figure 1.5: Excerpt of example SBML [28] 5 List of reactants and list of products would be associated under list of reactions, as shown in Figure 1.5. Figure 1.5 displays just an excerpt of the SBML associated with the example, as the complete SBML states more lists, such as unit definitions and compartments [28]. 1.1.5 Network Motifs Figure 1.6: A. Example motif indicating activation of all pathways B. Example motif showing repression of P1 to P3, P3 to P2 Network motifs are patterns that reoccur throughout transcription regulation networks, more often than expected compared to random networks [1]. Example motifs are shown in Figure 1.6. In Figure 1.6A, the example motif showcases activation of pathways with the inducer upregulating P1. Then P1 causes the activation of both P2 and P3. Moreover, P2 and P3 also activate each other. However, in Figure 1.6B, the motif indicates examples of repression. Sim- 6 ilar to Figure 1.6A, the inducer activates P1, and P1 activates P2, with P2 activating P3. However, in the case of Figure 1.6B, P1 now represses P3, while P3 represses P2. Figure 1.7: Biological Pathways modeled as Ordinary Differential Equations Biological pathways can be modeled mathematically as ordinary differential equations as shown in Figure 1.7. For a network with node j, balances for mRNA and protein can be represented as differential equations. The first equation has a rate transcription factor, a control rule also for transcription, and a dilution and degradation term. The second equation for a protein balance follows a similar format, with a rate factor for translation, a control rule for translation, and a dilution and degradation term. 7 Figure 1.8: Control rules represented as transfer functions Control rules for transcription and translation on network motifs can be represented as transfer functions as shown in Figure 1.8. The first case shows the promotor being repressed. The control rule from Figure 1.7 can be written in terms of transfer functions representing gene regulatory strength. The middle path shows how the promoter is being activated. The system can also be written with transfer functions and the integration rule. The third path shows the promoter being both activated and repressed, with the control rule factor for transcription being represented with a minimum. 8 1.2 Motivation With large numbers of species and reactions existing currently, coding by hand various reactions would be manually difficult. Therefore, a degree of automation is necessary with code generators. The system proposes a code generator for biological pathway models. The pathway models will be represented in terms of ordinary differential equations. The generator will be accessible to those without programming backgrounds since it is dependent on a natural language compiler. Users can write natural language text files as inputs to the system, rather than code. The advantage of the system is that users will not be limited by programming capabilities. Those without programming backgrounds will be able to generate code associated with biological pathway models. By using natural language processing, inputs can be written as simple grammatical sentences. The sentences will then be understood by the compiler and to output code. The system will ideally allow an alternative for users with a biological background, but not necessarily a programming background to generate code. 1.2.1 System Architecture Figure 1.9 showcases the system architecture composed of three layers. The first layer is the graphical user interface. The user interface can be a desktop interface, such as a Macbook, or an iOS device, such as an iPad. The user interface works with the user to accept input text files for the natural language compiler. The desktop GUI will be obtain files directly from the user’s computer, whereas 9 Figure 1.9: Proposed system architecture utilizing graphical user interfaces, a message passing layer, and a natural language compiler the iPad GUI relies on other applications to obtain text files. One application that could be used is Dropbox. The middle layer of the system architecture is the message passing layer, Mercury. Mercury functions as the mediator of the system, which enables the system to have multiple graphical user interfaces. The user interface will not directly contact the compiler, and the compiler will not directly contact the user interface. This system has Mercury sending and receiving messages between the layers. Mercury will receive start and stop messages from the user interface, which are then sent to the compiler to know when to start a test run or stop a test run. The compiler can then send messages through Mercury to the interface to notify the user. Messages from the compiler could include status messages, whether a run is progressing or completed. The com- 10 piler could also send error messages. If the compiler determines that an error exists in the given input text files, the compiler can send an error message to Mercury to pass along to the user. The user will be notified the error in terms of location of the text file, the line and column number. If there are no errors found, the compiler will then generate Julia programming language code representing biological pathway models. The generated code will be available to the user. 1.2.2 Swift Programming Language The Swift programming language was chosen for the system due to its compatibility with iOS devices, including the iPad Air. It is open source and platform independent. Swift can be used on Linux and Apple platforms [3]. It also utilizes the LLVM compiler [5]. Figure 1.10: Process of Swift LLVM compiler [24] The process is shown in Figure 1.10. It uses recursive descent parsing and semantic analysis to turn swift code into an abstract syntax tree(AST)[5]. The 11 syntax trees are then turned into swift intermediate language(IL). Swift intermediate language(SIL) generation is used to turn the abstract syntax tree into raw swift IL, then SIL guaranteed transformations result in the canonical Swift IL. LLVM Intermediate representation(IR) generation then turns SIL into LLVM IR. LLVM will then apply optimization to create an assembly and the an executable to generate machine code [24][5]. Swift was also released back in 2014 [2]. With a fairly new programming language, the use of the language could result in developing applications that could be new, innovative, and different from previous well known programming languages such as C and Objective-C. Swift as an object oriented programming language can be considered as a successor to other languages including Objective-C and C [6]. By working with iOS devices, Objective-C is also compatible. Swift projects can have Swift code files work alongside Objective-C files [4]. 12 CHAPTER 2 NATURAL LANGUAGE PROCESSING Natural Language Processing is a computer processing human languages, rather than programming languages [11]. It has been applied in various methods. Some methods include information retrieval, information extraction, and machine translation [30]. Written text and speech can be considered as inputs and outputs of a natural language processing system. Natural language processing systems can be composed of five parts. The first part is lexical analysis where text is divided into sentences or words. The second part is parsing or syntactic analysis, where sentences are checked for grammar. Semantic analysis follows as the third part, where sentence text is checked for logic and meaning. The fourth part is disclosure integration. Sentences are based on their position, and their meanings could be dependent on the sentence preceding it. Moreover, a sentence could affect the meaning of the sentence after it. The last part is pragmatic analysis, where sentences are interpreted based on context [43]. 2.1 Applications Natural language processing has been applied to application program interfaces. A Google Cloud natural language application program interface (API) has been released in beta that incorporates sentiment analysis, entity recognition, and syntax analysis. Sentiment analysis is interpreting the sentiment of analyzed text. Entity recognition is identifying entities and associating them with their types such as a person or a location, and syntax analysis is parsing text [37]. The Google Cloud natural language API functions to interpret and understand the structure and meaning of text. Users can use their document 13 storage on Google Cloud or upload text [35]. The API also supports various languages. Currently, sentiment analysis is supported in English, while both entity recognitions and syntax analysis are supported in Japanese, Spanish, and English [36]. Applications using natural language processing have also been used in bioinformatics to extract information from various literature to model pathways. One example is the GENomics Information Extraction System (GENIES) that looks into biological literature about cellular pathways [17]. GENIES is based on another natural language processing system, MedLEE (Medical Language Extraction and Encoding System), where MedLEE functioned to encode clinical reports [17] [18]. Another application based on MedLEE is BioMedLEE, where it uses natural language processing to extract information focusing on phenotypic data and biomolecular substances in genomic literature [42]. Figure 2.1: Components of MedLEE [17] 14 Figure 2.1 outlines the various components of MedLEE. The preprocessor is the first component that will identify sentences in clinical reports. Using the lexicon, single words and phrases will then be categorized. The parser, as the second component, then compares the words and phrases against grammar models to output target forms. If there is a case where the parser cannot parse a sentence, but it has relevant clinical information, then error recovery is activated. Error recovery results in the parser parsing segments of the sentence. The third component is used when combining relevant phrases in a sentence that have been separated. The last component is the encoder which maps output forms to coded controlled vocabulary[17]. Since GENIES is based on MedLEE, the structure contains similar components as shown in Figure 2.2. Figure 2.2: Components of GENIES [17] 15 The preprocessor, parser, and error recovery components from MedLEE are included. GENIES incorporates a tagger component, which functions by identifying and tagging proteins and genes in text [17]. 16 CHAPTER 3 COMPILERS 3.1 Cobol COmmon Business Oriented Language (COBOL) was developed in 1959 by the Conference on Data Systems Language (CODASYL). It was a high-level programming language with English-like syntax [44]. COBOL was ideally designed to be accessible for non-programmers to understand. Therefore, structural elements that were English-like were included [12]. English words could then be used to code in COBOL. It was based on Grace Hopper’s FLOW-MATIC [20]. FLOW-MATIC also had an English-like syntax, and was geared towards business applications. Some applications included automatic billing and calculating payroll [13]. For COBOL code to be understood, a compiler would have beeen needed to convert it to machine code [44]. 3.2 Compilers The main function of a compiler is to translate high-level programming language to low-level machine language [34]. The natural language compiler of the system will apply top-down parsing. Top-down parsing constructs a parse tree beginning with the start symbol, with the objective to transform to the input [45]. Compilers utilize tokenization, parsing, and design patterns. 17 3.2.1 Scanner Figure 3.1: Example of tokenization [31] A compiler has two main components, a scanner and a parser. The scanner functions as a tokenizer by turning a character sequence into individual tokens. The scanner goes through each character from the input and then separates the characters into tokens. For example, in Figure 3.1 the input character sequence was a sentence with seven words. The output of the sequence was then seven tokens where each word was defined to be a token. Therefore, the compiler will first scan received input sentences to turn the characters into tokens. 3.2.2 Parser Once the scanner creates the tokens, the compiler will then use a parser to recursively walk through a sequence of tokens. Recursive descent carries out predictive parsing by utilizing recursive functions [34]. The input is read from left to right. It checks the input if it is a nonterminal component, or a terminal component. If the component is terminal, then it is compared with the next input symbol. If the symbols are determined to match, then the system moves to the right to the next symbol and the next input. If the component is nonterminal, then a function is called to look at the next input, and the parsing later continues to the right to the next symbol [34]. An example process is defined in Figure 3.2, where it looks ahead and checks the symbol to see if it matches with the 18 Figure 3.2: Example process of recursive descent parsing [29] next character from the input. If the symbol and character input match, then the function returns true and moves onto the next character. While walking through the tokens, the parser will check the tokens against a grammar model. The first token will be checked to see if it syntactically follows the grammar model, once it does, then it walks to the next token. The compiler recursively walks through each input character to have it checked against a grammar model to see if they match before moving on. 3.2.3 Abstract Syntax Tree An abstract syntax tree (AST) represents the same information as a concrete syntax tree, but in a simplified form. An AST will have fewer nodes, where each node corresponds to either one or multiple nodes in a concrete syntax tree [34]. As shown in Figure 3.3, the concrete syntax tree has various subtrees and 19 multiple nodes. Figure 3.3: Example of a concrete syntax tree [34] In Figure 3.4, the AST has the same structure as the concrete syntax tree, however, the subtrees and nodes have been condensed and simplified. Figure 3.4: Example of an abstract syntax tree [34] 20 The addition and multiplication actions in the concrete syntax tree have been eliminated by renaming the subclasses. Moreover, the AST simplifies the sequences of nodes to just the terminal nodes [34]. 3.2.4 Visitor Pattern A visitor pattern is applied for the compiler as it traverses through syntax trees. This pattern allows operations to be applied to elements without changing the classes[40]. Therefore, classes of elements will not be modified when a new operation is added. 3.2.5 Strategy Pattern A strategy pattern utilizes a set of algorithms that function interchangeably[39]. The strategy pattern allows different strategies to be applied to the same method. By implementing this pattern, from the same interface, different code could theoretically be generated by using different programming language strategies. To obtain Julia code, a Julia strategy would be incorporated, or an Octave strategy to output Octave code. 21 CHAPTER 4 SWIFT APPLICATION 4.1 Desktop GUI For the desktop graphical user interface (GUI), a Mac Computer with Xcode 7.3 installed, was used. The user interface was created using a natural language model generator by Dr. Jeffrey Varner [46]. The hybrid model generator required the user to select an input text file located in the user’s computer. The input text file could be from any location on the computer. For example, the user could select files from the desktop, documents, or the downloads folder. Once the user selects the location of the input file, the user is then also required to select a location for the output generated files. Figure 4.1: Desktop GUI for selecting input files 22 In Figure 4.1, a test trial is shown where the input text file is selected from the user’s downloads folder. The output location is a defined folder on the user’s desktop. The generated output files will then be saved to the selected folder. The user also receives status messages window. If the system finds an error it will be reported in the window, if there are no errors found the run will be successful. The GUI will include a status message indicating that the run was successful and the code was generated. 4.1.1 GitHub Figure 4.2: GitHub Desktop Application Interface For the system utilizing the desktop GUI, a compatible GitHub application for the desktop is available. The user can define a local repository within the GitHub desktop application to store the output Julia files. On the model gener- 23 ator, the user will then select the local repository as the location for the output files. Once the files are uploaded to the repository, from the GitHub desktop application, the user can select publish, which will then publish the repository to the user’s online GitHub account. Once the user makes a commit and selects sync, and the changes from commits will be shown on the user’s GitHub account. As shown in Figure 4.2, the various output Julia model files are shown in the defined repository titled generated code. Any changes from previous files are highlighted in red to contrast with the modifications in green. In the bottom left side of the application, the user can write a commit to summarize the changes made. From the top right of the application, the user can sync the changes from the local repository to the repository on the user’s online GitHub account. The new files and commit will be shown on the user’s GitHub account. 4.2 iPad GUI An initial application was developed for the Apple iPad for developing model code for metabolic pathways. Therefore, Swift programming was the chosen programming language due to its compatibility with iOS devices. The application system was composed of a GUI, mediator, and compiler. The front end GUI would interact with the user to accept text file inputs. The mediator would then send the files as inputs with corresponding messages to the compiler. The compiler would then function to output model code. The GUI functions to allow the user to download, modify, and upload text files that the compiler will then take as inputs. The user should be able to create, send and receive text files from their computers to the iPad, and vice versa. The 24 front end GUI provided two file transferring techniques for the user. One file transferring method applied to the GUI was Dropbox. The user can download text files from his Dropbox account to the application. Another file transferring system applied was AirDrop, allowing users with Mac computers to transfer files to iOS devices. 4.2.1 Dropbox During the application development, the Dropbox user interface was titled TextTransfer. The objective of TextTransfer was to allow the user to be able to transfer text files from his Dropbox account to the iPad. To incorporate Dropbox authorization from the user, Texttransfer applied SwiftyDropbox, the Swift SDK for Dropbox, allowing the user to log into his Dropbox account as shown in Figure 4.3 [16][14]. The user will need to enter the Dropbox email address and password associated with his account. Figure 4.3: Sign in window for the user to log into DropBox 25 After the Dropbox credentials are entered, the user can then choose whether or not to allow the application to have access to the Dropbox account seen in Figure 4.4. If the user allows access, then the application is then granted access to read the files in the user’s account. Figure 4.4: TextTransfer application verifies with the user for permission to access Dropbox files In Figure 4.5, the files are listed to the user to select and download due to SwiftyDropbox [15]. The list of Dropbox files informs the user which files are in the user’s account. Files can then be downloaded and saved into the document directory in the application. 26 Figure 4.5: Example list of files in a user’s dropbox account 27 Figure 4.6: TextTransfer graphical user interface The user can also create files by typing in the given text fields for file name, file text, and file extension in Figure 4.6. By selecting the upload button from the GUI, the application then creates the file from the user’s inputs and uploads the file to the user’s Dropbox account. Then from his computer, the user can view the file on Dropbox and download the file. The corresponding Swift code, TextTransfer files are included in Appendix A. 28 4.2.2 AirDrop Another application for file transferring on the iPad utilized AirDrop. AirDrop enables content sharing between iOS devices and Mac computers through Wi-Fi and Bluetooth [23]. The Airdroptest application provided AirDrop as a selection to share text files from the iPad to the user’s computer [19]. The file is then available in the user’s downloads on his computer. The user can also carry out the reverse method. Files from the computer can be shared via AirDrop to the iPad, and opened in the Airdroptest application. Figure 4.7: Share icon shortcut menu with AirDrop In Figure 4.7, the top left indicates the share icon. For users on Mac desktops, when using applications, the share icon will be visible. Users can select the icon which will then cause a shortcut menu to appear. For Figure 4.7, by selecting send a copy of the file, another shortcut menu will appear for the user to select various sharing applications. Therefore, from the list of sharing applications available to the user, AirDrop can then be selected. 29 Figure 4.8: Control click with share with a shortcut menu with AirDrop Similarly, in Figure 4.8, AirDrop can be selected from a shortcut menu. However, the method differs from 4.7. Instead of the user clicking the share icon from applications, the user will control click a file from the Finder window. Once the user control clicks a file, the share option is shown in the shortcut menu. Then the user can select share and choose a sharing option. For the Mac desktops, it provides AirDrop among other options including Mail and Messages applications. The user can select AirDrop to share the selected file on Finder. Figure 4.9: Example recipients to share with on AirDrop[7] 30 Figure 4.9 shows an example menu that will appear to the user after selecting AirDrop from the share options using either technique from Figure 4.7 and Figure 4.8. The menu will list users visible to AirDrop, which includes their OSX and iOS devices. The user will then select the recipient from the list to share a file with. Figure 4.10: AirDrop from the Finder menu bar Figure 4.10 showcases a different method to access AirDrop compared to Figure 4.7 and Figure 4.8. From the desktop Finder menu bar, the user can select the go menu. By selecting go, various menus are listed, including the user’s documents, desktop, applications, and AirDrop. Therefore, the user can access AirDrop from the desktop menu bar. 31 Figure 4.11: AirDrop from the desktop Finder window[7] Figure 4.11 shows the screen that will appear from selecting airdrop using the method described in Figure 4.10. It also shows that AirDrop can be selected from the Finder window. When the user opens the Finder window, to the left is a sidebar. Under favorites in the side bar lists AirDrop. By selecting AirDrop from the sidebar will open AirDrop. The screen in the Finder window will show the users that are visible to share with. The bottom of the screen details to the user who can see the user, based on the discoverable setting. The user can either select everyone to be discoverable by everyone, or contacts only. With the contacts only option, only people in the user’s contacts on the device will be able to discover the user. The user can also not be discoverable by selecting no one. Therefore, the user will not be discovered by any other user. Moreover, other users will not be able to see the user to then share files over AirDrop. 32 Figure 4.12: AirDrop Graphical user interface The Airdroptest application GUI, as shown in Figure 4.12, has edit fields for the user to create files, and a share button to share files via AirDrop to a nearby MacBook computer if AirDrop is enabled as well. The text field and modify button allow users to modify files on the GUI. List of files is supposed to indicate the files stored in the application and check file content will access the file and determine the contents. 33 The user can select the share button the GUI to share files from the iPad to a computer within close range as seen in Figure 4.13. With Wi-Fi and Bluetooth activated, if a MacBook user is within distance, the icon on the sharing view will indicate the owner. Figure 4.13: AirDropTest sharing component on the GUI 34 The iPad user can then tap on the icon to share with that user using AirDrop, as shown in Figure 4.14. In this example, the user can share with a user on a MacBook Pro. Figure 4.14: User can tap to share files using AirDrop As seen in Figure 4.15, the MacBook owner is informed that another user wants to share a file from his iPad. The MacBook owner is given the option whether or not to accept the file, or decline. If the user chooses to accept, there is also the option of accepting the file and opening the file immediately. 35 Figure 4.15: MacBook users can accept or decline files shared from AirDrop A MacBook owner could also send a file to the iPad user back using AirDrop. The user can drag files from the desktop to the icon on the AirDrop window. From Figure 4.16, when a MacBook user shares a file using AirDrop back to the Figure 4.16: MacBook users can share files back to the iPad using AirDrop iPad, the user must wait to see if the file will be accepted or declined on the iPad. 36 Figure 4.17: iPad users can decline or accept files shared through AirDrop In Figure 4.17, the iPad screen will indicate a message to the user to choose whether to decline or accept the file a MacBook user is attempting to share. If the user chooses to accept the file, then the iPad will ask the user to choose which application to open the downloaded file. 37 Figure 4.18: If a file is accepted through AirDrop, the user can select the airdroptest application to open the file From Figure 4.18, files downloaded from Airdrop can be opened using the Airdroptest application. By selecting Airdroptest, the application then returns the user to the application GUI. The corresponding Airdroptest code can be found in Appendix B. 38 4.2.3 GitHub For the output code from the compiler, the code would ideally be stored in a repository. The system relies on GitHub repositories. Therefore, a GitHub framework used to allow a GitHub login [41]. From the GUI the user can select authentication, which then proceeds to direct the user to a GitHub loginscreen, as shown in Figure 4.19. Figure 4.19: GitHub user login screen to allow the application authorization The user can then provide their credentials and approve the application having authorization access to the GitHub account. The corresponding github authorization code can be found in Appendix C. 39 4.2.4 Mercury The Mercury framework functions as the mediator between the front end GUI and the back end compiler. An example of a mediator is shown in Figure 4.20, where the control tower functions as the mediator. Each pilot of a plane will communicate with the control tower instead of each other. The control tower then dictates to the pilots who can depart and land in the terminal area [38]. Figure 4.20: Example of a mediator system [38] Therefore, Mercury allows the GUI and the compiler to work together without knowing each other. Mercury will pass messages between the GUI and the compiler. Mercury is composed of different message types and associated keys [47].The message types correspond to the possible messages sent and received between the GUI and compiler. Mercury will receive start and stop messages from the GUI and send the messages to the compiler. If the compiler receives 40 a start message key, then the compiler will start to generate a run by using the text file inputs. The the text file input will be an array of strings. If the compiler receives a stop message key, then the compiler will stop the current run. Other message types in Mercury convey status messages that the compiler can send to the GUI. The GUI can receive a progress message key, then the compiler is in progress running. If the GUI receives an error message, then the text input has an error due to syntax. The last message is a completed message if the compiler finds no errors and is able to generate a run. The corresponding Mercury framework code can be found in Appendix D. 41 CHAPTER 5 CODE GENERATION 5.1 First Generation Grammar Statement Structure The compiler relies on grammar models while parsing through tokens. Grammar statement strategies were established to determine if the given input text statements followed the grammar models. The first generation grammar strategies followed two patterns. The first pattern focused on either transcription or translation depending on the keyword of the sentence. The second pattern was a regulation pattern that indicated transcription or expression being induced or repressed as shown in Figure 5.1. Figure 5.1: A. Example motif B. First generation grammar strategies 42 Figure 5.1A showcases an example motif where a trigger is transferred from the system. Trigger as metabolite will induce the transcription of gene N1 that results in the expression of mRNA N1. Moreover, protein N1 induces the transcription of gene N1 and gene N2, which results in the expression of the mRNA N1 and mRNA N2. However, protein N2 represses the transcription of gene N1 and the expression of mRNA N1. Figure 5.1B defines the grammar strategies for the first generation compiler. The strategies are classified in by different patterns. One pattern focuses on transcription and translation, where a user defines a biological symbol with a reserved keyword, either transcribes or translates, then another biological symbol is defined by the user. These components then generate another biological symbol created the user. The syntax utilizes generates as an arrow. The other pattern is a regulation pattern, with a structure of an user defined symbol with action reserved keywords for another biological symbol. A user defined biological symbol will either induce or repress the transcription or expression of another biological symbol. Based on the motif in Figure 5.1A, Figure 5.1B lists examples in relation to the grammar strategies. The first example for the transcription and translation patterns, describes the motif with RNAP transcribes gene N1 and gene N2 that generates mRNA N1 and mRNA N2. Then the second example showcases translation with ribosome translates mRNA N1 and mRNA N2 into protein N1 and protein N2. For the regulation pattern, the first example indicates the expression of protein N2 is being induced by protein N1. The second example indicates the auto regulation system where protein N1 induces the expression protein N1. The last example is the expression of protein N1 is being repressed by protein N2. 43 Figure 5.2: Example of first generation grammar strategies Following the format of the grammar strategies from Figure 5.1, Figure 5.2 shows various example statements color coded based on the grammar strategies. Biological symbols highlighted in green correspond the symbols in the transcription or translation pattern. The words highlighted in yellow are associated with reserved keywords. In the basal transcription example, the keywords are transcribes and translates. The words in orange are other biological symbols defined by the user syntactically after the reserved keyword. The generates symbol is coded in purple, and the final products are highlighted in blue. For the regulation pattern, the first input biological symbols are also highlighted in orange. The reserved keywords induces, represses, and transcription are highlighted in yellow. Similar to the transcription and translation pattern, the generates symbol is purple and the last products are blue. In the interactions statements, the user defined biological symbols Trigger, protein N1, protein N2, 44 gene N1, and gene N2 are highlighted in orange. The reserved keywords induces and transcription are highlighted in yellow, while the mRNA products are in blue. Comparing the example statements in Figure 5.2 to the grammar strategies in Figure 5.1, the words the and of are skipped. The grammar strategies focus on looking at the reserved keywords, and the biological symbols. Therefore, the meaning of the sentences will still be understood without the other words. 5.2 Second Generation Grammar Statement Structure An issue with the first generation grammar strategies was the lack of flexibility. The statements were restricted to follow two basic patterns based on either transcription and translation or regulation. The second generation grammar statements proposed more statement strategies. The different statement strategies were expanded to include metabolic control statements, metabolic stoichiometry statements, type assignments, system transfers, and expression statements. Similar to the first generation grammar statement strategies, the second generation utilized user defined biological symbols and reserved keywords. The biological symbols and reserved keywords differed depending on the strategy. In Figure 5.3A, the grammar strategy for the type assignment of biological symbols is given. The user defines a biological symbol, then the structure of the statement follows the format is a type of reserved species type. The words is and a are defined as tokens for the compiler to understand the sentence structure. Of is not defined as a specific token, but using natural language, the sentence would follow the format of is a type of, despite of not being strictly defined. The 45 Figure 5.3: Second Generation Grammar Strategies A. Type Assignment Statement Grammar Strategy B. System Transfer Statement Grammar Strategy C. Expression Statement Grammar Strategy reserved species then follows of, the expected reserved species types include proteins, metabolites, DNA, messenger RNA, and regulatory RNA. The first example has P is a type of protein, where P is the user defined biological symbol, and is and a are following the correct grammar strategy with type as the next word. This informs the compiler that this sentence is a type assignment statement when type is read. The reserved species type finishes the statement, in the first example is it a protein. In the second example M is defined as a metabolite and the reserved species type is a metabolite. The second example follows the same structure as the first example of a symbol followed by is a type of, and the corresponding reserved species type. 46 In Figure 5.3B, the system transfer grammar strategy is defined. The structure allows the user to define either a biological symbol or a list of biological symbols. The biological symbols are then transferred either from or to the system. Transferred is the reserved keyword that informs the compiler that the statement follows the system transfer grammar strategy. For the case of a singular biological symbol, such as the example metabolite M 1, it is transferred from the system, whereas in the second example the list of the biological symbols proteins P 1, P 2, and P 3 are transferred to the system. For Figure 5.3C, the grammar strategy is associated with expression statements. The user can define either a biological symbol or a list of biological symbols, followed by a reserved keyword either induces or represses. The statement structure then skips the word the, but reads the reserved keyword expression or transcription and skips of to result in a user defined biological symbol or a list of biological symbols. Though the words, the and of, are skipped in the structure, the overall statement meaning is still readable by the compiler as the biological symbols either induces or represses expression or transcription of defined biological symbols. In the example for Figure 5.3C, metabolite M 1 induces the expression of Protein P 1, the user defined symbols are metabolite M 1 and protein P 1 with the reserved keywords are induces and expression. In the second example, following the same structure, the user defined symbols are protein P 1 and protein P 2, with the reserved keywords represses and expression. In Figure 5.4A, the grammar strategy for metabolic control statements is defined. The structure has the user define a biological symbol or list of biological symbols followed by a reserved keyword. For the metabolic control case, the 47 Figure 5.4: Second Generation Grammar Strategies A. Metabolic Control Statement Grammar Strategy B. Metabolic Stoichiometry Statement Grammar Strategy reserved keywords are associated with activates or inhibits. After the reserved keywords, another biological symbol or list of biological symbols are then defined. As shown in Figure 5.4A, an example following the statement structure with Metabolite M 1 and M 2 activates protein P 1 and P 2. The first component of the statement is the list of biological symbols, metabolites M 1 and M 2, followed by the reserved keyword activates, which is then completed by another list of biological symbols. For the first example, the list of biological symbols includes Protein P 1 and protein P 2. The second example has one biological 48 symbol, Metabolite M 3 with the reserved keyword inhibits. The metabolite inhibits a list of biological symbols, in this example are also Protein P 1 and Protein P 2. The grammar strategy for metabolic stoichiometry statements is shown in Figure 5.4B. Similar to the metabolic control statement grammar strategy, the structure utilizes user defined biological symbols followed by reserved keywords then more biological symbols. For metabolic stoichiometry, the first input in the statement can either be solely a biological symbol, a list of biological symbols, a biological symbol generating a biological symbol or a list of biological symbols, or a list of biological symbols generating a biological symbol or a list of biological symbols. Depending on the first defined symbols of the user, the reserved keyword could be catalyze, catalyzes, or multiple keywords with is catalyzed by. To finish the statement structure, the user defines more biological symbols after the reserved keywords. Once again, the user can define a biological symbol, a list of biological symbols, a biological symbol generating a biological symbol or a list of biological symbols, or a list of biological symbols generating a biological symbol or a list of biological symbols. The first example in Figure 5.4B has a list of biological symbols forming a reaction to generate another biological symbol. In this structure Metabolite M 1 and Metabolite M 2 generate Metabolite M 3. Metabolite M 3 is then catalyzed by a list of biological symbols, Protein P 1 or Protein P 4. Similarly, in the second example the reserved keywords is catalyzed by is associated with the user defined symbols, Metabolite M1 generating Metabolite M 3 and the resulting biological symbol Protein P 4. The third example for the grammar strategy has a list of biological symbols either Protein P 1 or Protein P 2 that catalyzes Metabo- 49 lite M 3 generating Metabolite M 4. Figure 5.5: Example of second generation grammar strategies In Figure 5.5, the examples of the second generation grammar strategies are shown colored coded based on the strategies from Figure 5.4 and Figure 5.3. Green biological symbols are the initial inputs in the statements. The orange and purple highlighted terms are defined tokens in the grammar strategies to fit natural language syntax. The words is, a, and from make the sentences grammatically correct, following natural language. Yellow highlighted terms are associated with reserved keywords. The blue highlighted terms are the final defined biological symbols that the user defines. Each statement ends with a semicolon for the compiler to know the statement has ended. 50 5.3 Julia Programming Language The generated output code modeling biological pathways is given in the Julia programming language. Julia was used based on its performance similar to other programming languages. Julia can call functions in both Python and C. Moreover, Julia is open source and not proprietary. It does not cost users to obtain Julia. Julia also has various external packages that have been contributed by its community of developers [27]. Based on those aspects Julia was selected compared to other languages, such as MATLAB. If MATLAB was chosen, it would cost users money to obtain since MATLAB is dependent on licenses. Users would need to pay to purchase MATLAB products [33]. In the Hybrid Model Generator Swift project, Julia Language Strategy Library defines the output Julia files that are generated to the user [46]. The files consist of Project, SolveBalanceEquations, Balances, Control, DataFile, and Kinetics. 5.3.1 Output Files Project In the Julia Project file, statements for all model files are included. Therefore, when the compiler completes a successful run, all the Julia files in the project will be generated. 51 SolveBalanceEquations The SolveBalanceEquations Julia file is dependent on CVODE from the Sundials package to solve the balance equations [26]. For ordinary differential equation systems, CVODE from Sundials(SUite of Nonlinear and DIfferential/ALgebraic Equation Solvers) is used for solving initial value problems [25]. The file calls on the Balances Julia file, and the DataFile Julia file. Balances Balances calls on the Control Julia file and the Kinetics Julia file, while it is called by the SolveBalanceEquations Julia file. The file’s main function is to encode material balance equations for the metabolic model. Control Control is called by the Balances Julia file. Its main function is to calculate both gene expression and metabolic control vectors. DataFile DataFile is called by SolveBalanceEquations. The Julia file works by creating a data dictionary. The data dictionary stores information about the model, including initial conditions and control and kinetic parameters. 52 Kinetics Kinetics is called by the Balances Julia file. The Kinetics file functions by encoding the gene expression and metabolic kinetics. 53 CHAPTER 6 FUTURE WORK 6.1 Conclusion The system resulted in a new innovative application to generate simulation code for biological pathway models. The application provided a new methodology for automatic code generation that could be used in scientific fields. Biological fields focusing on pathway models could benefit from this system. Simulation code for modeling biological pathways could easily be generated by the compiler with simple text files. Users would start with unstructured text that would then result into model code. Therefore, users would not have manually write code for pathways. This automatic generation system is significant for people with non-programming backgrounds. Users with non-programming backgrounds will not need to produce code themselves. The minimal requirement to use the system is being able to write text files. Therefore, in scientific fields, users with a biological background, but may lack a programming background could rely on this application. They could write simple biological statements and have the compiler generate simulation code for them. A programming background would not be necessary. However, the application could also be beneficial towards those with programming backgrounds. Users with programming background could manually program simulation code and use the application as a checking system. They could run the application and see if the generated code is the same as what they had manually coded. The application architecture relied on graphical user interfaces, a message passing layer, and a natural language compiler to provide an accessible, user 54 friendly system. The graphical user interfaces provided multiple ways to input text files. By proposing both a desktop interface and an iPad interface, users with either device could benefit from the application. If users choose to access the application on their computer they can easily select a text file anywhere on their computer, such as from their documents, desktop, or downloads. Alternatively, if users have an iPad, the application provides them multiple options to access their text files. Users could either choose to obtain files from their Dropbox account or through AirDrop. Users can directly access their Dropbox account from the iPad GUI, or transfer files from their computer to the iPad. By allowing multiple user interfaces, the application provides various ways users can interact with the system that works for them. By incorporating a message passing layer, the GUI and the compiler are able to send messages back and forth. These messages are significant to the system as they instruct the user of any errors that may occur. The natural language compiler on the desktop GUI was successful in generating output Julia code. It was able to read simple text files with biological statements. Therefore, by using a natural language compiler system, users with a non-programming background could input text files to then generate code for modeling biological pathways. However, the current system could be improved. Various issues with the system’s components will be addressed, followed by suggested improvements. 55 6.2 Graphical User Interfaces The compiler currently is functional on the desktop GUI, but not on the iPad. The compiler Swift code will need to be translated and updated for iOS compatibility. The desktop compiler follows frameworks for OSX devices utilizing Cocoa framework and AppKit, instead of CocoaTouch and UIKit. The same methodology from the Swift desktop compiler code can be applied for the iPad as the same grammar strategies are being used. The overall frameworks and structure of the view controller will need to change. The desktop compiler currently uses multiple message passing Swift classes directly in the Xcode project. The Mercury framework will focus on the same aspects of the multiple message classes, but condense the classes as one framework to be included in the compiler project. The iPad GUI provides a GitHub authorization sign in for the user to login into their account, however, it does not provide a working process to create new repositories to upload code. The GUI should be modified to allow the user to create new repositories which will be used to store generated output code. The compiler project for the iPad GUI will be based on the Swift code used for the desktop GUI, but modified for iOS devices. The iPad GUI Swift classes will need to incorporate functions to allow users to create new repositories on their GitHub accounts. The user should be able to name the repository, and have generated code from the compiler be stored in the repository. The GitHub authorization Swift file will be changed and improved to allow users to see their repositories and create respoistiories directly from the GUI. The application on the iPad currently applies two file transferring methods, 56 DropBox and AirDrop. Further methods could be added to the application to provide the user more options. Various other options to input text files from the GUI can be included such as email, GitHub, etc. The GUI can be modified from the UIActivityViewController, by including previous excluded activity types in the Viewcontroller.Swift file [23]. Email can be included, where the application needs to request the user to log into their email account. The user can then download attachments files in their email. Repositories in a user’s GitHub account could also be an option. The user can log into their account and download files from repositories. 6.3 Message Passing Layer Mercury currently has Swift classes for various status messages. However, some of the status message files can be considered incomplete. For example, the error message Swift file needs to incorporate various error cases. The error message file should be able to output different error messages depending on the cases of syntax or biology. The status messages will be edited to account for various cases. The error message file will need to state different error messages back to the user. If there is a syntactical error in the text input, then the user should receive an error message stating there was a syntax error and the location of the error within the text file. If the error is due to not making biological sense, the message file should have a case to indicate a biology error. The user should then receive a message stating the biological reason why there was an error. The error messages could also be improved to highlight the error to the user corresponding to the line and 57 column numbers of the error. 6.4 Compiler The compiler utilizes grammar strategies based on reserved keywords. In a grammatical sense, the system can read natural language, however in a biological sense the system functions incorrectly. No notion of a biological error, the system currently only checks for syntactical errors. For example, if the statement protein 1 induces the transcription of protein 2, the compiler will read that statement as correct. The grammar of the statement will be considered correct following the expression statement grammar strategy. The biological symbols protein 1 and protein 2 are acceptable tokens, and the reserved keywords are defined in the sentence with induces and transcription. However, the issue lies in the biological sense, the statement should call an error to the user. Biologically, protein 1 does not induce the transcription of protein 2. The compiler should return an error based on the biology of the statement being incorrect. The system currently only considers the grammar of the statements, not the biology. Therefore, the system needs to be improved to incorporate the biological definitions behind the statements. The input statements need to make sense biologically as well as grammatically. Semantics will need to be checked as the current system does not recognize errors in the biological sense. Another issue is the sentence delimiter where a semicolon at the end of each input statement is necessary for the compiler to run. The system expects the user to always use semicolons, missing a semicolon will result in an error. Multiple sentence delimiters should be included as possible symbols. 58 The Swift classes will need to be improved as currently, the generated output Julia files produce inaccurate statements. The functions defined in the Julia files are correct, but the inputs, such as the state vector, are not. In the files, the vectors produced are incorrect as extra factors are included. For example, the Kinetics Julia language file had listed a state vector with gene p n1, gene n1, mrna n1,mrna p n1, and p n1 in one test run for the compiler. The terms gene p n1 and mrna p n1 indicate product terms for gene n1 and mrna n1, but the product terms are already listed with mrna n1 and p n1. The Swift code files will need to be debugged to determine what is causing the extra terms to appear in the generated output files. For future iterations, the compiler should be able to determine if given text inputs make biological sense, and recognize if there are errors. The compiler will need to be able to understand whether the user defined biological symbols make biological sense with the reserved keywords chosen. Therefore, the compiler will need to be able to declare errors based on biology. The system also currently sends back an error message to the user as soon as it finds the first error. A possible change that could be made to the compiler is instead of only throwing the first error and stopping, the compiler runs through the entire given text file and returns to the user all found errors. The system checks for individual tokens for reserved keywords. In each grammar strategy, only a few keywords are defined, such as activates and inhibits. However, to improve the grammar strategies, synonyms for each reserved keyword could be added in the system. For activates, upregulates could be a possible option, and similarly for inhibits, downregulates could be included. An addition of a set of possible keywords could be defined. There- 59 fore, when the system checks for a token, it can determine whether the keyword is a member of the keyword set. By including a set of keywords, the user will not be limited to just one or two of the previous keywords of the grammar strategies. Moreover, alternative spellings for keywords could be included. For example, in the metabolic stoichiometry statement grammar strategy, the reserved keyword is catalyze. Catalyze could also be spelled as catalyse. The compiler currently only reads the first spelling, and does not understand the alternative spelling. Therefore, the compiler could be improved to read alternative spellings for words in the given input text. Additional sets could also be applicable to punctuation. The current system relies on having each input text sentence end with a semicolon. The semicolon is for helping the compiler determine when the statement has ended. However, ending a statement with a semicolon is not intuitive for natural language. To improve the system, a set of possible punctuation marks could be included. The user will not be restricted to having to use only semicolons. The set could include punctuation marks such as a period, or a comma. Other output code options could be included in the system. Currently, the desktop system outputs code in the Julia programming language. Other programming languages could be added to the generator, such as C, Octave, Python, or Swift. The generated files can be defined in their respective languages and added into the Swift project by incorporating language strategy library files. By incorporating various programming languages, the compiler could then generate code for biological pathway models in a language that a user selects. 60 APPENDIX A DROPBOX GUI Swift Programming Language Code for iPad Application Dropbox GUI // // AppDelegate.swift // TextTransfer // // Created by Rohaine Hsu on 9/12/15. // Copyright 2015 Rohaine Hsu. All rights reserved. // import UIKit import SwiftyDropbox @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after // application launch. Dropbox.setupWithAppKey("") 61 return true } func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool { if let authResult = Dropbox.handleRedirectURL(url) { switch authResult { case .Success(let token): print("Success! User is logged into Dropbox.") case .Error(let error, let description): print("Error: \(description)") } } return false } func applicationWillResignActive(application: UIApplication) { /*// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or 62 when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.*/ } func applicationDidEnterBackground(application: UIApplication) { /*// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.*/ } func applicationWillEnterForeground(application: UIApplication) { /*// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.*/ } 63 func applicationDidBecomeActive(application: UIApplication) { /* // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.*/ } func applicationWillTerminate(application: UIApplication) { /*// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.*/ } } 64 // // TableViewController.swift // TextTransfer // // Created by Rohaine Hsu on 10/23/15. // Copyright 2015 Rohaine Hsu. All rights reserved. // import UIKit var data: NSMutableArray! class TableViewController: UITableViewController { var data = [] override func viewDidLoad() { super.viewDidLoad() /*// Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 65 // self.navigationItem.rightBarButtonItem = self.editButtonItem()*/ } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be // recreated. } // MARK: - Table view data source /* override func numberOfSectionsInTableView (tableView: UITableView) -> Int { // #warning Incomplete implementation, return the number of sections return 0 }*/ override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return data.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) 66 -> UITableViewCell { let cell = tableView.dequeueReusable CellWithIdentifier ("FileCell", forIndexPath: indexPath) as! UITableViewCell cell.textLabel?.text = data[indexPath.row] as! String return cell } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let indexPath = tableView.indexPathForSelectedRow let currentCell = tableView.cellForRowAtIndexPath (indexPath!) as UITableViewCell? //print("/\(currentCell!.textLabel!.text)") if let name = currentCell!.textLabel!.text { ViewController().downloadfile("/\(name)") //ViewController().write("/\(name)") //ViewController().filecontent("\(name)") //ViewController().write("\(name)") //ViewController().filecontent("/\(name)") } } /* // Override to support conditional editing of 67 the table view. override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // Return false if you do not want the specified item to be editable. return true } */ /* // Override to support editing the table view. override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { if editingStyle == .Delete { // Delete the row from the data source tableView.deleteRowsAtIndexPaths ([indexPath], withRowAnimation: .Fade) } else if editingStyle == .Insert { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view } } 68 */ /* // Override to support rearranging the table view. override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { } */ /* // Override to support conditional rearranging of the table view. override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { // Return false if you do not want the item to be re-orderable. return true } */ /* // MARK: - Navigation // In a storyboard-based application, you will often 69 want to do a little preparation before navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { // Get the new view controller using segue.destinationViewController. // Pass the selected object to the new view controller. } */ } 70 // // ViewController.swift // TextTransfer // // Created by Rohaine Hsu on 9/12/15. // Copyright 2015 Rohaine Hsu. All rights reserved. // import UIKit import SwiftyDropbox class ViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate { var filenames: Array! override func viewDidLoad() { super.viewDidLoad() self.filename.delegate = self; self.filetext.delegate = self; self.fileextension.delegate = self; self.modifytext.delegate = self; self.modifycontent.delegate = self; 71 self.modifycontent.editable = true self.modifycontent.layer.borderColor = UIColor(red: 0.9, green: 0.9, blue: 0.9, alpha: 1.0).CGColor self.modifycontent.layer.borderWidth = 1.0 self.modifycontent.layer.cornerRadius = 5 self.filenames = [] // Verify user is logged into Dropbox if let client = Dropbox.authorizedClient { // Get the current user’s account info client.users.getCurrentAccount().response { response, error in print("*** Get current account ***") if let account = response { print("Hello \(account.name. givenName)") } else { print(error!) } } // List folder client.files.listFolder(path: "").response { response, error in 72 print("*** List folder ***") if let result = response { print("Folder contents:") for entry in result.entries { print(entry.name) self.filenames!.append (entry.name) } } else { print(error!) } print(self.filenames) } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be // recreated. } @IBAction func linkButtonPressed(sender: AnyObject) { if (Dropbox.authorizedClient == nil) { 73 Dropbox.authorizeFromController(self) } else { print("User is already authorized!") //Dropbox.unlinkClient() } } @IBAction func viewFileContent(sender: AnyObject) { filecontent("test.txt") } /*func filecontent(filepath: String) { let documentDirectoryURL = try! NSFileManager. defaultManager().URLForDirectory(.Document Directory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) let fileDestinationUrl = documentDirectoryURL. URLByAppendingPathComponent("\(filepath)") do { let contentsOfFile = try NSString (contentsOfFile: fileDestinationUrl.path!, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") } catch let error as NSError { 74 } }*/ print(error) print("No file found") func filecontent(filepath: String) { let fileManager = NSFileManager. defaultManager() let directoryURL = fileManager. URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask)[0] let fileDestinationUrl = directoryURL. URLByAppendingPathComponent("\(filepath)") // print(fileDestinationUrl) do { let contentsOfFile = try NSString (contentsOfFile: fileDestinationUrl.path!, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") } catch let error as NSError { print(error) print("No file found") } 75 } /*func downloadfile(filename: String){ if let client = Dropbox.authorizedClient { let destination: (NSURL, NSHTTPURLResponse) -> (NSURL) = { (temporaryURL, response) in if let directoryURL = NSFileManager. defaultManager().URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask) [0] as? NSURL { let path = directoryURL. URLByAppendingPathComponent ("\(filename)") return path } return temporaryURL } client.files.download(path: filename, destination: destination).response { response, error in if let (metadata, data) = response 76 } }*/ } { print("*** Download file ***") print("Downloaded file name: \(metadata.name)") //print("Downloaded file data: \(data)") } else { print(error!) } func downloadfile(filename: String){ if let client = Dropbox.authorizedClient { let destination : (NSURL, NSHTTPURLResponse) -> NSURL = { temporaryURL, response in let fileManager = NSFileManager. defaultManager() let directoryURL = fileManager. URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask)[0] // generate a unique name for 77 // this file in case //we’ve seen it before //let UUID = NSUUID().UUIDString //let pathComponent = "\(UUID)//\(response.suggestedFilename!)" let newfilename = String(filename. characters. dropFirst()) print(newfilename) if self.checkexisting(newfilename) { let index = newfilename.startIndex let index2 = newfilename.endIndex. advancedBy(-4) let other = newfilename[Range (start: index, end: index2)] print(other) let character = other.characters. last! print(character) let char = String(character) if char >= "0" && char <= "8" { let number = Int(char) let newvalue = number! + 1 78 let newchar = String(newvalue) let index3 = other.endIndex. advancedBy(-1) let other2 = other[Range (start: other.startIndex, end: index3)] print(other2) let name = other2 + newchar + ".txt" return directoryURL. URLByAppendingPathComponent(name) } else if char == "9" { let index3 = other.endIndex. advancedBy(-2) let char2 = other[index3] print(char2) let charString = String(char2) if charString >= "1" && charString <= "8" { let number = Int(charString) let newvalue = number! + 1 79 let newchar = String (newvalue) let other2 = other[Range (start: other.startIndex, end: index3)] print(other2) let name = other2 + newchar + "0.txt" return directoryURL. URLByAppendingPathComponent (name) } if charString == "9" { let other2 = other[Range (start:other.startIndex, end: index3)] print(other2) let name = other2 + "100.txt" if self.checkexisting(name) { let index = name. startIndex 80 let index2 = name. endIndex. advancedBy(-4) let other = name[Range (start: index, end: index2)] print(other) let newname = other + ".1.txt" print(newname) return directoryURL. URLByAppendingPath Component(newname) } return directoryURL.URLBy AppendingPathComponent(name) } else { let index3 = other.endIndex. advancedBy(-1) let other2 = other[Range (start:other.startIndex, end: index3)] print(other2) 81 let name = other2 + "10.txt" return directoryURL.URLBy AppendingPathComponent(name) } } else if char == ")" { let index3 = other.endIndex. advancedBy(-2) let char = other[index3] let charString = String(char) if charString >= "0" && charString <= "9" { let number = Int (charString) let newvalue = number! + 1 let newchar = String(newvalue) let other2 = other [Range(start: other.startIndex, end: index3)] 82 print(other2) let name = other2 + newchar + ").txt" if self.checkexisting (name) { let index = name. startIndex let index2 = name. endIndex. advancedBy(-4) let other = name [Range(start: index, end: index2)] print(other) let newname = other + ".1.txt" print(newname) return directoryURL. URLByAppending PathComponent(newname) } return directoryURL. URLByAppendingPath Component(name) 83 } //return directoryURL. URLByAppending PathComponent(name) } else { let name = other + "1.txt" return directoryURL. URLByAppending PathComponent(name) } } else { return directoryURL.URLByAppending PathComponent(newfilename) } /*// let newurl = directoryURL.URL ByAppendingPathComponent("\(newfilename)") // print(newurl) //return directoryURL.URLByAppendingPath Component(newfilename) // return directoryURL.URLByAppendingPath 84 Component(pathComponent)*/ return directoryURL.URLByAppendingPath Component(newfilename) } client.files.download(path: filename, destination: destination).response { response, error in if let (metadata, url) = response { // print(url) print("*** Download file ***") let data = NSData(contentsOfURL: url) print("Downloaded file name: \(metadata.name)") print("Downloaded file url: \(url)") print("Downloaded file data: \(data)") } else { print(error!) } } } 85 } func checkexisting(filepath: String) -> Bool { let fileManager = NSFileManager. defaultManager() let directoryURL = fileManager. URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask)[0] let fileDestinationUrl = directoryURL. URLByAppending PathComponent("\(filepath)") let filemgr = NSFileManager. defaultManager() if (filemgr.fileExistsAtPath (fileDestinationUrl.path!)) { print("file found") return true } else { print("none") return false } } 86 @IBOutlet var modifycontent: UITextView! @IBOutlet var filename: UITextField! @IBOutlet var filetext: UITextField! @IBOutlet var fileextension: UITextField! func textFieldShouldReturn(textField: UITextField) -> Bool { self.view.endEditing(true) return false } func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { if(text == "\n") { textView.resignFirstResponder() return false } return true } @IBAction func upload(sender: AnyObject) { //createfile("text", filename: "/Sample.txt") self.createfile("\(self.filetext.text!)", filename: ("/\(self.filename.text!). 87 \(self.fileextension.text!)")) } func createfile(text: String, filename: String) { if let client = Dropbox.authorizedClient { // Upload a file let fileData = text.dataUsingEncoding (NSUTF8StringEncoding, allowLossy Conversion: false) print(fileData) //client.filesUpload(path:filename, body: // fileData!).response { response, error in client.files.upload(path:filename, autorename: true, body: fileData!) .response { response, error in if let metadata = response { print("*** Upload file ****") print("Uploaded file name: \(metadata.name)") print("Uploaded file revision: \(metadata.rev)") 88 // Get file (or folder) metadata //client.filesGetMetadata (path: "/test.txt"). // response { response, error in client.files.getMetadata (path: "/test.txt"). response { response, error in print("*** Get file metadata ***") if let metadata = response { //print("Name: //\(metadata.name)") if let file = metadata as? Files. FileMetadata { //print("This is //a file.") print("This is a file with path: \(file.pathLower)") print("File size: \(file.size)") } else if let folder = metadata as? Files.FolderMetadata { 89 //print("This is a //folder.") print("This is a folder with path: \(folder.pathLower)") } } else { print(error!) } } } } } } @IBAction func Check(sender: AnyObject) { files() check("test.txt") } /*func files() { let documentsURL = try! NSFileManager. defaultManager().URLForDirectory( 90 .DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) do { let directoryContents = try NSFileManager. defaultManager().contentsOfDirectoryAtURL (documentsURL.absoluteURL, includingProperties ForKeys: nil, options: NSDirectoryEnumeration Options()) print(directoryContents) } catch let error as NSError { print(error.localizedDescription) } }*/ func files() { let fileManager = NSFileManager .defaultManager() let directoryURL = fileManager .URLsForDirectory (.DocumentDirectory, inDomains: 91 .UserDomainMask)[0] do { let directoryContents = try fileManager.contentsOfDirectory AtURL(directoryURL.absoluteURL, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions()) print(directoryContents) } catch let error as NSError { print(error.localizedDescription) } } /*func check(filepath: String) { let documentDirectoryURL = try! NSFileManager.defaultManager(). URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) let fileDestinationUrl = documentDirectoryURL. URLByAppendingPathComponent 92 ("\(filepath)") let filemgr = NSFileManager.defaultManager() if (filemgr.fileExistsAtPath( fileDestinationUrl.path!)) { print("file found") } else { print("none") } }*/ func check(filepath: String) { let fileManager = NSFileManager.defaultManager() let directoryURL = fileManager. URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask)[0] let fileDestinationUrl = directoryURL .URLByAppending PathComponent("\(filepath)") let filemgr = NSFileManager.defaultManager() if (filemgr.fileExistsAtPath (fileDestinationUrl.path!)) { print("file found") } 93 else { print("none") } } @IBAction func Modify(sender: AnyObject) { //print(self.modifycontent.text) // print(self.modifytext.text!) write("99.txt") } @IBOutlet var modifytext: UITextField! /*func text() -> String { if let a = self.modifytext.text { return self.modifytext.text! } else { return "" } }*/ func write(filepath: String) { //print(self.modifycontent.text!) //if let text = self.modifytext.text { 94 let text = self.modifytext.text! let fileManager = NSFileManager. defaultManager() let directoryURL = fileManager. URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask)[0] let fileDestinationUrl = directoryURL .URLByAppending PathComponent("\(filepath)") print(fileDestinationUrl) do { // try text.writeToFile (fileDestinationUrl.path!, // atomically: true, encoding: NSUTF8StringEncoding) try text.writeToFile (fileDestinationUrl.path!, atomically: true, encoding: NSUTF8StringEncoding) //try self.filetext.text!.writeToURL // (fileDestinationUrl, // atomically: true, encoding: NSUTF8StringEncoding) 95 let contentsOfFile = try! NSString(contentsOfURL: fileDestinationUrl, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") //print("modified content = \()") createfile("\(contentsOfFile)", filename: "/\(filepath)") } catch let error as NSError { print(error) print("No file found") } //} /*else { let text = "" let fileManager = NSFileManager. defaultManager() let directoryURL = fileManager. URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask)[0] let fileDestinationUrl = directoryURL.URLBy 96 AppendingPathComponent("\(filepath)") print(fileDestinationUrl) do { //try text.writeToFile (fileDestinationUrl.path!, atomically: true, encoding: NSUTF8StringEncoding) try text.writeToURL(fileDestinationUrl, atomically: true, encoding: NSUTF8StringEncoding) let contentsOfFile = try! NSString(contentsOfURL: fileDestinationUrl, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") //print("modified content = \()") createfile("\(contentsOfFile)", filename: "/\(filepath)") } catch let error as NSError { print(error) print("No file found") } 97 } let text = self.modifytext.text! //let text = "\(self.modifytext.text!)" print(filepath) let fileManager = NSFileManager. defaultManager() let directoryURL = fileManager. URLsForDirectory (.DocumentDirectory, inDomains: .UserDomainMask)[0] let fileDestinationUrl = directoryURL .URLByAppending PathComponent("\(filepath)") print(fileDestinationUrl) do { //try text.writeToFile (fileDestinationUrl.path!, atomically: true, encoding: NSUTF8StringEncoding) try text.writeToURL (fileDestinationUrl, atomically: true, encoding: NSUTF8StringEncoding) 98 let contentsOfFile = try! NSString(contentsOfURL: fileDestinationUrl, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") //print("modified content = \()") createfile("\(contentsOfFile)", filename: "/\(filepath)") } catch let error as NSError { print(error) print("No file found") }*/ } @IBAction func cancel(segue:UIStoryboardSegue) { } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { var DestViewController = (segue.destinationViewController 99 as! UINavigationController). topViewController as! TableViewController DestViewController.data = self.filenames } } 100 APPENDIX B AIRDROP GUI Swift Programming Language Code for iPad Application AirDrop GUI // // AppDelegate.swift // Airdroptest // // Created by Rohaine Hsu on 9/21/15. // Copyright 2015 Rohaine Hsu. All rights reserved. // import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool { /*do { let contentsOfFile = try NSString( contentsOfFile:url.path!, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") 101 } catch let error as NSError { print(error) print("No file found") }*/ let documentDirectoryURL = try! NSFileManager. defaultManager().URLForDirectory( .DocumentDirectory,inDomain: .UserDomainMask, appropriateForURL: nil, create: true) let fileDestinationUrl = documentDirectoryURL. URLByAppendingPathComponent("Inbox") /*do { let contentsOfFile = try NSString (contentsOfFile: fileDestinationUrl.path!, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") } catch let error as NSError { print(error) print("No file found") }*/ do { let directoryContents = try NSFileManager.defaultManager(). 102 contentsOfDirectoryAtURL (fileDestinationUrl.absoluteURL, including PropertiesForKeys: nil, options: NSDirectory EnumerationOptions()) print(directoryContents) } catch let error as NSError { print(error.localizedDescription) } return true } func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after // application launch. return true } func applicationWillResignActive(application: UIApplication) { /*// Sent when the application is about to move from active to inactive state. This 103 can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.*/ } func applicationDidEnterBackground(application: UIApplication) { /* // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.*/ } func applicationWillEnterForeground(application: 104 UIApplication) { /*// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.*/ } func applicationDidBecomeActive(application: UIApplication) { /*// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.*/ } func applicationWillTerminate(application: UIApplication) { /*// Called when the application is about to terminate. Save data if appropriate. See also application DidEnterBackground:.*/ } } 105 // // ViewController.swift // Airdroptest // // Created by Rohaine Hsu on 9/21/15. // Copyright 2015 Rohaine Hsu. All rights reserved. // import UIKit class ViewController: UIViewController, UITextFieldDelegate { override func viewDidLoad() { super.viewDidLoad() self.filename.delegate = self; self.filetext.delegate = self; self.fileextension.delegate = self; self.text.delegate = self // Do any additional setup after loading the //view, typically from a nib. } override func didReceiveMemoryWarning() { 106 super.didReceiveMemoryWarning() // Dispose of any resources that can be // recreated. } func filecontent(filepath: String) { let documentDirectoryURL = try! NSFileManager. defaultManager().URLForDirectory(.Document Directory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) let fileDestinationUrl = documentDirectoryURL. URLByAppendingPathComponent("\(filepath)") do { let contentsOfFile = try NSString (contentsOfFile: fileDestinationUrl.path!, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") } catch let error as NSError { print(error) print("No file found") } } func inboxfilecontent() { 107 let documentDirectoryURL = try! NSFileManager. defaultManager().URLForDirectory(.Document Directory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) let fileDestinationUrl = documentDirectoryURL. URLByAppendingPathComponent ("Inbox/Other file.txt") do { let contentsOfFile = try NSString (contentsOfFile: fileDestinationUrl. path!, encoding: NSUTF8StringEncoding) print("Content of file = \(contentsOfFile)") } catch let error as NSError { print(error) print("No file found") } } func filesinDocs() { let documentsURL = try! NSFileManager. defaultManager().URLForDirectory (.DocumentDirectory,inDomain: .UserDomainMask, appropriateForURL: 108 nil, create: true) do { let directoryContents = try NSFileManager .defaultManager().contentsOfDirectoryAtURL (documentsURL.absoluteURL, includingProperties ForKeys: nil, options: NSDirectoryEnumeration Options()) print(directoryContents) } catch let error as NSError { print(error.localizedDescription) } } func filesinInbox() { let documentDirectoryURL = try! NSFileManager. defaultManager().URLForDirectory(.Document Directory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) let fileDestinationUrl = documentDirectory URL.URLByAppendingPathComponent("Inbox") do { let directoryContents = try NSFileManager 109 .defaultManager().contentsOfDirectory AtURL(fileDestinationUrl.absoluteURL, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions()) print(directoryContents) } catch let error as NSError { print(error.localizedDescription) } } @IBOutlet var filename: UITextField! @IBOutlet var filetext: UITextField! @IBOutlet var fileextension: UITextField! @IBOutlet var text: UITextField! func textFieldShouldReturn(textField: UITextField) -> Bool { self.view.endEditing(true) return false } @IBAction func createFile(sender: AnyObject) { let documentDirectoryURL = try! NSFileManager. defaultManager().URLForDirectory(.Document Directory, inDomain: .UserDomainMask, 110 appropriateForURL: nil, create: true) let filename = "\(self.filename.text!). \(self.fileextension.text!)" let fileDestinationUrl = documentDirectoryURL. URLByAppendingPathComponent(filename) let contentsOfFile = "\(self.filetext.text!)" var error: NSError? do { try contentsOfFile.writeToURL (fileDestinationUrl, atomically: true, encoding: NSUTF8StringEncoding) if let errorMessage = error { print("Failed to create file") print("\(errorMessage)") } else { print("File \(self.filename.text!). \(self.fileextension.text!) created") } } catch let error as NSError { print(error) } } 111 @IBAction func Checkfilecontent(sender: AnyObject) { inboxfilecontent() } @IBAction func listoffiles(sender: AnyObject) { filesinDocs() filesinInbox() } @IBAction func shareFile(sender: AnyObject) { let documentDirectoryURL = try! NSFileManager. defaultManager().URLForDirectory (.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true) let text = documentDirectoryURL.URLByAppending PathComponent("sample.txt") /*let path = NSBundle.mainBundle().pathFor Resource("Testfile", ofType: "txt") let text = try? NSString(contentsOfFile: path!, encoding: NSUTF8StringEncoding)*/ let controller = UIActivityViewController (activityItems: [text], applicationActivities: 112 nil) controller.excludedActivityTypes = [UIActivityTypePostToFacebook, UIActivityTypePostToTwitter, UIActivityTypePostToWeibo, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypePostToFlickr, UIActivityTypePostToTencentWeibo, UIActivityTypeMail] self.presentViewController(controller, animated: true, completion: nil) if let pop = controller.popover PresentationController { let v = sender as! UIView pop.sourceView = v pop.sourceRect = v.bounds } } @IBAction func modifyfile(sender: AnyObject) { 113 write("sample.txt") } func write(filepath: String) { let text = self.text.text! let fileManager = NSFileManager .defaultManager() let directoryURL = fileManager .URLsForDirectory (.DocumentDirectory, inDomains: . UserDomainMask)[0] let fileDestinationUrl = directoryURL. URLByAppending PathComponent("\(filepath)") print(fileDestinationUrl) do { try text.writeToFile(fileDestinationUrl .path!,atomically: true, encoding: NSUTF8StringEncoding) let contentsOfFile = try! NSString (contentsOfURL: fileDestinationUrl, encoding: NSUTF8StringEncoding) print("Content of file = 114 \(contentsOfFile)") } catch let error as NSError { print(error) print("No file found") } } } 115 APPENDIX C GITHUB AUTHORIZATION Swift Programming Language Code for GitHub Authorization // // SignInViewController.swift // ghauth // // Created by Rohaine Hsu on 3/11/16. // Copyright 2016 Rohaine Hsu. All rights reserved. // import UIKit class SignInViewController: UIViewController, UIWebViewDelegate { let clientId = "" let clientSecret = "" override func viewDidLoad() { super.viewDidLoad() if let webview = view as? UIWebView { webview.delegate = self let urlString = "https://github.com/ 116 login/oauth/ authorize?client_id=\(clientId)" if let url = NSURL(string: urlString) { let req = NSURLRequest(URL: url) webview.loadRequest(req) } } // Do any additional setup after loading // the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be // recreated. } func webView(webView: UIWebView, shouldStart LoadWithRequestrequest: NSURLRequest, navigationType: UIWebView NavigationType) -> Bool { if let url = request.URL where url.host == "ghauth://" { if let code = url.query?.components SeparatedByString("code=").last { let urlString = "https://github.com 117 /login/oauth/access_token" if let tokenURL = NSURL(string: urlString){ let req = NSMutableURLRequest (URL: tokenURL) req.HTTPMethod = "POST" req.addValue("application/json", forHTTPHeaderField: "Content-Type") req.addValue("application/json", forHTTPHeaderField: "Accept") let params = [ "client_id": clientId, "client_secret": clientSecret, "code": code ] req.HTTPBody = try? NSJSONSerialization. dataWithJSONObject (params, options: []) let task = NSURLSession. sharedSession(). dataTaskWithRequest(req) { data, response, error in if let data = data { do { 118 if let content = try NSJSONSerialization. JSONObjectWithData (data, options: []) as? [String: AnyObject] { if let accessToken = content ["access_token"] as? String { self.getUser (accessToken) } } } catch{} } } task.resume() } } return false } return true } func getUser(accessToken: String) { let urlString = "https://api.github.com/user" 119 if let url = NSURL(string: urlString){ let req = NSMutableURLRequest(URL: url) req.addValue("application/json", forHTTPHeaderField: "Accept") req.addValue("token\(accessToken)", forHTTPHeaderField: "Authorization") let task = NSURLSession.sharedSession(). dataTaskWithRequest(req) { data, response, error in if let data = data { if let content = String(data: data, encoding: NSUTF8StringEncoding){ dispatch_async(dispatch_get_ main_queue()){ print(content) self.presenting ViewController?. dismiss ViewControllerAnimated (true, completion: nil) } } } } task.resume() 120 } } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepareForSegue(segue: UIStoryboard Segue, sender: AnyObject?) { // Get the new view controller using segue. destinationViewController. // Pass the selected object to the new view controller. } */ } 121 // // ViewController.swift // ghauth // // Created by Rohaine Hsu on 2/29/16. // Copyright 2016 Rohaine Hsu. All rights reserved. // import UIKit class ViewController: UIViewController { //let kClientId = "" //let kClientSecret = "" override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the // view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be // recreated. } 122 /*func requestGithubAccess () { let authURL = NSURL(string: "https://github.com/ login/oauth/authorize?client_id=\(kClientId) &redirect_uri=githubclient://&scope =user,repo") UIApplication.sharedApplication(). openURL(authURL!) }*/ /*@IBAction func Authenticate(sender: AnyObject) { //requestGithubAccess() }*/ /*func exchangeCodeInURL(codeURL: NSURL) { if let code = codeURL.query { let request = NSMutableURLRequest (URL: NSURL(string: "https://github.com/login /oauth/access_token?\(code)&client_id= \(kClientId)&client_secret= \(kClientSecret)")!) request.HTTPMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Accept") NSURLSession.sharedSession(). 123 dataTaskWithRequest(request, completionHandler: {(data,response, error) -> Void in if let httpResponse = response as? NSHTTPURLResponse { var jsonError : NSError? //if let rootObject = NSJSONSerialization. JSONObjectWithData(data, options: nil, error: &jsonError) as? [String: AnyObject], token = rootObject ["access_token"] as? String { do { let rootObject = try NSJSONSerialization. JSONObjectWithData(data!, options: NSJSONReadingOptions. MutableContainers) as? [String: AnyObject] let token = rootObject! ["access_token"] as? String 124 let request = NSMutableURLRequest (URL: NSURL(string: finalURL)!) request.setValue(token, forHTTP HeaderField: "Authorization") } catch { print(error) } } }).resume() } }*/ } 125 APPENDIX D MERCURY FRAMEWORK Swift Programming Language Code for Mercury framework // // Mercury.swift // Mercury // // Created by Jeffrey Varner on 3/28/16. // Copyright 2016 Varnerlab. All rights reserved. // import Foundation public typealias MessageKey = String public protocol MercuryMessage { func getMercuryMessageKey() -> MessageKey } public protocol MercurySubscriber { func receive(message: MercuryMessage) } public class Mercury { 126 // Class/instance variables public static let sharedInstance = Mercury() private var subscriber_dictionary = Dictionary >() // Define the message keys public static let EchoKey:MessageKey = "ECHO_MESSAGE_KEY" public static let ErrorKey: MessageKey = "ERROR_MESSAGE_KEY" public static let StartKey: MessageKey = "START_MESSAGE_KEY" public static let StopKey: MessageKey = "STOP_MESSAGE_KEY" public static let CompletedKey: MessageKey = "COMPLETED_MESSAGE_KEY" public static let ProgressKey: MessageKey = "PROGRESS_MESSAGE_KEY" // private constructor private init() { // do anything here? // ... } 127 public func subscribe(subscriber: MercurySubscriber, messageKey: MessageKey) -> Void { if (subscriber_dictionary[messageKey] == nil){ subscriber_dictionary[messageKey] = [] } subscriber_dictionary[messageKey]!. append(subscriber) } public func publish(message: MercuryMessage) -> Void { if let subscriber_array = subscriber_dictionary [message.getMercuryMessageKey()] { for subscriber in subscriber_array { subscriber.receive(message) } } } } 128 // // StartMessage.swift // Mercury // // Created by Rohaine Hsu on 4/20/16. // Copyright 2016 Varnerlab. All rights reserved. // import Foundation public class StartMessage:MercuryMessage { public var message_payload:[String]? public func getMercuryMessageKey() -> MessageKey { return Mercury.StartKey } public init() { } public var let UUID = NSUUID().UUIDString } 129 // // StopMessage.swift // Mercury // // Created by Rohaine Hsu on 4/20/16. // Copyright 2016 Varnerlab. All rights reserved. // import Foundation public class StopMessage:MercuryMessage { public func getMercuryMessageKey() -> MessageKey { return Mercury.StopKey } public init() { } public var UUID: String? } 130 // // ProgressMessage.swift // Mercury // // Created by Rohaine Hsu on 4/29/16. // Copyright 2016 Varnerlab. All rights reserved. // import Foundation public class ProgressMessage:MercuryMessage { public var message_payload:String? public func getMercuryMessageKey() -> MessageKey { return Mercury.ProgressKey } public init() { } public var UUID: String? } 131 // // CompletedMessage.swift // Mercury // // Created by Rohaine Hsu on 4/29/16. // Copyright 2016 Varnerlab. All rights reserved. // import Foundation public class CompletedMessage:MercuryMessage { public var message_payload:String? public func getMercuryMessageKey() -> MessageKey { return Mercury.CompletedKey } public init() { } public var UUID: String? } 132 // // ErrorMessage.swift // Mercury // // Created by Rohaine Hsu on 4/20/16. // Copyright 2016 Varnerlab. All rights reserved. // import Foundation public class ErrorMessage:MercuryMessage { public var message_payload:String? public func getMercuryMessageKey() -> MessageKey { return Mercury.ErrorKey } public init() { } public var line_number: String? public var column_numer: String? public var error_sentence: String? public var token: String? public var UUID: String? } 133 BIBLIOGRAPHY [1] Uri Alon. An introduction to systems biology: design principles of biological circuits. CRC press, 2006. [2] Apple. Swift has reached 1.0. https://developer.apple.com/swift/blog/ //?id=14, September 2014. [3] Apple. About swift. https://swift.org/about/#swiftorg-and-open-source, 2016. [4] Apple. About swift. https://developer.apple.com/library/ios/ documentation/Swift/Conceptual/Swift Programming Language/index.html#//apple ref/doc/uid/TP40014097-CH3-ID0, March 2016. [5] Apple. Compiler and standard library. https://swift.org/compilerstdlib/#compiler-architecture, 2016. [6] Apple. Swift. https://developer.apple.com/swift/, 2016. [7] Apple. Use airdrop to send content from your mac. https://support. apple.com/en-us/HT203106, 2016. [8] BBC. Metabolic pathways. http://www.bbc.co.uk/education/guides/ zwnffg8/revision/1, 2016. [9] Larry Bernstein. Signaling transduction tutorial. https://pharmaceutica lintelligence.com/2014/08/12/signaling-transduction-tutorial/, August 2014. [10] Finja Bu¨ chel, Nicolas Rodriguez, Neil Swainston, Clemens Wrzodek, Tobias Czauderna, Roland Keller, Florian Mittag, Michael Schubert, Mihai Glont, Martin Golebiewski, Martijn van Iersel, Sarah Keating, Matthias Rall, Michael Wybrow, Henning Hermjakob, Michael Hucka, Douglas B. Kell, Wolfgang Mu¨ ller, Pedro Mendes, Andreas Zell, Claudine Chaouiya, Julio Saez-Rodriguez, Falk Schreiber, Camille Laibe, Andreas Dra¨ger, and Nicolas Le Nove`re. Path2models: large-scale generation of computational models from biochemical pathway maps. BMC Systems Biology, 7(1):1–19, 2013. 134 [11] K Bretonnel Cohen and Lawrence Hunter. Natural language processing and systems biology. In Artificial intelligence methods and tools for systems biology, pages 147–173. Springer, 2004. [12] Michael Coughlan. Beginning COBOL for Programmers. Apress, 2014. [13] Georgi Dalakov. First compiler of grace hopper. http://historycomputer.com/ModernComputer/Software/FirstCompiler.html, 2016. [14] Dropbox. Swiftydropbox. https://github.com/dropbox/SwiftyDropbox, 2015. [15] Dropbox. Swiftydropbox tutorial. https://www.dropbox.com/developers /documentation/swift#tutorial, 2015. [16] Dropbox. Swiftydropbox documentation. http://dropbox.github.io/ SwiftyDropbox/api-docs/latest/, Feburary 2016. [17] Carol Friedman, Pauline Kra, Hong Yu, Michael Krauthammer, and Andrey Rzhetsky. Genies: a natural-language processing system for the extraction of molecular pathways from journal articles. 17(suppl 1):S74–S82, 2001. [18] Carol Friedman, Lyudmila Shagina, Socrates A Socratous, and Xiao Zeng. A web-based version of medlee: A medical language extraction and encoding system. In Proceedings of the AMIA Annual Fall Symposium, page 938. American Medical Informatics Association, 1996. [19] Nick Hanan. Add sharing to your swift app via uiactivityviewcontroller. http://www.codingexplorer.com/sharing-swift-app-uiactivityview controller/, November 2014. [20] Tony Hey, Anthony J. G. Hey, and Gyuri Pa´pay. The Computing Universe: A Journey through a Revolution. Cambridge University Press, 2014. [21] Michael Hucka, Andrew Finney, Herbert M Sauro, Hamid Bolouri, John C Doyle, Hiroaki Kitano, Adam P Arkin, Benjamin J Bornstein, Dennis Bray, Athel Cornish-Bowden, et al. The systems biology markup language (sbml): a medium for representation and exchange of biochemical network models. Bioinformatics, 19(4):524–531, 2003. [22] National Human Genome Research Institute. Biological pathways. 135 https://www.genome.gov/27530687/biological-pathways-fact-sheet/, August 2015. [23] Arthur Knopper. Airdrop tutorial in ios8 with swift. http://www.ios creator.com/tutorials/airdrop-tutorial-ios8-swift, May 2015. [24] Kostiantyn Koval. Swift High Performance. Packt Publishing, 2015. [25] Computation Lawrence Livermore National Laboratory. Sundials: Suite of nonlinear and differential/algebraic equation solvers. http://computation.llnl.gov/projects/sundials-suite-nonlineardifferential-algebraic-equation-solvers, 2016. [26] The Julia Language. Sundials for julia. https://github.com/julialang/ sundials.jl, 2013. [27] The Julia Language. Julia. http://julialang.org/, 2016. [28] The Systems Biology Markup Language. More detailed summary of sbml. http://sbml.org/More Detailed Summary of SBML, June 2009. [29] Forbes D. Lewis. Recursive descent parsing. http://www.cs.engr.uky.edu /˜lewis/essays/compilers/rec-des.html. [30] E. D. Liddy. Natural language processing. In 2nd, editor, Encyclopedia of Library and Information Science. 2001. [31] Christopher D. Manning, Prabhakar Raghavan, and Hinrich Schu¨ tze. Introduction to information retrieval. http://nlp.stanford.edu/IRbook/html/htmledition/tokenization-1.html, 2008. [32] MathWorks. Model a gene-regulation pathway. http://www.mathworks. com/help/simbio/gs/-model-a-gene-regulation-pathway.html?s tid=gn loc drop, 2016. [33] MathWorks. Pricing and licensing. http://www.mathworks.com/pricinglicensing/index.html?intendeduse=commprodcode=ML, 2016. [34] Torben Ægidius Mogensen. Basics of Compiler Design. Torben Ægidius Mogensen, 2009. 136 [35] Google Cloud Platform. Cloud natural language api beta. https://cloud.google.com/natural-language/, 2016. [36] Google Cloud Platform. Google cloud natural language api documentation. https://cloud.google.com/natural-language/docs/, 2016. [37] Apoorv Saxena, Dan Aharon, and Dave Stiver. Introducing cloud natural language api, speech api open beta and our west coast region expansion. https://cloudplatform.googleblog.com/2016/07/the-latest-forCloud-customers-machine-learning-and-west-coast-expansion.html, July 2016. [38] SourceMaking. Mediator. https://sourcemaking.com/design patterns /mediator, 2016. [39] SourceMaking. Strategy. https://sourcemaking.com/design patterns /strategy, 2016. [40] SourceMaking. Visitor. https://sourcemaking.com/design patterns /visitor, 2016. [41] Tatsuya Tobioka. Sign in with github without 3rd party libraries. http://swift.tnantoka.com/2015/11/13/github-login-from-scratch.html, November 2015. [42] P. Karina Tulipano, Ying Tao, William S. Millar, Pat Zanzonico, Katherine Kolbert, Hua Xu, Hong Yu, Lifeng Chen, Yves A. Lussier, and Carol Friedman. Natural language processing and visualization in the molecular imaging domain. Journal of Biomedical Informatics, 40(3):270 – 281, 2007. [43] Tutorialspoint. Ai - natural language processing. http://www.tutorials point.com/artificial intelligence/artificial intelligence natural language processing.htm, 2016. [44] Tutorialspoint. Cobol - overview. http://www.tutorialspoint.com/cobol/ cobol overview.htm, 2016. [45] Tutorialspoint. Compiler design-top-down parser. http://www.tutorials point.com/compiler design/compiler design top down parser.htm, 2016. [46] Jeffrey Varner. Natural language model generator. https://github.com /jeffreyvarner/NaturalLanguageModelGeneratror, 2015. 137 [47] Jeffrey Varner. Mercury. https://github.com/varnerlab/Mercury, 2016. 138