Simulerad effektivisering av genotypdataanalys genom

TVE 16 027 maj
Examensarbete 15 hp
Juni 2016
Simulerad effektivisering av
genotypdataanalys genom poolade
data
Simon Strömstedt Hallberg
Jonas Giek
Abstract
Simulated optimization of genotype data analysis by
pooling data
Simon Strömstedt Hallberg, Jonas Giek
Teknisk- naturvetenskaplig fakultet
UTH-enheten
Besöksadress:
Ångströmlaboratoriet
Lägerhyddsvägen 1
Hus 4, Plan 0
Postadress:
Box 536
751 21 Uppsala
Målet med projektet är att undersöka om
det går att effektivisera hur man
undersöker människors gener. Detta görs
genom att skapa ett program i Java.
Resultatet är ett program som sorterar
genotypdata från 1000 Genomes Project
och utvärderar nyttan av att undersöka
genotyper från flera individer
samtidigt.
Telefon:
018 – 471 30 03
Telefax:
018 – 471 30 00
Hemsida:
http://www.teknat.uu.se/student
Handledare: Carl Nettelblad
Ämnesgranskare: Mia Sterby
Examinator: Martin Sjödin
ISSN: 1401-5757, TVE 16 027 maj
Innehåll
1 Introduktion
1.1 Bakgrund . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Motivering och målbeskrivning . . . . . . . . . . . . . . . . .
2 Metod
2.1 Utförande . . . . . . .
2.1.1 ReadVCF . . .
2.1.2 RandomGroups
2.1.3 Poolning . . . .
2.2 Verktyg . . . . . . . .
2.2.1 MATLAB . . .
2.2.2 Java . . . . . .
2.2.3 HTSJDK . . .
2.2.4 Eclipse . . . . .
2.2.5 GitHub . . . .
2.2.6 Maven . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
5
6
6
6
7
7
9
9
9
9
9
10
10
3 Resultat
11
3.1 Andel entydigt bestämda individer . . . . . . . . . . . . . . . 11
3.2 Minor Allele Frequency (MAF) . . . . . . . . . . . . . . . . . 13
4 Diskussion
15
4.1 Utvärdering . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2 Felkällor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5 Slutsatser
5.1 Upplevelse av verktyg .
5.1.1 Överblick . . .
5.1.2 GitHub . . . .
5.1.3 Maven . . . . .
5.1.4 HTSJDK . . .
5.2 Utveckling . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
16
16
16
17
17
17
6 Referenser
18
Appendices
19
3
A ReadVCF
19
B RandomGroups
21
4
Populärvetenskaplig sammanfattning av projektet
Grundtanken med detta projekt är att det borde gå att effektivisera hur
man analyserar egenskaper hos gener bland olika människor. Det bygger på
att undersöka flera människors gener samtidigt i stället för var och en för
sig, vilket sänker kostnaden. Nackdelen med detta är dock att en del av
resultaten inte går att spåra till rätt individer. Därför krävs en undersökning
för att avgöra hur stor del av resultaten som blir entydiga och se om det är en
tillräckligt stor del i förhållande till den sänkta kostnaden. För att inte slösa
på resurser innan det går att fastställa om det faktiskt är en hållbar process
undersöks detta genom simuleringar i Java med Eclipse som utvecklingsmiljö.
1
1.1
Introduktion
Bakgrund
1000 Genomes Project är ett projekt som pågick mellan 2008 och 2015 där
man skapade den största offentliga katalogen för mänsklig variation och genotypdata. Dessa data finns tillgängliga för allmänheten i form av VCF-filer
(Variant Call Format) och används i många forskningsprojekt. Ett sätt att
studera gener är med hjälp av microarrayer som fungerar som en platta med
många små element som vardera representerar en position där det finns olika
varianter. I dessa element skapas en reaktion som ger utslag på en av varianterna, vilket ger information om huruvida genen finns eller inte. Metoden är
vida använd idag och förhållandevis billig, men det är fortfarande kostsamt
att testa stora populationer [1].
1.2
Motivering och målbeskrivning
Processen som beskrivs i bakgrunden kan göras effektivare genom att poola
data från flera individer i samma microarray. Tanken med detta projekt är
att undersöka hur många av individerna i microarrayen som ger entydiga och
tillförlitliga svar när deras data poolas. Initialt avses grupperna innehålla åtta slumpmässiga individer var och i det fallet gör man sex microarrayer med
fyra av dessa individer i varje. Detta sänker kostnaden med en fjärdedel. Om
grupper om åtta ger en hög träffsäkerhet kan det vara intressant att använda
ännu större grupper då det ytterligare sänker kostnaden.
5
Denna möjlighet undersöks med hjälp av tidigare nämnda data från 1000
Genomes Project. Dessa data läses in med det Java-baserade biblioteket
HTSJDK som är skapat för att hantera bland annat vcf-filer [2]. De positionerna filtreras sedan för att matcha de som microarrayerna testar. Grupperna
undersöks för att avgöra hur många individer som ger ett entydigt svar för
var och en av de genetiska positioner som testas.
För varje markör avses också att undersöka dess Minor Allele Frequency
(MAF) vilket är hur ofta den ovanligaste allelen förekommer i markören.
Detta är intressant då en hög MAF bör betyda att fler grupper har svårare
att bli entydigt bestämda. Målet är att resultatet sedan ska kunna avläsas
och exporteras till MATLAB för att utvärderas.
En ambition är att implementera API- och CLI-gränssnitt så att andra användare lättare kan använda programmet. Det skulle också vara intressant
att göra det möjligt att ändra parametern för storlek på grupper samt att
testa specifika populationer ur den totala baserat på till exempel geografi.
2
2.1
2.1.1
Metod
Utförande
ReadVCF
Simuleringen skedde i utvecklingsmiljön Eclipse med programspråket Java.
Det Java-baserad biblioteket HTSJDK användes för att hantera VCF-filerna.
Kromosom 11 i 1000 Genomes Project fas 3 var de grunddata som användes
[3]. Denna innehåller 4045628 markörer från 2504 olika individer. Dessa data
filtrerades mot en textfil som innehåller 2612357 markörnamn som finns på
microarrayen Infinium Omni2.5Exome-8 v1.3 BeadChip [4]. Funktionaliteten
att göra detta inkapslades i en klass som heter ReadVCF, som skapades för
detta projekt.
Detta gjordes genom att varje markörnamn skannades från textfilen in i
en HashSet. Sedan läts en iterator gå över VCF-filen och jämföra varje
VariantContext-objekts namn mot setet. HashSet valdes över
ArrayList då det gick fortare att söka i ett HashSet-objekt, testade körningar med ArrayList tog över 10 timmar att slutföra. Det tog cirka 5
6
minuter att köra programmet med HashSet. Då den interna ordningen
på namnlistan inte hade någon betydelse så fanns inget skäl att använda
ArrayList.
Iteratorn var nödvändig att använda då arbetsminnet inte klarade av att
konvertera hela VCF-filen i ett stycke. Vid varje överensstämmande markörnamn skrevs det VariantContext-objektet in i en ny VCF-fil som totalt
fick 34749 markörer, vilka alla testade en specifik genotyp från samtliga individer.
2.1.2
RandomGroups
Slumpningen och utvärderingen gjordes i en annan klass som heter
RandomGroups. Programmet hämtade först alla individers identifikation
till en lista, sedan gjordes en lista av listor som representerade grupperna.
Där slumpades identifikationerna in med hjälp av ett tidsbaserat slumpfrö
medan de togs bort ur den första listan. Sedan utvärderades varje markör genom att en iterator gick igenom varje VariantContext-objekt i VCF-filen.
För varje objekt utvärderades alla grupper och resultatet adderades och
skrevs in i en textfil. Markörens MAF beräknades också genom att ta fram
den ovanligaste allelen, räkna hur ofta den förekom och dividera den på
antal alleler. Resultatet av MAF-beräkningen skrevs in i en separat textfil. Det gjordes totalt tre simuleringar med slumpfröna 230431854001625,
129666562967335 och 130067199881048, i den ordningen.
2.1.3
Poolning
Poolningen baserades på att dela en grupp på åtta individer i två lika stora
delar, tre gånger, i olika konstellationer. De åtta individerna skrevs binärt
under varandra och uppdelningen i delgrupperna skedde genom att dela in
nollorna och ettorna i varsinn grupp för varje kolumn. Grupperingen visas
nedan i Tabell 1. I Tabell 2 visas det tydligare hur de sex delgrupperna såg
ut med de åtta individerna numrerade 0-7.
7
Tabell 1: Denna tabell visar hur poolningen bestämdes, där varje unik färg
är en delgrupp
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
Tabell 2: Denna tabell visar hur alla individer (numrerade 0 till 7) i vardera
grupp poolades
0, 1, 2, 3
4, 5, 6, 7
0, 1, 4, 5
2, 3, 6, 7
0, 2, 4, 6
1, 3, 5, 7
Det finns totalt fyra olika kombinationer av alleler i varje markör, de kan
kallas; 0|0, 1|1, 0|1 och 1|0. 1|0 och 0|1 säger i detta fall samma sak. När resultaten 1|1 eller 0|0 fås i en delgrupp betyder det att individerna i delgruppen
ger entydiga resultat. För att en individ entydigt ska kunna bestämmas måste denne ha en homozygot genotyp och dennes genotyp måste vara likadan
som de övriga genotyperna i den delgruppen (delgrupperna syns i Tabell 2).
Homozygot betyder att båda allelerna i genotypen är likadana, alltså 0|0 eller
1|1.
Om exempelvis individ nummer 7 har genotypen 1|0 och resten av individerna har genotypen 0|0 kommer det inte gå att säga något om delgrupperna
med individ 7 i sig (de kommer att få resultatet 0|1 eller 1|0). Resten av
delgrupperna kommer dock att vara entydiga (de kommer att få resultatet
0|0), vilket innebär att individerna 0-6 går att återskapa, men inte individ 7.
Detta utnyttjades för att analysera hur många individer som gick att enty8
digt bestämmas för respektive markör, och hur MAF påverkade resultaten.
Detta visades sedan med hjälp av plottar i MATLAB.
2.2
2.2.1
Verktyg
MATLAB
MATLAB är ett program som används för att göra matematiska beräkningar
och skapa plottar utifrån resultaten. Det används i detta projekt för att utvärdera resultaten av simuleringarna som görs i Java. Textfilerna med resultaten
av utvärderingarna som görs i Java läses in i MATLAB. Sedan skapas plottar
utifrån dessa data som visar hur andel individer som ger entydigt bestämda
resultat förändras mellan de olika markörerna samt vid olika MAF.
2.2.2
Java
Java är ett objektorienterat programspråk, vilket innebär att program består
av ett eller flera objekt som samspelar. Dessa objekt och deras egenskaper
definieras i sin tur i olika klasser. En unik sak med Java är att när det
språkets program kompileras skapas Javabytekod som sedan exekveras av en
virituell dator kallad Java Virtual Machine (JVM). Då JVM alltid exekverar
programmen gör det Javaprogram väldigt portabla då de kan köras på andra
platformar utan att kompileras om [5].
2.2.3
HTSJDK
HTSJDK är ett Java-baserat bibliotek som bland annat har klasser som kan
hantera VCF-filer. VCF är ett filformat som i princip är ett tabellformat i
text där varje markör har data för varje individ lagrad. HTSJDK används för
all inläsning och manipulering av VCF-filerna då de är för stora för att öppna
på annat sätt. HTSJDK klarar också av att hantera det komprimerade vcf.gzformatet vilket gör att ursprungsdata kunde behållas i en avsevärt mycket
mindre storlek lokalt [2].
2.2.4
Eclipse
Eclipse är en utvecklingsmiljö som fungerar bra när man arbetar med programmeringsspråket Java. Det är den miljön och det språket som har använts
mest i detta projekt. Det finns olika vyer och perspektiv i Eclipse, vilket gör
9
att användaren kan anpassa miljön efter hur projektet är uppbyggt. I detta
fall användes standardperspektivet Java för att skriva klasserna och bygga
projektet.
2.2.5
GitHub
GitHub är en hemsida för externa Git-repositorier. Git fungerar lite annorlunda än många andra versionhanteringsprogram i att den för varje version tar
en ögonblicksbild på hela projektet istället för att bara spara ändringar i de
ändrade filerna. Detta gör att man lätt kan återgå till tidigare versioner av
samtliga filer som tillsammans bygger upp projektet. Det har bra integration
med Eclipse och används för versionshantering och hjälper författarna att
hålla varandra uppdaterade. GitHub möjligör att dela projekt med andra
som då får möjlighet att föreslå ändringar i koden (push) samt uppdatera
sin egen kod utifrån projektets utveckling (pull) [6].
2.2.6
Maven
Apache Maven är ett program som kan användas för att bygga mjukvaruprojekt med flera komponenter. Med M2Eclipse integrerades det direkt till
Eclipse och användes för att sköta beroenden för projektet. Beroenden finns
för att projektet ska hitta filer och klasser som används i projektet. Detta
underlättar avsevärt arbetet då fler än en användare ska jobba med samma
projekt [7].
10
3
3.1
Resultat
Andel entydigt bestämda individer
4000
3500
Antal markörer
3000
2500
2000
1500
1000
500
0
0
10
20
30
40
50
60
70
80
90
100
Andel entydigt bestämda individer i procent
Figur 1: Denna figur visar ett histogram över markörfördelningen i förhållande till andel entydigt bestämda individer för den första simuleringen, med
antal markörer på y-axeln och andel entydigt bestämda individer på x-axeln.
Figur 1 visar resultatet av den första simuleringen i form av ett histogram.
Resultatet visar markörfördelningen i förhållande till andel entydigt bestämda individer uppdelat i intervall om 2,5% entydigt bestämda individer. Till
exempel är det ungefär 4000 markörer som har mellan 2,5% och 5% entydigt bestämda individer och ungefär 1500 markörer som har mellan 10% och
12,5% entydigt bestämda individer.
11
Andel entydigt bestämda individer i procent
100
90
80
70
60
50
40
30
20
10
0
1
Figur 2: Denna figur visar ett lådogram över hur markörerna är uppdelade i
förhållande till andel entydigt bestämda individer för den första simuleringen,
med andel entydigt bestämda individer på y-axeln.
Figur 2 visar motsvarande resultat som figur 1, men i form av ett lådogram
i stället för ett histogram. Resultatet visar, precis som innan, markörfördelningen i förhållande till andel entydigt bestämda individer, men illustrerar
i detta fall vilka intervall av andel entydigt bestämda individer som hör till
vilka kvartiler av antal markörer.
12
3.2
Minor Allele Frequency (MAF)
Andel entydigt bestämda individer i procent
100
90
80
70
60
50
40
30
20
10
0
0
5
10
15
20
25
30
35
40
45
50
Minor Allele Frequency (MAF) i procent
Figur 3: Denna figur visar en punktplot över hur andel entydigt bestämda
individer beror av MAF för varje markör för den första simuleringen, med
andel entydigt bestämda individer på y-axeln och MAF i procent på x-axeln.
Figur 3 visar ett annat resultat av samma simulering som Figur 1 och Figur
2, i form av en punktplot. Denna illustrerar hur andel entydigt bestämda
individer beror av MAF för varje markör. Varje punkt motsvarar alltså en
markör.
13
1800
1600
Antal markörer
1400
1200
1000
800
600
400
200
0
0
5
10
15
20
25
30
35
40
45
50
Minor Allele Frequency (MAF) i procent
Figur 4: Denna figur visar ett histogram över markörfördelningen i förhållande till MAF i den filtrerade filen, med antal markörer på y-axeln och MAF i
procent på x-axeln.
Figur 4 illustrerar markörfördelningen i förhållande till MAF i den filtrerade
filen. Det är en jämnare fördelning mellan staplarna i denna figur än i Figur
1, där markörfördelning i förhållande till andel entydigt bestämda individer
visas, notera att MAF ligger på 23,80% i snitt.
Medelvärdena och standardavvikelserna för de olika simuleringarnas antal
entydigt bestämda individer visas nedan i Tabell 3.
Tabell 3: Denna tabell visar medelvärdena och standardavvikelserna för de
olika simuleringarna
Slumpfrö
Medelvärde Standardavvikelse
230431854001625 934,01
757,69
129666562967335 931,66
757,51
130067199881048 934,66
756,30
Medelvärdena från Tabell 3 ligger väldigt nära varandra och motsvarar ungefär 37% av det totala antalet individer 2504. Alltså ger ungefär 37% av
14
individerna ett entydigt resultat när en simulering körs med grupper om åtta
individer. Standardavvikelserna från Tabell 3 ligger även de nära varandra.
4
4.1
Diskussion
Utvärdering
Det syns i Figur 1 att andel entydigt bestämda individer är ganska jämnt
fördelat bland markörerna. Det är ungefär lika många markörer som har
47,5-50% entydigt bestämda individer och 90-92,5% entydigt bestämda individer. Detta gäller dock inte för låga andel entydigt bestämda individer,
där antalet markörer är högre. Detta beror troligtvis på hur utvärderingen av
poolerna görs, grupper kan endast få resultaten noll, fyra, fem, sex, sju samt
åtta entydigt bestämda individer. Detta beror på att minst en delpool med
fyra måste vara homozygota och lika för att någon individ ska bestämmas.
Markörer med hög MAF kommer således förskjuta resultaten mot noll för
varje grupp.
Det syns i Tabell 3 att de olika simuleringarna har väldigt lika resultat,
vilket tyder på att programmet fungerar bra, även om det egentligen krävs
en bredare statistisk analys för att fastställa detta. Medelvärdet är ungefär
37% entydigt bestämda individer för samtliga simuleringar, vilket är ett resultat som anses fullgott. Detta speciellt med tanke på att MAF i genomsnitt
låg på 23,80%, vilket tyder på att många av de undersökta markörerna hade
tämligen vanligt förekommande varianter.
Om det är tillräckligt hög träffsäkerhet för att kunna användas i praktiken
är svårt att säga, men för markörer med låg MAF bör det kunna vara ett
användbart tillvägagångssätt. I Figur 3 ser vi att en stor andel av markörerna
med MAF under 5% har fler än 80% entydigt bestämda individer, vilket är
ett väldigt bra resultat.
Det är också värt att notera att information erhålls även för många av de
individer som inte entydigt kan bestämmas. Om alla utom en individ i en
viss delpool har 0|0 (vilket ibland kan bestämmas från andra delpooler) och
svaret från delpoolen blir 1|0 så kan vi inte med säkerhet bestämma den
sista individens alleler. Men vi vet att den minst innehåller en etta, vilket i
15
biologiska sammanhang kan vara viktig information i sig.
4.2
Felkällor
Ett oroväckande resultat är markörerna i nedre vänstra hörnet på Figur 3.
Vi kan inte med säkerhet förklara hur en markör får så få bestämda individer
med så låg MAF. Det kan bero på att vissa markörer inte har komplett
data på samtliga individer och att ett tomt anrop till dessa i utvärderingen
förstör hela gruppen. Resultaten skulle också behöva statistiskt säkerställas
ytterligare för att vara fullständigt pålitliga.
5
5.1
5.1.1
Slutsatser
Upplevelse av verktyg
Överblick
Då projektet startade så var båda författarna helt okunniga om några av
verktygen vi arbetade med, vilket kan göra att en utvärdering av dem kan
vara intressant. Java och Matlab hade vi båda erfarenhet av så dem utesluter
vi ur utvärderingen då dessa fungerade som väntat. Det vi först kom i kontakt
under arbetet med var Eclipse. Detta program har stora fördelar över DrJava
som vi tidigare använt. Det finns mycket fler valmöjligheter och integrerade
tillbehör, vilket underlättar arbetet oerhört när allt fungerade. På grund av
alla valmöjligheter tar det dock avsevärt mycket längre tid att vänja sig vid
än DrJava som man i princip bara startar och börjar skriva kod i. Vi använder
Eclipse istället för DrJava bland annat för att DrJava inte har ett bra sätt
att importera hela HTSJDK på.
5.1.2
GitHub
Det andra nya verktyget vi kom i kontakt med var Git och närmare bestämt
GitHub. GitHub använder vi primärt för att dela projektet mellan författarna. Eclipse direktintegration med GitHub underlättar vid varje pull och
push av projektet och är väldigt smidigt att använda när allt är konfigurerat.
Konfigureringen tar dock ganska lång tid och det är svårt att veta om man
allting är rätt inställt. Vi har ingen version av vårt projekt som helt havererar
16
utan att vi enkelt kan spåra varför. Hade vi haft det hade tiden det tog att
konfigurera git troligen känts mer väl spenderad.
5.1.3
Maven
Maven var det tredje nya verktyg vi bekantade oss med. Det var något enklare
konfigurera än Git. Vårat projekt har ganska få delar så vi använde det
primärt för att importera HTSJDK som ett beroende på ett väldigt enkelt
sätt.
5.1.4
HTSJDK
HTSJDK var det sista obekanta verktyget vi använde. Det har exakt allt vi
behöver i form av klasser för att läsa in data och bearbeta dem efter våra
behov och mer därtill. Det stora hindret för att använda HTSJDK är dock
inte att förstå upplägget mellan olika klasser ur ett programmeringsperspektiv. Det svåra för oss är att som noviser inom biologi så förstår vi inte alltid
termerna de använder sig av i dokumentationen. Detta resulterar i att vi
ibland måste pröva ett par olika metoder och skriva ut det de returnerar för
att se om det är den metod vi söker. Att HTSJDKs dokumentation är riktad
till personer med djupare kunskaper i biologi får dock anses som fullständigt
rimligt.
5.2
Utveckling
Som nämnt i inledningen skulle det vara intressant att utveckla programmet
så att det blir möjligt för användaren att ställa in hur många individer som
ska finnas i varje grupp. Utvärderingsloopen i detta projekt blev lite för specifik och fungerar endast för grupper om åtta individer. För att lyckas med
denna utveckling krävs det att det upptäcks ett samband för hur villkoren
för entydighet ändras när man ökar antalet individer i varje grupp.
Det skulle också vara intressant att kunna ställa in olika parametrar, till
exempel geografi, för att kunna göra simuleringar som är mer specifika för
olika situationer.
Gränssnitten, även om de existerar skulle också kunna utvecklas. I nuvarande
17
form tar de båda programmen in argument för in- och utdata. För användare helt utan programmeringsbakgrund kanske ett grafiskt gränssnitt skulle
kunna implementeras, detta i kombination med valmöjligheter för grupper
skulle ge produkten ett professionellare intryck.
Det skulle också kunna utvecklas ett mått för den information som man
får om vissa individer som inte entydigt kan bestämmas samt ett sätt att
beräkna detta.
Fler körningar av programmet mot fler kromosomer skulle också behövas,
samt att biologer som jobbar med microarrayer utvärderar ifall resultaten är
bra nog för att metoden bör praktiseras.
6
Referenser
[1] IGSR: The International Genome Sample Resource. The 1000 Genomes Project[Internet] Cambridgeshire: European Molecular Biology Laboratory; 2008[Uppdaterad 2016-05-26, citerad 2016-05-26]. Hämtad från:
http://www.1000genomes.org/about
[2] Samtools. A Java API for high-throughput sequencing data (HTS) formats.[Internet].[citerad 2016 25 maj]. Hämtad från:
https://samtools.github.io/htsjdk/
[3] IGSR: The International Genome Sample Resource. The 1000 Genomes
Project[Internet] Cambridgeshire: European Molecular Biology Laboratory; 2008[Uppdaterad 2015-05-27, citerad 2016-05-26]. Hämtad från:
ftp://ftp.1000genomes.ebi.ac.uk/vol1/ftp/release/20130502/ALL.chr11.phase3_shapeit2_mvncall_integrated_v5a.20130502.genotypes.vcf.gz
[4] Illumina.
Infinium
Omni2.5-8
v1.3
Support
Files[Internet]
Hämtad
från:
[uppdaterad
2016
mars
10;
citerad
2016
9
mars]
ftp://webdata2:[email protected]/downloads/productfiles/humanomni25/v13/infiniumomni2-5-8-v1-3-a1-455-locus-report.zip
[5] Skansholm J. Java direkt med Swing. 8. uppl. Lund: Studentlitteratur
AB, 2014.
18
[6] Chacon S, Straub B. Pro Git [Internet]. New York:
Apress; 2014 [citerad 2016 maj 25] GitHub. Hämtad från:
https://progit2.s3.amazonaws.com/en/2016-03-22-f3531/progiten.1084.pdf
[7] The Eclipse Foundation. M2Eclipse[Internet].[uppdaterad 2015 sep 21;
citerad 2016 maj 25] Hämtad från: http://www.eclipse.org/m2e/
Appendices
A
ReadVCF
/**
*@author Jonas Giek & Simon Stromstedt Hallberg
*attempt at reading a VCF
*/
package poolinggenomes;
import
import
import
import
import
import
import
import
import
import
import
public
htsjdk.samtools.util.CloseableIterator;
htsjdk.variant.vcf.VCFFileReader;
htsjdk.variant.variantcontext.VariantContext;
htsjdk.variant.variantcontext.writer.VariantContextWriter;
htsjdk.variant.variantcontext.writer.VariantContextWriterBuilder;
htsjdk.variant.variantcontext.writer.Options;
htsjdk.variant.vcf.VCFHeader;
htsjdk.samtools.SAMSequenceDictionary;
java.util.HashSet;
java.io.*;
java.util.Scanner;
class ReadVCF {
/**
* This is a program to filter an existing .vcf-file against a
textfile
* containing the names of the variants you want to keep.
* @param args The first argument is the filename of marker
names that the program will filter the .vcf-file against.
@param
args The second argument is the filename of the .vcf
*
or vcf.gz-file you want to filter.
* @param args The third argument is the name of the output file
.
*/
public static void main(String[] args) throws
19
FileNotFoundException {
Scanner scan = new Scanner(new File(args[0]));
HashSet<String> names = new HashSet<String>();
int countfilter= 0;
int countgrundfil= 0;
while (scan.hasNext()){
scan.nextInt();
names.add(scan.next());
countfilter++;
scan.nextLine();
}
scan.close();
File vcfFile = new File(args[1]);
VCFFileReader reader = new VCFFileReader(vcfFile);
SAMSequenceDictionary dic = VCFFileReader.
getSequenceDictionary(vcfFile);
VCFHeader header = reader.getFileHeader();
VariantContextWriterBuilder builder = new
VariantContextWriterBuilder()
.setReferenceDictionary(dic)
.setOption(Options.INDEX_ON_THE_FLY);
VariantContextWriter writer = builder
.setOutputFile(args[3])
.build();
CloseableIterator<VariantContext> iter = reader.iterator
();
VariantContext variant = null;
writer.writeHeader(header);
int count= 0;
while (iter.hasNext()) {
variant = iter.next();
if (names.contains(variant.getID()) && variant!=
null) {
writer.add(variant);
count++;
}
countgrundfil++;
}
System.out.println(count);
System.out.println(countfilter);
System.out.println(countgrundfil);
System.out.println();
System.out.println(variant.getID());
reader.close();
}
}
20
B
RandomGroups
/**
* @author Jonas Giek & Simon Stromstedt Hallberg
*///
package poolinggenomes;
import
import
import
import
import
import
import
import
import
htsjdk.samtools.util.CloseableIterator;
htsjdk.variant.vcf.VCFFileReader;
htsjdk.variant.variantcontext.VariantContext;
htsjdk.variant.variantcontext.Allele;
java.io.*;
java.util.Set;
java.util.ArrayList;
java.util.List;
java.util.Random;
class RandomGroups {
/**
* This a program to calculate how many of the indivduals in a
certain vcf-file
* could get their genotype correctly determined with randomised
pooling in microarrays.
* Output files contain how many correctly determined individuals
each marker got as well
* as the Minor Allele Frequency of the marker.
* @param args The argument is the input file that will be
evaluated.
*/
public static void main(String[] args) throws FileNotFoundException
{
long seed = System.nanoTime();
// long seed = null;
File vcfFile = new File(args[0]);
VCFFileReader reader = new VCFFileReader(vcfFile, false);
CloseableIterator<VariantContext> iter = reader.iterator();
VariantContext variantForNames = iter.next();
Set<String> names = variantForNames.getSampleNames();
ArrayList <String> namelist = new ArrayList(names);
int size = namelist.size();
int shrinkingSize = namelist.size();
int sizeOfGroups = 8;
Random rdm = new Random(seed);
String seedToNameCount =
"markcount"+String.valueOf(seed)+".txt";
String seedToNameMAF = "maf"+String.valueOf(seed)+".txt";
ArrayList <ArrayList<String>> groups =
21
new ArrayList<ArrayList<String>>();
for (int i = 0; i < (size/sizeOfGroups); i++) {
ArrayList<String> L = new ArrayList<String>();
for (int j = 0; j <sizeOfGroups; j++) {
int ind = rdm.nextInt(shrinkingSize);
String S = namelist.get(ind).toString();
L.add(S);
namelist.remove(ind);
shrinkingSize--;
}
groups.add(L);
}
iter.close();
CloseableIterator<VariantContext> iter2 = reader.iterator();
VariantContext variant = null;
int countmarkers=0;
double maf;
List<Allele> alleles = null;
PrintWriter outputStream=new PrintWriter(seedToNameCount);
PrintWriter outputStream1=new PrintWriter(seedToNameMAF);
//PrintWriter outputStream=new
PrintWriter(seedToName+"replica.txt");
int count;
while (iter2.hasNext()) {
variant = iter2.next();
alleles = variant.getAlleles();
variant.getCalledChrCount(alleles.get(0));
if (variant.getCalledChrCount(alleles.get(0))
>=variant.getCalledChrCount(alleles.get(1))) {
maf = (double) variant.getCalledChrCount
(alleles.get(1))/variant.getCalledChrCount();
}
else {
maf = (double) variant.getCalledChrCount
(alleles.get(0))/variant.getCalledChrCount();
}
outputStream1.println(maf);
countmarkers++;
count=0;
for (int j = 0; j < groups.size(); j++) {
if (variant.getGenotype(groups.get(j).get(0)).isHom()
&& (variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(2)))
&& variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(3)))
|| variant.getGenotype(groups.get(j).get(0)).
22
sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(4)))
&& variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(5)))
|| variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(2)))
&& variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(4)))
&& variant.getGenotype(groups.get(j).get(0)).
sameGenotype(variant.getGenotype(groups.get(j).get(6)))))
count++;
if (variant.getGenotype(groups.get(j).get(1)).isHom()
&& (variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(2)))
&& variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(3)))
|| variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(4)))
&& variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(5)))
|| variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(3)))
&& variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(5)))
&& variant.getGenotype(groups.get(j).get(1)).
sameGenotype(variant.getGenotype(groups.get(j).get(7)))))
count++;
if (variant.getGenotype(groups.get(j).get(2)).isHom()
&& (variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(3)))
|| variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(4)))
&& variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(6)))
|| variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(3)))
23
&& variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(6)))
&& variant.getGenotype(groups.get(j).get(2)).
sameGenotype(variant.getGenotype(groups.get(j).get(7)))))
count++;
if (variant.getGenotype(groups.get(j).get(3)).isHom()
&& (variant.getGenotype(groups.get(j).get(3)).
sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).get(3)).
sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).
get(3)).sameGenotype(variant.getGenotype(groups.get(j).get(2)))
|| variant.getGenotype(groups.get(j).
get(3)).sameGenotype(variant.getGenotype(groups.get(j).get(2)))
&& variant.getGenotype(groups.get(j).
get(3)).sameGenotype(variant.getGenotype(groups.get(j).get(6)))
&& variant.getGenotype(groups.get(j).
get(3)).sameGenotype(variant.getGenotype(groups.get(j).get(7)))
|| variant.getGenotype(groups.get(j).
get(3)).sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).
get(3)).sameGenotype(variant.getGenotype(groups.get(j).get(5)))
&& variant.getGenotype(groups.get(j).
get(3)).sameGenotype(variant.getGenotype(groups.get(j).get(7)))))
count++;
if (variant.getGenotype(groups.get(j).get(4)).isHom()
&& (variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(5)))
|| variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(2)))
&& variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(6)))
|| variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(5)))
&& variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(6)))
&& variant.getGenotype(groups.get(j).
get(4)).sameGenotype(variant.getGenotype(groups.get(j).get(7)))))
count++;
if (variant.getGenotype(groups.get(j).get(5)).isHom()
&& (variant.getGenotype(groups.get(j).
24
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(4)))
|| variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(4)))
&& variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(6)))
&& variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(7)))
|| variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(3)))
&& variant.getGenotype(groups.get(j).
get(5)).sameGenotype(variant.getGenotype(groups.get(j).get(7)))))
count++;
if (variant.getGenotype(groups.get(j).get(6)).isHom()
&& (variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(0)))
&& variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(2)))
&& variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(4)))
|| variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(4)))
&& variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(5)))
&& variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(7)))
|| variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(2)))
&& variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(3)))
&& variant.getGenotype(groups.get(j).
get(6)).sameGenotype(variant.getGenotype(groups.get(j).get(7)))))
count++;
if (variant.getGenotype(groups.get(j).get(7)).isHom()
&& (variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(4)))
&& variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(5)))
&& variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(6)))
|| variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(2)))
25
&& variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(3)))
&& variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(6)))
|| variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(1)))
&& variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(3)))&&
variant.getGenotype(groups.get(j).get(7)).
sameGenotype(variant.getGenotype(groups.get(j).get(5)))))
count++;
}
outputStream.println(count);
}
outputStream.close();
outputStream1.close();
System.out.println(seed);
System.out.println(countmarkers);
reader.close();
}
}
26