Toteutusdokumentti Populous Helsinki 10.12.2004 Ohjelmistotuotantoprojekti HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos
Kurssi 581260 Ohjelmistotuotantoprojekti (6 ov) Projektiryhmä Heli Borg Markus Heinonen Ville Luolajan-Mikkola Olli Orajärvi Asiakas Petteri Hintsanen Johtoryhmä Juha Taina Turjo Tuohiniemi Kotisivu http://www.cs.helsinki.fi/group/populous Versiohistoria Versio Päiväys Tehdyt muutokset 0.1 6.12.2004 Ensimmäinen luonnos 1.0 10.12.2004 Ensimmäinen versio
Sisältö i 1 Johdanto 1 1.1 Tuotteen tausta ja tarkoitus......................... 1 1.2 Dokumentin rakenne............................ 1 1.3 Terminologia................................ 2 2 Järjestelmän yleiskuvaus 3 2.1 Toteutus- ja toimintaympäristö....................... 3 2.2 Ohjelmointikielet.............................. 4 2.3 Rajaukset.................................. 4 3 Arkkitehtuurikuvaus 5 3.1 Komponenttien väliset suhteet....................... 5 3.1.1 Suorittava kerros.......................... 6 3.1.2 Kontrollikerros........................... 6 3.1.3 Käyttöliittymäkerros........................ 7 3.2 Luokkien väliset suhteet.......................... 7 3.2.1 Luokkakaavio............................ 7 3.3 Ydin-komponentti.............................. 7 3.3.1 Rajapinta.............................. 9 3.3.2 Enumeraattorit........................... 10 3.3.3 ICore-rajapinta........................... 11 3.3.4 IStatusCallback-rajapinta...................... 11 3.3.5 Core-luokka............................. 11 3.3.6 CoreFactory-luokka........................ 11 3.3.7 Parameters-luokka......................... 12 3.3.8 Log-luokka............................. 14 3.3.9 Globaalit määrittelyt........................ 16 3.4 Pedigree-komponentti............................ 16 3.4.1 Rajapinta.............................. 17 3.4.2 Enumeraattorit........................... 18 3.4.3 IPedigree-rajapinta......................... 18 3.4.4 Pedigree-luokka.......................... 18
ii 3.4.5 PedigreeFactory-luokka...................... 18 3.4.6 FamilyTree-luokka......................... 19 3.4.7 SubPopulation-luokka....................... 20 3.4.8 Individual-luokka.......................... 22 3.4.9 Segment-luokka.......................... 23 3.5 Marker-komponentti............................ 24 3.5.1 Rajapinta.............................. 24 3.5.2 Enumeraattorit........................... 25 3.5.3 IMarker-rajapinta.......................... 25 3.5.4 Marker-luokka........................... 25 3.5.5 MarkerFactory-luokka....................... 26 3.6 Tekstikäyttöliittymä-komponentti...................... 26 3.6.1 Rajapinta.............................. 27 3.6.2 CursesUI-luokka.......................... 27 3.6.3 CursesUIMenu-luokka....................... 28 3.6.4 CursesUIParam-luokka....................... 29 3.6.5 CursesUIResult-luokka....................... 30 3.7 Hakemistorakenne............................. 31 3.8 Tiedostoformaatit.............................. 32 3.8.1 pedigree............................... 32 3.8.2 chrom................................ 33 3.8.3 param................................ 33 4 Käyttöliittymä 33 4.1 Komentorivikäyttöliittymä......................... 33 4.2 Ncurses................................... 37 4.3 Käyttötapaukset............................... 38 4.3.1 Käyttötapaus 1: Sokeritaudin periytymisen tutkiminen....... 39 4.3.2 Käyttötapaus 2: Aineistoa artikkelia varten............. 39 4.3.3 Käyttötapaus 3: Sokeritautigeenitutkimuksen uusiminen...... 40 4.3.4 Käyttötapaus 4: Geeniparametrien toimivuuden testaus....... 41 4.3.5 Käyttötapaus 5: Väärät tutkimustiedot................ 41 4.3.6 Käyttötapaus 6: Ämmänsaaren väestön kehittyminen........ 41
4.3.7 Käyttötapaus 7: Siirtolaisten vaikutus Ämmänsaaren geeniperimään................................. 42 iii
1 Johdanto 1 Tämä toteutusdokumentti kuvaa toteutetun Populous-populaatiosimulaatorin teknisen toteutuksen. Toteutusdokumentissa kuvataan yksityiskohtaisesti toteutetun järjestelmän arkkitehtuuri, komponentit, tietosisältö sekä toteutettavat käyttöliittymät. Toteutusdokumentin perustana käytetään Populous-projektin suunnitteludokumenttia 1.0. 1.1 Tuotteen tausta ja tarkoitus Populous on syksyn 2004 aikana Helsingin yliopiston Tietojenkäsittelytieteen laitoksella Ohjelmistotuotantoprojekti -kurssin puitteissa toteutettu projekti. Projektissa tuotettiin populaation kehityksen simulointiin käytettävän ohjelmiston osa. Projektin pohjana on HIIT -perustutkimusyksikössä käytössä oleva populaatiosimulaattori. Nykyisen populaatiosimulaattorin toiminnassa ilmenneet ongelmat ovat lähtökohtana Populous-projektille. Simulaattori on tehty väitöskirjatyön pohjalta ja muokattu moneen kertaan. Nyt tämän ohjelmistotuotantoprojektin avulla halutaan selkeyttää käytössä olevaa ohjelmaa. Nykyisellään tuote koostuu neljästä erillisestä osasta: genped, chrom, simco ja markertool, sekä skripteistä, joilla niiden toiminta on yhdistetty. Tässä projektissa korvataan käytössä olevan ohjelmiston kaksi ensimmäistä osaa tavoitteena prosessin suoraviivaistaminen. Lisäksi laaditaan käyttöliittymä ohjelmiston käytön helpottamiseksi. Erilaisten geenikartoitusmenetelmien ja genomin rakenteen selvittämiseen tarkoitettujen menetelmien testaamisessa simuloidut aineistot ovat välttämättömiä. Simulointiprosessin lähtökohtana on tyypillisesti yksi populaatioisolaatti. Populaatio koostuu pienestä joukosta yksilöitä, joista populaatio kasvaa annettuun loppukokoon saakka. Simulaatio jäljittelee perusjoukon geenien periytymistä jälkeläisille ja sukupolvelta toiselle laajenemisprosessin kuluessa. 1.2 Dokumentin rakenne Luvussa kaksi kuvataan projektin yhteydessä toteutettu järjestelmä yleisesti. Yleiskuvaukseen sisältyy järjestelmän toteutus- ja toimintaympäristön selvittäminen, käytettävien ohjelmointikielten määritteleminen ja toteutetun ohjelman rajaus. Luku kolme kuvaa toteutetun järjestelmän arkkitehtuurin. Se sisältää yksityiskohtaisen kuvauksen kustakin järjestelmän komponentista ja niiden välisistä suhteista. Ensimmäinen aliluku käsittelee kamponenttien välisiä suhteita ja toinen luokkien välisiä suhteita. Aliluvut 3.3-3.6 kuvaavat ydin-, pedigree-, marker- ja tekstikäyttöliittymäkomponenttien rajapintoja ja luokkia. Luvussa 4 kuvataan projektin yhteydessä toteutetut käyttöliittymät, joita on kaksi: komentorivikäyttöliittymä ja tekstipohjainen Ncurses -käyttöliittymä.
2 1.3 Terminologia Dokumentissa käytetyt termit ja lyhenteet: Alipopulaatio: Populaatio voi jakautua useisiin populaatioisolaatteihin. Alipopulaatioiden välillä pariutumistodennäköisyys on pienempi kuin alipopulaation sisällä. Emäspari: Kromosomeissa sijaitsevat toisiaan vastaavat dna:n rakenneosat. (engl. basepair). Genomi: Perimä eli eliön tai solun sisältämä perinnöllinen informaatio. HIIT -perustutkimusyksikkö: Tietojenkäsittelytieteen laitoksen yhteydessä toimiva Helsingin yliopiston ja Teknillisen korkeakoulun yhteisen Helsinki Institute for Information Technology -tutkimuslaitoksen (HIIT) perustutkimusyksikkö (BRU).Yksikön keskeisiä tutkimusalueita ovat data-analyysi, adaptiivinen laskenta ja laskennallinen neurotiede. Iterointi: Iteroidaan, eli ajetaan koko simulaatiotyö samoilla parametreilla useita kertoja. Alatapaus Marker-iterointi. Loppupopulaatio: Populaatiosimulaation lopussa olevan viimeisen sukupolven edustajat muodostavat loppupopulaation. Marker-iterointi: Iteroidaan simulaatiotyötä, mutta otetaan Pedigree- tiedostot valmiina, jolloin iteroidaan ainoastaan Simcoa ja Markertoolia, ts. sukupuu pysyy staattisena. Markkeri: Kromosomissa paikka, jossa esiintyy yksilöiden välistä vaihtelua. Markertool: Valmis itsenäinen binääri, joka ottaa otoksen markereita kromosomitiedosta käyttäen myös Simcon tulostetta apunaan. Erikoistapauksessa (vanhemmat mukaan otokseen -optio) tarvitaan syötteenä lisäksi viimeisen sukupolven sukupuu ja toiseksi viimeisen sukupolven kromosomitiedosto. Ncurses: Yleisesti käytössä oleva kirjasto tekstitilaisen terminaali-ikkunan sisällön ja toimintojen määrittelyyn. Tässä projektissa NCURSES:lla on tarkoitus toteuttaa yksinkertainen ikkunamainen käyttöliittymä, jolla voidaan suorittaa rinnakkaista ajoa lukuunottamatta samat käyttötapaukset kuin Javalla toteutettava käyttöliittymä. Pedigree: Ohjelman komponentti, jonka vastuulla on sukupuun ja sen yksilöiden genotyyppien generointi (rekombinoimalla), sekä sukupolven kromosomit. Perustajajäsen: Populaation ensimmäisen sukupolven edustaja, jonka perimästä simulaatio lähtee liikkeelle. Populaatio: Joukko saman lajin yksilöitä, jotka elävät samalla alueella. Populaatioisolaatti: Eristäytynyt populaatio, jossa ei geenivaihtoa ulkopuolelta.
Siirtolainen: Muualta populaatioon tuleva yksilö, jonka geeniperimä poikkeaa ko. populaatioisolaatin perimästä. Simco: Valmis itsenäinen binääri, joka generoi halutun määrän SNP- tai STR-markereita (kohtia geenissä, joita voidaan tarkastetella erojen varalta). Toimii itsenäisesti. SNP -mutaatio: Lajin sisäinen, nukleotidisekvenssin tietyssä kohdassa esiintyvä vaihtelu. Muutokset tapahtuvat ainoastaan yhdessä emäsparissa.(engl. SNP = Single Nucleotide Polymorphism). STR-markkerit: Lyhyellä peräkkäisellä kromosomijaksolla toistuvat markkerit. Vaihtelu muodostuu jakson toistojen lukumäärästä. (engl. STR = Short Tandem Repeat). Tekijäinvaihto: Kromosomien risteäminen jakautumisen yhteydessä. (engl. cross-over). Tree: Pelkkä sukupuu ilman perintöainesta. 3 2 Järjestelmän yleiskuvaus Tässä luvussa kuvataan toteutettu järjestelmä. Järjestelmän liittyminen nykyisin käytössä oleviin järjestelmän osiin on esitetty kuvassa 1. Ohjelma muodostuu ohjelmakomponentista, siihen liittyvistä käyttöliittymistä ja kahdesta ulkoisesta ohjelmast: Simco ja Markertool. Simco generoi populaatiolle markkerit ja Markertool kerää populaatiosta otoksen henkilöitä ja heidän markkeridatansa. Ohjelman sisäinen osa vastaa sukupuu- ja geeniaineiston käsittelystä yhdessä ulkoisten komponenttien kanssa. Ohjelmaa voi käyttää kahdella eri tavalla. Komentorivikäyttöliittymällä voidaan yhdellä komennolla ajaa koko simulaatio läpi. Tekstipohjainen curses-käyttöliittymä, joka pohjautuu teksti- ja valintakenttiin, tarjoaa komentoriviä helpomman mahdollisuuden ajaa ohjelmaa. Molemmat käyttöliittymät ovat englanninkielisiä. 2.1 Toteutus- ja toimintaympäristö Koska järjestelmä on suunniteltu nimenomaan Tietojenkäsittelytieteen laitoksella toimivan HIIT-perustutkimusyksikön käyttöön, se on suunniteltu toimimaan laitoksen Linuxkäyttöympäristössä. Ohjelmassa on kiinnitetty erityistä huomiota ohjelman etäkäyttöön, esim. SSH:n kautta, suunnittelemalla tekstipohjainen käyttöliittymä, joka tukee mahdollisimman hyvin tällaista käyttöä.
4 2.2 Ohjelmointikielet Kuva 1: Toteutettu järjestelmä. Populous ohjelmoidaan Tietojenkäsittelytieteen laitoksen Linux-ympäristössä C++- kielellä käyttäen sen standardikirjastoja. Tekstikäyttöliittymässä hyödynnetään C-kielistä ncurseskirjastoa. Ohjelman testauksessa käytetyt tulosteiden oikeellisuuden tarkistusskriptit toteutettiin Perlillä. 2.3 Rajaukset Populousin on toimittava yhdessä valmiina olevien komponenttien, simcon ja markertoolin, kanssa. Kaikkien syöte- ja tulostetiedostojen on oltava yhteensopivia em. ohjelmien kanssa.
3 Arkkitehtuurikuvaus 5 Tässä kappaleessa kuvataan toteutetun järjestelmän arkkitehtuuri. Järjestelmän komponentit ja niiden väliset suhteet on selvitetään omissa aliluvuissaan. Arkkitehtuurikaavio on esitetty kuvassa 2. Kuva 2: Toteutetun järjestelmän arkkitehtuuri. 3.1 Komponenttien väliset suhteet Ohjelmisto jakautuu itsenäisiin komponentteihin, joiden välillä on minimaaliset rajapinnat. Komponenttien välinen liikenne koostuu rajapintakutsuista, ja ainoastaan Ydin-komponentti on yhteydessä useampaan kuin yhteen muuhun komponenttiin. Ohjelman rakenne on erittäin modulaarinen ja helposti päivitettävä. Ohjelmalla on kiinnitetty suoritusjärjestys, jota ei varioida missään tapauksessa. Ohjelman erilaiset suoritusmoodit saadaan jättämällä joitain vaiheita pois, esim. komentoriviltä ohjelmaa ajettaessa jätetään käyttöliittymäkomponenttikutsu pois ja simulaatiossa on mahdollista ohittaa Pedigree- komponentti kokonaan. Ohjelman komponenttien kutsujärjestys on: main()-metodi -> Ncurses -> Ydin -> Pedigree -> Ydin -> Marker -> Ydin -> Ncurses. Kun ohjelma käynnistetään komentoriviltä, main-metodi parsii parametrit, tarkistaa niiden eheyden sekä luo ja käynnistää Core-luokan. Core luo tuloshakemiston, siirtyy sinne, ajaa simulaation kutsumalla Pedigree- ja Marker-komponentteja peräkkäin ja lopuksi
poistaa turhat tiedostot ja vapauttaa resurssit. Ncursesin tapauksessa main-metodi luo ja käynnistää ncurses-käyttöliittymäkomponentin, jossa annetaan parametrit ja käynnistetään Core-luokan RunSimulation()-metodi näillä parametreilla. Ohjelman algoritmisesta luonteesta huolimatta interaktiivisuuteen (ts. kesken suorituksen päivitetään käyttäjällä seurantatietoja) panostettiin suunnittelemalla callback- järjestelmä, jossa suorituksen aikana tietyissä pisteissä kutsutaan kutsuvaa osaa (käyttöliittymä), jolloin se saa mahdollisuuden päivittää käyttöliittymää. Säikeitä ei käytetä. Ohjelmisto jakautuu kolmeen kerrokseen: suorittava kerros (Pedigree, Marker), kontrollikerros (Ydin) ja käyttöliittymäkerros (tekstikäyttöliittymä, komentorivikäyttöliittymä). Lisäksi suorittavaan kerrokseen liittyy kaksi ulkoista suorittavaa komponenttia, jotka ovat vanhasta järjestelmästä sellaisinaan otettuja valmiita binääreitä (simco ja markertool). 6 3.1.1 Suorittava kerros Suorittavassa kerroksessa olevat komponentit Pedigree ja Marker tekevät varsinaisen simulaation eri osavaiheet. Pedigree-komponentti luo sukupuun ja siihen yleensä liitettävät kromosomitiedot, ja Marker luo niiden ja Marker-komponentin sisällä luotujen markkerien pohjalta simulaation lopullisen tuloksen. Marker-komponentti tarvitsee aina syötteekseen Pedigree-komponentin tuloksen, eli nämä komponentit ajetaan aina peräkkäin tai otetaan Pedigree-tuotteet valmiina tiedostoista. Marker ei varsinaisesti itse tee suorittavaa työtä, vaan kutsuu ulkoisia ohjelmia, simcoa ja markertoolia. Kerroksen komponentit saavat suorittamiseen tarvittavat tiedot parametrinaan. Komponentit tiedottavat työn etenemisestä niitä kutsunutta Ydin-komponenttia callback-rajapinnan kautta. 3.1.2 Kontrollikerros Kontrollikerros hallinnoi yhden työn suorituksen. Se ajaa suorittavan kerroksen komponentit järjestyksessä Pedigree, Marker; välittää tietoa työn etenemisestä ydintä kutsuneelle komponentille callback-rajapinnan kautta, ja työn päätyttyä huolehtii, että ylimääräiset työn ohessa luodut väliaikaistiedostot tuhotaan. Ydin saa parametrinaan kaikki työn suorittamiseen tarvittavat arvot, ja tiedon siitä minkä tyyppistä työtä ollaan suorittamassa: generoidaan ainoastaan sukupuu halutuin sukupolvin ilman kromosomeja (#1), generoidaa sukupuut ja siihen kromosomit (#2), suoritetaan simulaatio kokonaisuudessaan (#3) tai suoritetaan ainoastaan Marker parametrina annetulla sukupuulla ja kromosomidatalla (#4). Kaikissa tapauksissa on mahdollista iteroida simulaatioita ja useimmissa tapauksissa laajentaa sitä esim. alipopulaatioilla. Yksinkertaisimmassa tapauksessa #1 suoritetaan ainoastaan Pedigree, ja tästäkin ainoastaan ensimmäinen puoli. Tuloksena saadaan pelkkä sukupuu ilman kromosomitietoja. Tapaus #2:ssa suoritetaan Pedigree kokonaisuudessaan. Tulokseksi saadaan sukupuu ja kromosomitiedot.
Yleisimmässä tapauksessa #3 suoritetaan sekä Pedigree että Marker kertaalleen alusta loppuun. Tulokseksi saadaan markertool-ohjelman tuloste. Välituloksien säilytys määritellään parametreissa. Tapaus #4:ssä suoritetaan ainoastaan Marker-komponentti. Tällöin Pedigree-komponentin generoimat sukupuu- ja kromosomitiedostot annetaan parametrina, jolloin Pedigree-vaihe voidaan ohittaa. Myös iterointi on mahdolista, jolloin Marker suoritetaan samoilla parametreilla haluttu määrä kertoja samoilla sukupuutiedostoilla, säilyttäen jokaisen ajokerran tulokset omassa tiedostossaan. Kontrollikerroksen muodostavaan Ydin-komponenttiin on sijoiteltu kaikki ohjelman osat, jotka eivät erityisesti ole suorittavaa kerrosta tai käyttöliittymää. Näitä ovat parametri-, log- ja sighandlerluokka sekä main, enum-määrittelyluokka ja istatuscallback-rajapintaluokka. 7 3.1.3 Käyttöliittymäkerros Ohjelmaan on rakennettu kaksi käyttöliittymää: teksti- ja komentorivikäyttöliittymä. Komentorivikäyttöliittymä ei ole interaktiivinen ja on tarkoitettu ohjelman tehokkaaseen käyttöön ja laajentamiseen. Tekstikäyttöliittymä on rakennettu ohjelman pääasialliseksi käyttöliittymäksi. Tekstikäyttöliittymä koristelee komentorivikäyttöliittymän parametrien annon syöttökentillä, arvojen virheentarkistuksilla ja simuloinnin tekstuaalisella seurannalla. Käyttöliittymä ei ole täysin interaktiivinen simuloinnin suorituksen aikana, jolloin käyttäjälle näytetään seurantaruutu tilatietoineen. Ajon voi terminoida control-c:llä, mikä sammuttaa koko ohjelman siististi, mutta ei takaa tulostietojen säilyvyyttä. 3.2 Luokkien väliset suhteet Tässä luvussa kuvataan luokkien välisiä suhteita. Luokkakaaviossa esitetään kaikki toteutettavan järjestelmän luokat. Lisäksi kuvataan luokkien välistä verkkokommunikaatiota ja palvelupyyntöjä sekä viestien koodausta tarkemmin. 3.2.1 Luokkakaavio Koko järjestelmän luokkakaavio on esitetty kuvassa 3. Luokkakaaviossa ovat ainoastaan järjestelmän luokat, eli siitä puuttuvat globaalit main- ja sig_handler-funktiot ja globaali muuttuja process_state. Nämä kuuluvat loogisesti Ydin-komponenttiin, ja main-funktio voi kutsua joko Core- tai CursesUI-luokkaa. 3.3 Ydin-komponentti
8 Kuva 3: Toteutetun järjestelmän luokkakaavio Ydin on koko ohjelman toimintaa koordinoiva ja ohjaava komponentti. Ydin saa viestejä joko suoraan käyttäjältä (komentorivikäyttöliittymä) tai tekstipohjaiselta käyttöliittymältä. Ydin toimii välikerroksena käyttäjän ja simulaation suorittavien komponenttien välissä. Ydin ohjaa Pedigree- ja Marker-komponentin käyttöä, sekä välittää tietoa käyttäjälle käyttöliittymän kautta ja poistaa väliaikaisia tiedostoja ja ylläpitää tiedon välitystä. Ydin-komponenttiin on myös sisällytetty globaalit luokat Parameters ja Log, sekä kaikki kaikki globaalit funktiot ja muuttujat. Perusteena tälle on, että Ydin-komponentin katsotaan olevan keskeisin osa sovellusta. Ytimen luokat ja näiden väliset suhteet on esitetty kuvassa 4.
9 Kuva 4: Ydin-komponentin luokat. 3.3.1 Rajapinta Ydin tarjoaa palveluita tekstikäyttöliittymälle. Ydin sisältää simulaation ajojen hallinnan, koordinoinnin, lokin, virhetilanteiden hallinnan ja delegoinnin ohjelman sisällä sekä tulosten ja tulosteiden ohjaamisen käyttäjälle. Ytimen on tarkoitus piilottaa mahdollisim-
man paljon populaatiosimulaatioteknisistä asioista ja tarjota keskitetysti esim. parametrien parseroinnin, validoinnin (Parameters-luokka) ja simulaatiokomponenttien kutsun (Core-luokka). Tyypillisessä simulaatiokäyttötapauksessa käyttäjä antaa käyttöliittymän kautta halutut parametrit. Käyttöliittymä syöttää parametrit Parameters-olioon, joka annetaan ytimelle. Parameters-luokka parsii syötteet ja tarkistaa niiden arvoalueet ja eheyden. Ydin määrittää parametrien pohjalta simulaatiotyön. Tämän takia ydin tarjoaa käyttöliittymille hyvin pelkistetyn rajapinnan, joka koostuu pääasiassa parametrien vastaanottamisesta. Näin käyttöliittymät voidaan erottaa simulaatiosta ja sen toteutuksesta mahdollisimman tehokkaasti. int RunSimulation(TSimType type, Parameters params) Luovutetaan parametrijoukko ytimelle suoritusta varten. Parametri type määrittelee minkä tyyppinen simulaatio halutaan suorittaa. Määritellään rajapinnassa ICore. int main(int argc, char *argv[]) Ohjelmiston globaali pääfunktio. Tätä kutsutaan ensimmäiseksi kun ohjelma käynnistetään komentoriviltä. Tunnistaa parametreista halutaanko ohjelmaa ajaa palvelimena, tekstikäyttöliittymänä vai suoraan suorittaa simulaatio, ja käynnistää sen mukaisen komponentin, josta ohjelman suoritus varsinaisesti alkaa. void Update(TStatus status) Callback-metodi, jolla Pedigree- ja Marker-komponentit lähettävät tietoa edistymisestään. Määritellään rajapinnassa IStatusCallback. 10 3.3.2 Enumeraattorit TStatus Kuvaa simulaatiotyön tilaa. Mahdolliset arvot ovat: INIT = työtä ei vielä aloitettu, TREE = yksi sukupuun sukupolvi luotu kromosomeineen, PEDIGREE = kaikki sukupolvet luotu, MARKER = simco ajettu (markkerit generoitu), SAMPLE = markertool ajettu (otos otettu), READY = simco ja markertool ajettu kokonaisuudessa (kaikki mahdolliset iteraatiot), työ valmis ERROR = työn suorituksessa on tapahtunut virhe TProcessState Kuvaa prosessin tilaa. Mahdolliset arvot ovat: INIT = alkutila, NCURSES = tekstikäyttöliittymä, CORE = prosessi suorittaa simulaatiota TSimType Kuvaa simulaation tyyppiä. Mahdolliset arvot ovat:
11 NONE = simulaatiota ei suoriteta, FULL = täysi ajo alusta loppuun, TREE = luodaan pelkkä sukupuu Pedigree-komponentissa, PEDIGREE = ajetaan vain Pedigree-komponentti, PROCESS = suoritetaan pelkkä Marker-komponentti valmiille sukupuulle 3.3.3 ICore-rajapinta ICore on ydinkomponentin kutsurajapinta. Metodit public int RunSimulation(TSimType type, Parameters ¶ms) Metodilla käynnistetään simulaation suoritus. Onnistuneen suorituksen yhteydessä paluuarvo on 0, virhetilanteessa -1. Tieto varsinaisen virheen aiheuttajasta kirjataan lokitiedostoon. 3.3.4 IStatusCallback-rajapinta IStatusCallback luo rajapinnan, jolla välitetään tietoa työn edistymisestä kutsuneelle taholle. Metodit public virtual void Update(TStatus status) Callback-metodilla, jolla kontrolli voidaan siirtää hetkeksi työn suorituksesta hierarkiassa ylemmälle kerrokselle. Parametri status on enumeraattorityyppiä TStatus. 3.3.5 Core-luokka Core on Ydin-komponentin pääluokka. Core hoitaa töiden koordinoinnin ja jakaa annettujen parametrien mukaan tehtävät Pedigree- ja Marker- komponenteille. Metodit public int RunSimulation(TSimType type, Parameters ¶ms) Ajaa simulaation. Saa syötteenään valmiin ja tarkistetun Parameters-olion. Parametri type on enumeraattorityyppiä TSimType ja määrittelee simulaation tyypin. 3.3.6 CoreFactory-luokka CoreFactory on tehdasolio, jolla luodaan ICore-tyyppisiä olioita.
12 Metodit public static ICore* Construct() Luo ICore-tyyppisen olion. Varsinaisen toteuttavan luokan valinta tehdään metodin sisällä. Virhetilanteessa palautetun osoittimen arvo on 0. 3.3.7 Parameters-luokka Parameters-luokka kapseloi ohjelman parametrit. Se luodaan ja täytetään käyttöliittymätasolla ja annetaan ytimelle simulaation suoritusta varten. Komentoriviltä käytettäessä käyttöliittymätaso on ydin itse, jolloin se kontruoidaan siellä. Se ei varsinaisesti kuulu Ydin-komponenttiin, vaan kulkee suorituksen mukana komponentista toiseen. Parameters-olion voi konstruoida joko käyttämällä kontruktoria, joka saa syötteenään char-merkkijonotaulukossa kaikki parametrit (komentoriviltä ja palvelimesta) tai attribuutit voi täyttää itse (tekstikäyttöliittymä). Luonnin jälkeen tulee kutsua Check-metodia, joka tarkistaa parametri-olion parametrit. Parameters-oliossa kaikilla kentillä on asetettuna arvo, jota käytetään. Oletusarvoja käytettäessä on Parameters-oliota luovan metodin tehtävä asettaa nämä arvot oikein. Metodit public int Check(TSimType type) Tarkistaa parametrina saamansa tyypin perusteella siihen liittyvien parametrien arvojen oikeellisuuden ja funktionaalisen eheyden. Metodin paluuarvo on onnistuneella suorituksella 0 ja virhetilanteessa -1. Virhetilanteen varsinainen aiheuttaja kirjataan lokitiedostoon. Metodin parametri type on enumeraattorityyppiä TSimType. public int ParseFile(char *filename) Käytetään lataamaan parametrien arvot tiedostosta. Lukee annetun tiedoston sisällön ja asettaa ParseString()-metodin avulla olion kenttien arvot sen mukaisiksi. public int ParseString(char *str) Käytetään asettamaan parametrit yhdellä komentorivimuotoisella merkkijonolla. Pilkkoo annettun merkkijonon ParseArgv()-metodin ymmärtämään muotoon ja syöttää sen tälle. public int ParseArgv(int argc, char **argv) Asettaa olion kentät ohjelmiston komentoriviparametrien perusteella. Saa parametrikseen samat tiedot kuin main()-funktio, mutta ilman ensimmäistä, ohjelman ajotiedoston sisältävää kenttää. Konstruktori pyrkii löytämään merkkijonoista kaikki mahdolliset määritellyt parametrit ja asettamaan arvonsa sen mukaisesti. Virhetilanteissa osa arvoista jää asettamatta, ja oliota luovan onkin kutsuttava Check-metodia
13 Koodi Selitys -1 Määrittelemätön virhe -2 Arvoaluevirhe jossakin parametrissa -3 Kaikkia vaadittuja parametreja ei asetettu -4 Ristiriita parametreissa Taulukko 1: Parameters::Check()-virhekoodit vielä tämän jälkeen varmistaakseen luonnin onnistumisen ja että kaikki tarvittavat parametrit oli määritelty. public int SetSubPopulationMigrations(char *str) Parametrina annettavan 0-terminoidun merkkijonon on oltava samassa muodossa kuin alipopulaatioiden migraatiotodennäköisyydet määritellään ohjelman parametreissa. Metodi parsii tämän merkkijonon ja asettaa sen olion kentän subpopulation- Migrations arvoksi. Palauttaa onnistuessaan arvon 0, virhetilanteessa -1. public int ToFile(char *filename) Tallentaa olion tiedot tiedostoon, jonka nimi annetaan parametrina. Tiedoston sisältö tallennetaan muotoon, jonka ParseFile()-metodi osaa lukea. public int ToLog() Tulostaa olion kaikki parametrit logiin debug-määreellä. public Parameters() Konstruktori asettaa kaikki kentät 0-arvoiksi. public int Clear() Asettaa kaikki arvot vakioiksi. public int GetSizesFromChrom() Laskee unixin wc:n avulla kromosomitiedostoista sukupolven koon. private bool CheckSubPopulations() Tarkistaa alipopulaatioiden eheyden. Katsoo että alipopulaatioiden määrä täsmää ja että alipopulaatioiden migraatiotaulukko on ehyt. private bool CheckFileExists(std::string file) Tarkistaa että tiedosto on olemassa. Yrittää avata sitä ja katsoo onnistuiko avaus. private bool CheckSaveGenerations() Tarkistaa että savegenerations-parametrissa ei ole annettu liian suuria tai pieniä sukupolvia. Attribuutit Parameters-luokan attribuutit on listattu taulukossa 2. Parametrit tarkistetaan Check-metdissa simulaatiomoodin mukaan. Moodit: 1 = TREE
14 2 = PEDIGREE 3 = FULL 4 = PROCESS (=MARKER) Kustakin parametrista on mainittu, tarkistetaanko se tietyssä moodissa. Vain yhden moodin parametrit tarkistetaan, muista ei välitetä. 3.3.8 Log-luokka Log on ohjelmiston lokitiedostoon kirjoittamiseen tarkoitettu luokka. Jokaisella lokirivillä on rivin tyyppi, jotka ovat vakavimmasta vähiten vakavaan Critical, Error, Info ja Debug, sekä vapaamuotoinen, mutta yksirivinen tekstiselitys. Lokitiedosto kirjoitetaan hakemistoon, josta ohjelmisto on suoritettu. Log on Singleton-tyyppinen olio, josta luodaan tasan yksi ilmentymä prosessia kohti. Metodit public static Log& GetInstance(bool debug = false) Palauttaa Log-olion. Luo tarvittaessa uuden Log-olion. Debug-tilan voi asettaa päälle ainoastaan ensimmäisellä kutsukerralla, eikä sitä voi kesken ohjelman suorituksen asettaa pois päältä. public int LogCritical(string msg) Lisää lokitiedostoon parametrina saadun viestin kriittinen-statuksella. public int LogError(string msg) Lisää lokitiedostoon parametrina saadun viestin virhe-statuksella. public int LogInfo(string msg) Lisää lokitiedostoon parametrina saadun viestin info-statuksella. public int LogDebug(string msg) Lisää lokitiedostoon parametrina saadun viestin debug-statuksella. Rivi lisätään vain mikäli attribuutti debug on asetettu arvoon true. public int WriteLog(string level, string msg) Lisää lokitiedoston parametrina saadun viestin annetulla statuksella. Attribuutit private Log _instance Sisäinen olio, jonka kaikki luokkaa käyttävät jakavat. Tuhotaan vasta ohjelman suorituksen päättyessä. private bool _debug Määrittelee kirjoitetaanko debug-rivit tiedostoon.
15 Tyyppi Muuttuja (1,2,3,4 = Sallittu arvoalue Tarkistushuomioita pakollinen) bool saveparameters string paramfile string resultdir int founders (1234) 2-n int parentgensize 2-n int lastgensize (123) 2-n int generations (123) 1-n int iterations 1-n Vakio-arvo 1. bool pedigreeonce Ei vaikutusta, jos iterations 1 TSimType simulationmode (1234) TREE, PE- DIGREE, FULL, MAR- KER Määrittää, mitä parametreja tarkistetaan. Turhat parametrit jätetään huomioimatta. string treefile Pakollinen vain jos parentsinresult string pedigreefile (34) string parentpedigreefile Pakollinen vain jos parentsinresult vector<int> savegenerations 1-generations int subpops 1-n Vakio-arvo 1. Tulee antaa kaikki 3 subpop-parametria. vector<int> subpopsizes 2-founders Määrä täsmättävä edelliseen. double[][] subpopmigrations 0.0-1.0, sum=1.0 int chromlength (234) 2-n string strfile Tarkistetaan olemassaolo. double snprate (34) 0.0-1.0 double recombrate (34) 0.0-1.0 int effectivepopsize 2-n (34) double diseasemutfreq (34) 0.0-1.0 double minminorallelefreq 0.0-1.0 (34) bool markermap int markers (34) 1-n int sampletype (34) 1-4 int samplesize (34) 0-n double prevalence (34) 0.0-1.0 double penetrance (34) 0.0-1.0 Sekä korkeus että leveys oltava subpops. Joka rivin summa 1.0. Ei korjata taulukkoa, jos siinä virheitä. bool report bool parentsinresult bool allowsiblings Huomioimatta jos ei parents ei asetettu. string resultfileprefix Sisäinen muuttuja. Taulukko 2: Parameters muuttujat
16 private string _logfile Lokitiedosto, johon lokirivit kirjoitetaan. 3.3.9 Globaalit määrittelyt Globaalit funktiot ja muuttujat eivät kuulu mihinkään luokkaan, vaan näkyvät kaikille niitä käyttäville sellaisenaan. Funktiot int main(char* args[]) Main-metodi. Metodi ajetaan ensimmäisenä kun ohjelma käynnistetään komentoriviltä. Metodissa tehdään yksinkertaistettu parametrien tarkistus, jonka pohjalta se joko käynnistää tekstikäyttöliittymän (ei parametreja) tai aloittaa simulaation suorituksen. Lopullinen simulaation parametrien tarkistus tehdään Parameters-luokan sisäisessä metodissa Check. Parametrien konstruointiin tarjotaan Parameters-luokan konstruktoria. void sighandler(int sig) Signaalinkäsittelijä, jossa määritellään mitä tehdään kun prosessi saa UNIX- signaalin. Käyttäytyminen riippuu suurelta osin globaalista muuttujasta process_state. Muuttujat TProcessState process_state Muuttujalla määritellään missä tilassa ja minkä tyyppinen senhetkinen prosessi on. Tällä kontrolloidaan lähinnä signaalinkäsittelijän toimintaa, koska esim. simulaation ja tekstikäyttöliittymän yhteydessä samakin signaali pitää voida tulkita eri tavalla. Muuttuja on enumeraattori-tyyppiä TProcessState. 3.4 Pedigree-komponentti Pedigree korvaa ja yhdistää vanhan järjestelmän genpedin ja chromin. Pedigree tuottaa halutut sukupuutiedostot (iteration_pedigree_generation) ja kromosomitiedostot sukupolvittain (iteration_chrom_generation). Vakiona mitään pedigree-komponentin tulosteita ei säilytetä simulaation ajon jälkeen, eli sitten kun markertool on käynyt ne läpi. Tulosteiden poistoa ei toteuteta Pedigreehen vaan se tapahtuu muualla. Option takana on mahdollisuus säilyttää käytetyt sukupuu- ja kromosomitiedostot, sekä mahdollisuus generoida ja säilyttää ylimääräisiä sukupolvitiedostoja. Pedigree-komponentin luokat ja näiden väliset suhteet on esitetty kuvassa 5.
17 Kuva 5: Pedigree-komponentin luokat. 3.4.1 Rajapinta Pedigree-komponentin rajapinta tarjoaa yhden metodin sukupuun ja kromosomien luomista varten. Se mitä kullakin suorituskerralla luodaan määräytyy parametreista. int GeneratePedigree(TPedigreeType type, Parameters& params) Generoidaan parametreissä määritellyt asiat. Ensimmäisellä parametrilla voidaan jättää kromosomit generoimatta. TPedigreeType on enumeraattori, joka kertoo suorituksen tyypin.
18 3.4.2 Enumeraattorit TPedigreeType Kuvaa Pedigree-komponentin suorituksen tyypin. Mahdolliset arvot ovat: FULL = täysi ajo, TREE = vain sukupuu 3.4.3 IPedigree-rajapinta IPedigree on Pedigree-luokan rajapinta ytimelle. Metodit virtual int GeneratePedigree(TPedigreeType, Parameters&) Core-luokalle näkyvä rajapintametodi. Toteutus aliluokassa. Palauttaa onnistuessaan arvon 0, virhetilanteessa -1. 3.4.4 Pedigree-luokka Pedigree luo sukupuut ja vastaa niiden tallennuksesta. Metodit public int GeneratePedigree(TPedigreeType, Parameters&) GeneratePedigree on implementaatio rajapintaluokan metodille. Metodi ottaa parametreikseen TPedigreeType-enumin ja Parameters-luokan, jotka kertovat missä moodissa ohjelmaa ajetaan ja sisältävät tarvittavat parametrit ajoa varten. Metodi luo luokan sisäiset oliot, FamilyTree ja RecombTree, joissa tapahtuu varsinainen sukupuun ja kromosomien prosessointi. Töiden välillä metodi palauttaa tilatietoa IStatusCallback-luokan Update()-metodin kautta. Attribuutit private IStatusCallback *_callback Callback-rajapinnan toteuttava olio tilan päivittämistä varten. 3.4.5 PedigreeFactory-luokka PedigreeFactory on staattinen tehdasluokka, joka luo instanssin Pedigree- luokasta ja palauttaa osoittimen siihen. Metodit
public static IPedigree* Construct(IStatusCallback*) Metodi luo Pedigree-instanssin ja palauttaa sen osoittimen kutsujalle. Palautettu oli on dynaamisesti luotu ja kutsujan on huolehdittava sen tuhoamisesta delete:llä. 19 3.4.6 FamilyTree-luokka FamilyTree on sukupuun hallintaluokka. Luokka kontrolloi yhtä tai useampaa alipopulaatioluokkaa, niiden yksilömääriä, sukupolvien tulostusta ja yksilöiden liikkumista alipopulaatioiden välillä. Metodit public FamilyTree(Parameters&) Konstruktori, jolla luokan olio on syytä luoda. Parametrina annettavalla Parametersoliolla on oltava puun ja rekombinaatioiden generointiin vaadittavat arvot oikeellisesti asetettuna. public int CreateAndPrintTree(IStatusCallback*, bool with_recomb) Luo sukupuun ja haluttaessa tekee siihen rekombinaatiot. Tallentaa tuloksen tiedostoihin sukupuu kerrallaan. Tallennettavat tiedot määritellään konstruktorille annetun Parameters-olion kautta. private void CreateMigrations() Hoitaa siirtolaisten liikennettä alipopulaatioiden välillä. private int OutputGeneration(int inmode, int generation, deque<individual>) Tulostaa viimeksi haetun sukupolven sukupuun, jonka järjestysnumero annetaan parametrissa generation (0 = ensimmäinen sukupolvi). Parametrilla inmode määritellään tulostuksen kohde; 1 = STDOUT, 2 = tiedosto. Tulostus järjestetään yksilöiden tunnusten mukaan. private void InitCrossoverFrequencies() Alustaa tekijänvaihtotaajuudet. Logiikka kopioitu vanhasta ohjelmasta. private int OutputChromosomes(int inmode, int generation, deque<individual>) Tulostaa viimeksi haetun sukupolven kromosomit. Sukupolven järjestysnumero annetaan parametrissa generation (0 = ensimmäinen sukupolvi). Parametrilla inmode määritellään tulostuksen kohde; 1 = STDOUT, 2 = tiedosto. Tulostus järjestetään segmenttien alkupisteen mukaan. private double Mult(double n) Kertomafunktio. Toiminnallisuus suoraan aiemmasta ohjelmasta, sillä muutoksella, että ylivuotomahdollisuuden takia muuttujatyyppi vaihdettu isompaan. Attribuutit
20 private Parameters *theparam Simulaatioparametrit. private IStatusCallback *callback Callback-rajapinnan toteuttava olio tilatiedon päivitystä varten. private int cur_gen Käsittelyn alla oleva sukupolvi. private int cur_gen_size Käsittelyn alla olevan sukupolven koko. private double grfact Sukupolven kasvukerroin. private double[] crossover_probability Muutujanvaihdon todennäköisyystaulukko. private vector<double> gen_sizes Taulukko johon kaikkien sukupolvien yksilömäärät lasketaan. Käytetään doublea, pyöristysvirheen kasautumisen vähentämiseksi. private vector<subpopulation> s_pops Käsiteltävät alipopulaatiot. Jos alipopulaatioita ei käytetä, vektori sisältää vain yhden populaation. Yksilöiden ja kromosomien luonti tapahtuu alipopulaatioissa. private vector<segment> generations_chromosomes Apuvektori kromosomisegmenttien keräämistä ja tulostamista varten. 3.4.7 SubPopulation-luokka SubPopulation Metodit public SubPopulation(int size, int generations, double *cross_prob, double chr_length, bool with_recomb, int start_ge_index, int sub_pop_index) Konstruktori, jolla SubPopulation-olio luodaan. Saa parametreinä alkupopulaation koon, sukupolvien määrän, muuttujanvaihtotodennäköisyydet, kromosomipituuden, valinnan kromosomien luomisesta, sukupolven ensimmäisen id:n(tarvitaan alipopulaatioissa) ja alipopulaatioindeksin. public int CreateNextGeneration(int start, int nr_of_indv) Luo uuden sukupolven. Parametreina ensimmäinen id ja sukupolven yksilömäärä. public int HaldaneSites(double[] site) Luo kohdat jossa rekombinaatiota tapahtuu.
21 public void SortSites(double[] site, int sites) Edellisen apumetodi. Kopioitu suoraan aiemmasta ohjelmasta. private void InheritedChromosome(vector<Segment> new_chrom, int persid, int pid, int which) Luo perustajille kromosomit ja periyttää jälkeläisille vanhempien kromosomit lisäten rekombinaatiot. Parametreina segmenttivektori tallennusta varten, henkilön id, vanhemman id ja kokonaisluku, joka kertoo kummalta vanhemmalta ollaan perimässä. public int GetNextGeneration(deque<Individual>, int start, int nr_of_indv) Julkinen metodi, joka käyttää edellistä metodia ja kopioi edellisen sukupolven palautusvektoriin. Parametreinä myös alipopulaatiosukupolven ensimmäinen id ja luotavan sukupolven koko. public int CreateNextGenerationAndGetSize(int start, int nr_of_indv) Rinnasteinen edellämainitulle metodille, mutta ei kopioi vektoria. public void GetEmigrants(vector<double>&, vector<individual>&) Ottaa parametreinä siirtymistödennäköisyystaulukon ja yksilövektorin kopioimista varten. Arpoo siirtymistodennäköisyyksillä muualle siirtyvät yksilöt ja kopioi ne vektoriin. public void AddEmigrants(vector<Individual>) Lisää tähän alipopulaatioon muualta tulleet yksilöt. public void CreateFounders(int start, int total) Luo perustajasukupolven. Attribuutit public int founder_count Säilyttää alkupopulaation määrän. Lähinnä diagnostiikkamuuttuja. public bool is_recomb Määrittelee luodaanko kromosomien rekombinaatiot pelkän sukupuun lisäksi. public double chrom_length Kromosomin pituus. public int g_rations Simulaation sukupolvien määrä. public int cur_gen Nykyisen sukupolven 0-kantainen järjestysluku. public int cur_gen_size Nykyisen sukupolven yksilöiden lukumäärä.
22 public int n_par_men Vanhemman sukupolven miesten lukumäärä. public int n_par_women Vanhemman sukupolven naisten lukumäärä. public int n_men Nuoremman sukupolven miesten lukumäärä. public int n_women Nuoremman sukupolven naisten lukumäärä. public int population_index Tämän alipopulaation tunnus. public double[] crossover_probability Muuttujanvaihtotodennäköisyystaulukko. public deque<individual> current_gen Nykyisen sukupolven yksilöt. Kasvaa kahteen suuntaan. Miehet alkupäässä, naiset loppupäässä. public deque<individual> parent_gen Edellisen sukupolven yksilöt. Miehet alkupäässä, naiset loppupäässä. 3.4.8 Individual-luokka Individual on säiliöluokka yksilötiedolle. Luokka on SubPopulation- ja FamilyTree- luokkien apuluokka. Metodit public Individual() Oletuskonstruktori, joka luo tyhjän Individual-olion. public operator<(individual&) Vertailuoperaattori < (pienempi kuin -) Individual-olioiden kesken. Palautuu olioiden id-kentän vertailuksi. Attribuutit public int id Yksilön tunniste. public int father_id Yksilön isän tunniste.
23 public int mother_id Yksilön äidin tunniste. public int gender Yksilön sukupuoli; 0 = mies, 1 = nainen. public int children Yksilön lapsien lukumäärä. public int index_in_gen Yksilön järjestysnumero sukupolvessaan. public int sub_population Alipopulaatio, johon yksilö kuuluu. public vector<segment> mothers_segment Äidiltä saadun kromosomin segmentit. public vector<segment> fathers_segment Isältä saadun kromosomin segmentit. 3.4.9 Segment-luokka Segment on säiliöluokka kromosomidatalle. Jokainen Individual-olio sisältää kaksi Segmentvektoria. Segment kuvaa kahden rekombinaatiokohdan välistä dna-jaksoa. Metodit public Segment() Oletuskonstruktori, joka luo tyhjän Segment-olion. public operator<(segment&) Vertailuoperaattori < (pienempi kuin -) Segment-olioiden kesken. Palautuu segmenttien alkupisteiden vertailuksi. Attribuutit public double start_point Segmentin alkupiste. public int founder_id Tunniste perustajayksilölle, jolta segmentti on peräisin. public int person_id Segmentin kantajan tunnus.
24 3.5 Marker-komponentti Kuva 6: Marker-komponentin luokat. Marker on yhteinen rajapintakomponentti markertoolille ja simcolle. Marker toimii em. ohjelmien ajurina, joka virtaviivaistaa niiden käyttöä ytimelle ja mahdollistaa ohjelman laajennettavuuden. Marker ajaa molemmat em. ohjelmat oikeilla parametreilla. Marker-komponentin luokat ja näiden väliset suhteet on esitetty kuvassa 6. 3.5.1 Rajapinta Marker-komponentin rajapinta sisältää yhden metodin, jonka kautta käytetään simco- ja markertool-komponentteja. Yksityiskohdat sisältyvät parametreihin. int Process(TMarkerType type, Parameters params&) Ajetaan Simco ja Markertool halutuin parametrein. TMarkerTypellä on kaksi vaihtoehtoa: WPAR ja NORMAL, mikä määrittelee ajetaanko ohjelmaa ns. TRIO-asetuksella (ts. parentsinresult-optio määritelty)
25 3.5.2 Enumeraattorit TMarkerType Kuvaa Marker-komponentin suorituksen tyypin. Mahdolliset arvot ovat: MARKER_NORMAL = normaali ajo, MARKER_WPAR = vanhemmat mukana otoksessa 3.5.3 IMarker-rajapinta IMarker on Marker-luokan rajapinta ytimelle. Metodit public int Process(TMarkerType type, Parameters ¶ms) Core-luokalle näkyvä rajapintametodi. Toteutus aliluokassa. Onnistuessaan metodi palauttaa arvon 0, virhetilanteessa -1. 3.5.4 Marker-luokka Marker-luokka toimii rajapintana Ytimen ja Simcon sekä Markertoolin välillä. Sisältää vain yhden metodin. Metodit public int Process(TMarkerType type, Parameters ¶ms) Luokan ainoa metodi. TMarkerType-enumeraattori määrittelee ajotavan, Parametersluokka sisältää parametrit simcolle ja markertoolille. Ensin ajetaan Simco ja sen jälkeen Markertool, molemmat ajetaan aina. Metodi käynnistää ulkoiset ohjelmat uuteen prosessiin system():llä ja jää odottamaan paluuarvoa. Parametrit on validoitu jo ennen ulkoisten ohjelmien ajamista, mutta jos virhetilanne kuitenkin syntyy, palautetaan negatiivinen arvo. Onnistuessaan metodi palauttaa arvon 0. Töiden välillä metodi palauttaa tilatietoa IStatusCallback-luokan Update()-metodin kautta. Metodissa ensin rakennetaan parameters-oliosta simcolle parametristring, jonka jälkeen kasataan markertoolille ajostring. Markertool vaatii myös tiedostoparametreja, joita varten Ydin on valmiiksi tehnyt symboliset linkit ohjelman tuloshakemistoon (jossa ohjelman suoritus sijaitsee koko simulaation ajan). Attribuutit private IStatusCallback *_callback Säilöö callback-olion (simulaation käynnistäjän).
26 3.5.5 MarkerFactory-luokka MarkerFactory on staattinen tehdasluokka, joka luo instanssin Marker- luokasta ja palauttaa osoittimen siihen. Metodit public static IMarker* Construct() Metodi luo Marker-instanssin ja palauttaa sen osoittimen kutsujalle. 3.6 Tekstikäyttöliittymä-komponentti Kuva 7: Tekstikäyttöliittymäkomponentin luokat. Tekstikäyttöliittymä pohjautuu ncurses-kirjastoon. Käyttäjä syöttää parametrit käyttöliittymässä kenttiin, joista käyttöliittymä kokoaa Parameters-olion, joka annetaan ytimelle RunSimulation() rajapinnalle. Ydin tarjoaa tietoa simulaation etenimsestä käyttöliittymälle Update()-rajapinnan kautta. Simulaation tuloksia ei visualisoida, ainoastaan tallennetaan tulostiedostot. Kutakin käyttöliittymänäkymää varten on oma luokkansa, yhteensä kolme kappaletta: alkuvalikko, parametrien syöttö, simulaation seuranta. Valikkoa ei ole toteutettu ncursesin MENU-kirjastolla, vaan manuaalisesti. Parametrien syöttöikkuna käyttää FORM:ia, joka on jaetta kahteen sivuun. Osassa kenttiä on syötteen validointi käytössä. Tulosten seurantanäkymä on tehty ilman lisäkirjastoja. Jokainen kolmesta näkymästä on toteutettu kokoruudun WINDOW:na, joita päivitetään ruudulle käyttäjän edetessä käyttöliittymässä. CDK:ta tai PANEL-kirjastoa ei käytetä. Tekstikäyttöliittymäkomponentin luokat on esitetty kuvassa 7.
27 3.6.1 Rajapinta void Update(TStatus status) Metodi, jonka avulla päivitetään ruudulle tilatietoa ohjelman edistymisestä aina jonkin osasuorituksen valmistuttua. void StartUI() Käynnistää tekstikäyttöliittymän. 3.6.2 CursesUI-luokka CursesUI vastaa ncurses-käyttöliittymän alustamisesta, käynnistämisestä, käyttöliittymäikkunoiden ja ytimen luonnista sekä käyttöliittymän käynnistämisestä. StartUI() tekee em. asiat ja looppaa kolmea eri ikkunaa kunnes ohjelma sammutetaan, jolloin StartUI() loppuu, suoritus palaa main():iin ja terminoituu. CursesUI toteuttaa IStatusCallback-rajapinnan, jota kautta ytimeltä tulee tilatietoa simulaatiosta. CursesUI välittää Update()-metodissaan tilapäivitysviestin CursesUIResult-olion Update()-metodiin, jossa tilatiedot päivitetään käyttäjälle. Jokainen CursesUI-näkymäluokka sisältää Show()-metodin, joka aktivoi kyseisen ikkunan (päivittää näytölle) ja käynnistää kyseisen ikkunan input-handlerin. Show() pitää siten kontrollin itsellään kunnes käyttäjä vaihtaa toiseen ikkunaan, jolloin Show() palauttaa paaluarvonaan seuraavan ikkunan numeron. Tyhjä parameters-olio luodaan jo tässä vaiheessa ja osoitin siihen annetaan kullekin näkymäluokalle. Metodit void Update(TStatus status) Ytimelle tarjottava metodi, jolla voidaan päivittää käyttöliittymää laskennan kuluessa tarjoamalla käyttöliittymälle kontrolli pieneksi hetkeksi. Määritellään rajapinnassa IStatusCallback. Kutsuu CursesUIResult::Update():a. void StartUI() Käynnistää tekstikäyttöliittymän. Main-metodi kutsuu, jos ohjelmisto käynnistetään ilman komentoriviparametreja. Attribuutit private Parameters *params Parametri-osoitin. StartUI() luo tyhjän parametri-olion, jonka osoitin jaetaan kaikille CursesUI-luokille.
28 private int centerx, centery Kuvaruudun keskipisteet. private ICore *core Core-osoitin, jonka StartUI() luo CoreFactorylla. private CursesUIResult *ResultWindow ResultWindow-osoitin, muut näkymäluokat luodaan paikallisesti StartUI:ssa, joka on käytännössä ohjelman main-looppi. Kun StartUI() päättyy, ohjelma terminoidaan. 3.6.3 CursesUIMenu-luokka Menu on yksinkertainen alkuvalikko, joka on toteutettu ilman ncursesin MENU-kirjastoa manuaalisesti. Tästä näkymästä voi sammuttaa koko ohjelman tai siirtyä parametrien syöttöikkunaan. Metodit public int Show() Kuten muut Show()-metodit: päivittää tämän näkymän näytölle ja käynnistää tähän näkymään liittyvän näppäimistökäsittelijän. private void PrintMenu() Tulostaa ruudulle reunat, otsikon ja menun korostaen valitun kohdan. Valintaa ylläpidetään choice-muuttujalla manuaalisesti. Attribuutit private int menux, menuy Menun sijainti. private int choice Menun viimeisin valinta. private int highlight Menun valinta, merkkaa myös valinnan korostuksella. private std::vector<char*> choices Menu-valinnat: "New simulation"ja "Exit". private WINDOW menu Menu-näkymän ikkuna.
29 3.6.4 CursesUIParam-luokka Param-luokka on suurin ncurses-luokka, ja sisältää paljon ncursesin FORM:iin liittyvää määrittelyä. Luokka kapseloi ikkunan, joka koostuu täysin yhdestä ncurses-formista, joka on jaettu kahteen sivuun. Kenttiä on 32 plus jokaiselle kentälle staattinen (O_ACTIVE == false) selitekenttä. Lisäksi BACK ja START napit on toteutettu kenttinä, joita ei voi muokata. Luokasta löytyy neljä suurta koodikeskittymää: FORMin luonti, input-looppi, parametrien keruu kentistä ja parameters-olion luonti, parameters-olion kenttien sijoittaminen lomakkeen kenttiin. Kaksi ensimmäistä sisältää runsaasti ncursesin vaatimaa yksinkertaista, mutta runsasta määrittelykoodia. Metodit public int Show() Päivittää ikkunan ruudulle ja pyörittää input-handleria, joka on yksi iso getch-pohjainen switch-lauseke. Kentissä liikkuminen on kovakoodattu käsin jokaista napinpainallusta myöten. Nuolinäppäimillä liikutaan kentissä, Page up ja down vaihtavat sivua, tab vierittää kentän mahdollisia vaihtoehtoisia arvoja ja enterillä voidaan aktivoida START ja BACK nappulat. private void FillParamsFromFile(std::string filename) Käyttää Parameters::FromFile()-metodia parsiakseen parametri-olion tiedostosta, jonka jälkeen kutsuu FillParams()-metodia, joka syöttää olion parametrit kenttiin. private void FillParams() Syöttää parameters-olion tiedot kenttiin. private void ConstructParameters() Sijoittaa jokaisen kentän tiedon valmiiksi luodun parameters-olion julkisiin kenttiin. Show()-metodi kutsuu kun käyttäjä on hyväksynyt parametrit START-napilla. private void Trim(std::string buffer) Poistaa parametrin stringistä alusta ja lopusta tyhjät merkit (space ja tab). private void CheckFileExists(std::string file) Tarkistaa onko annettu tiedosto olemassa. Yrittää avata tiedostoa ja tarkistaa onnistuiko avaus. private void PrintTitle() Tulostaa ruudulle reunat ja otsikon. Attribuutit private WINDOW *param Näkymän kokoruudun ncurses-ikkuna.
30 private FIELD *field[67] Ncursesin FIELD-taulukko, joka sisältää kaikki formin kentät. Päättyy nulliin. private FORM *form Itse lomake. private char* yesno[3] Sisältää "yes"/"no"valintakenttien valinnat. private char* sampletype[5] Sisältää sample-type kentän vaihtoehdot: random, affected, case+random, case+affected private char* simulationmode[5] Simulaatiomoodi-kentän vaihtoehdot: tree, pedigree, full, process. private int fields Kenttien lukumäärä. private int choice Nykyinen valinta, ts. mikä kenttä on aktiivisena. private int BACK, START BACK ja START nappuloiden (kenttien) numerot FIELD-taulukossa. private int NEWPAGE Sivunvaihtokenttä. Formi on jaettu kahteen sivuun, sivunvaihto määritellään ncursesissa alkamaan tietystä kentästä. Tässä tapauksessa CHROMLENGTH-kenttä. private Parameters *params Parametri-osoitin, luodaan CursesUI:ssa. 3.6.5 CursesUIResult-luokka CursesUIResult-luokka kapseloi simulaation seurantaruudun. Ruutu käynnistetään Paramruudulta. Luokka käynnistää simulaation ja päivittää ruudulle simulaation seurantatietoa. Lopuksi odotetaan käyttäjän vahvistusta simulaation loppumiselle ja palataan alkuvalikkoon. Luokan päätehtävä on reagoida Update-viesteihin, jotka päivittävät simulaation kulkua. Normaalisti tilatiedot kirjoitetaan allekkain. Iteraatioiden tapauksessa jokaisen iteraation kulku näytetään kerrallaan samalla alueella, peräkkäisten iteraatioiden tilatietoja ei näe, ainoastaan viimeisimmän. Markeria iteroitaessa näytetään samoin missä iteraatiossa simulaatio on menossa. Metodit public int Show() Päivittää näkymän ruudulle, kirjoittaa osan tilatiedoista ruudulle ja käynnistää simulaation, jonka jälkeen kirjoitetaan tuloshakemisto ja poistutaan Result-luokasta.