Exploring familial DNA profile matching

Exploring familial DNA profile matching


I watched the BBC program about this case broadcast
on 14 Feb, 2006.
" The baby in the concrete block "
Although I'd been aware of this case I'd not really
taken any notice until I saw the reference to forensic
'scientist' Jonathan Whitaker. He that is promoting
a 'science'that is not recognised elsewhere in
the world because it is impossible to do LCN =
Low Copy Number, DNA profiling, without contamination
at source or even by the crime-scene or lab operatives.
Forensic Science International 123 (2001) p215-223
International Journal of Legal Medicine(2003) 117:pp170-174

Baby 'Lara' body found Sept 2002 in a concrete block,
nothing to say this block had been transported
from a long way away, but never mind.
Anyway a Stuart Black , via isotopic analysis ,
determined the baby was local origin and died 1990 to 1992.
When this data didn't fit the other evidence
(Philip Chadwick could not have been the father etc),
he revised his date span to 1960s to 1980s, don't you just love
forensic scientists.

Standard autosomal DNA profiling got nowhere
on blood stains, blood or bone and then
they tried mitochondrial DNA profiling to get a handle on
the mother but nothing emerged.
Then somehow, fudged/not explained
in this BBC prog, via some magic by Jonathan Whitaker,
they ended with a full 10 loci , 20 datapoint
DNA profile. Presumably by his wondrous amplify
all and sundry LCN ,contamination included ,
but not separately identifiable.
No mention of any rare alleles( sorry alleyals) ,
the set of 20 numbers he wrote down on paper
was just for explanation. If it had been genuine
(10,11)(7,8)(2,3)(6,9)(11,13)(2,5)(7,9)(12,17)(2,4)(8,9)
whatever order, would have been so rare that
8 of those 20 'alleles' have never been recorded in humans.

There were 332 samples eventually obtained for
current and past Barepot residents.
One of those was an Anne Chadwick who was named in the
press and went through the ringer of being hounded by
the police because she happened to have 16 of the 20
alleles in the Lara profile and 1 in each of the 10
loci, so was initially deemed the mother. This seemed
outragious and unwarranted action by the police so
I set out to determine what sort of likelihood of
a random unrelated 'match'.

From simulation (URL for details below) these are
the results for 100,000 simulated profiles (population
of whole Cumbria about 490,000).
Simulation using national UK caucasian data with co-ancestry
comensurate with the only published data for this factor,
at a national level. No allowance for all the related
individuals that would be in the 100,000 or so of West
Cumbria or any ,say pre-Windscale/Sellafield influx,
autochthonous (Cumbrian parents and gparents)
population structure.

For 100,000 profiles, results were for a match
to a specific but random profile was
10 alleles matching ; 9,3051
11 matching; 4,323
12 matching; 1,413
13 matching ;379
14 matching ; 76
15 matching ; 10
16 matching; 4
And of course all those 4 had 1 each of the 10 loci
matching as well.
You have to go down to the 13 out of 20
before you get a reasonable chance of
9 or less out of 10.
For 10 randomly picked of the 13 allele matches
 6 profiles had 1 in each of the 10 specific loci.


The parents of AC had long since died and
been cremated. No DNA froom inherited brooch
or anything but a partial profile from a histology
slide of her mother Sheila Parker
that would not be frozen and unlikely to give even
7 locus profile. Lived in Seaton so further
sleights that the Chadwicks's must have moved
the concrete block, it just gets worse and worse.

The most annoying bit was effectively a convenient
closure to all the waste of time and money ,
without further explanation, at the end
of the prog - a post script
"New tests have confirmed almost certainly
that the parents Sheila & Joseph Thwaites
were almost certainly the parents"

I would be much more comfortable if the
surnames mentioned weren't so North Country.
eg 1901 census references, birth or resident, in
Cumberland for all "John Thwaites" was 10
out of all counties total of 117, and for Westmorland
5 out of those 117

If AC is related directly or via her mother to Lara
is of no consequence to me.
But if she isn't and JW's DNA profile of 'Lara' is correct
then the factor for closed community co-ancestry
is very much more significant than I suspected.

The patial match figures from simulation of 100,000 random
profiles with no co-ancestry was
10 ; 4,929
11; 1,796
12 ; 476
13 ; 111
14 ; 10
15 ; 2
16 ; nil

For co-ancestry factor agreeing with when they
accidently ? published such data, is the figures previously
shown here
ie 4 (16 in 20 alleles) partial matches in 100,000 , so 1 in 25,000
If AC is not related directly or via her mother to
'Lara' then that would suggest such partial matches go down
from 1 in 25,000 to 1 in 322 or thereabouts, highly
significant, for settled communities. This is exactly
the sort of information that should be coming out
,fully disclosed, and its not.

published background
http://www.timesandstar.co.uk/news/viewarticle.aspx?id=265250
http://www.timesandstar.co.uk/babylara/update_babylara.asp
http://www.whitehaven-news.co.uk/news/viewarticle.aspx?id=264872
http://www.guardian.co.uk/crime/article/0,,1531359,00.html

Visual Basic simulation routines
Further results trying to get somewhere near 1 in 332 
but that would require definite cross-linking of loci/alleles.
Adapting the generator to > 11 percent AFs only then 
a 1 million run produced 5,610 profiles
Then matching to my chosen profile of 
34/23/57/46/23/26/13/45/33/56
produced 
537 10 alllele matches, 278 for 11,79 for 12.18 for 13 ,2 for 14
changing the target profile to only have the included 
alleles to 
34/25/56/46/23/26/14/45/33/56
had results
1006 for 10, 645 for 11, 324 for 12 m 117 for 13, 
34 for 14, 7 for 15 and 0 for 16

No rare allele familial DNA matching scenario.
Randomly selected profile to check for partial matches 
to 
(16,17)(7,8)  (13,15) (20,24)(29,30)(13,17) (17,23)(11,13)(14,14)(17,18)
transformed to 
34/23/57/46/23/26/13/45/33/56


Two VB routines separated by horizontal line. The first generates and the second determines the number of matches by progressively checking each pair at each locus, the third for factored in co-ancestry
' Generating 10 loci x2 profiles Dim ph(20) Dim pb(20) ' initialising Random Number Generator - RNG count9 = 0 count8 = 0 Randomize a = 214013 c = 2531011 x0 = Timer z = 2 ^ 24 ' 1 file 'feb26-g' for original, un-directed pairs, source data. Open "feb26-d" For Output As #1 ' outputs directed Open "feb26-ac" For Output As #10 ' change for different total size eg 199999 for 200,000 ' for 10,000 For x = 0 To 9999 For j = 0 To 1 ' vWA ,first locus ' RNG random number generator temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj If ph(j) < 0.001 Then ph(j) = 11 If ph(j) < 0.106 Then ph(j) = 1 If ph(j) < 0.186 Then ph(j) = 2 If ph(j) < 0.402 Then ph(j) = 3 If ph(j) < 0.672 Then ph(j) = 4 If ph(j) < 0.891 Then ph(j) = 5 If ph(j) < 0.984 Then ph(j) = 6 If ph(j) < 0.998 Then ph(j) = 7 If ph(j) < 1 Then ph(j) = 8 If ph(j) > 10 Then ph(j) = 0 Next j For j = 2 To 3 ' THO1 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj If ph(j) < 0.002 Then ph(j) = 11 If ph(j) < 0.243 Then ph(j) = 1 If ph(j) < 0.437 Then ph(j) = 2 If ph(j) < 0.545 Then ph(j) = 3 If ph(j) < 0.546 Then ph(j) = 4 If ph(j) < 0.686 Then ph(j) = 5 If ph(j) < 0.99 Then ph(j) = 6 If ph(j) < 1 Then ph(j) = 7 If ph(j) > 10 Then ph(j) = 0 Next j For j = 4 To 5 ' D8 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj If ph(j) < 0.018 Then ph(j) = 11 If ph(j) < 0.031 Then ph(j) = 1 If ph(j) < 0.125 Then ph(j) = 2 If ph(j) < 0.191 Then ph(j) = 3 If ph(j) < 0.334 Then ph(j) = 4 If ph(j) < 0.667 Then ph(j) = 5 If ph(j) < 0.876 Then ph(j) = 6 If ph(j) < 0.964 Then ph(j) = 7 If ph(j) < 0.995 Then ph(j) = 8 If ph(j) < 1 Then ph(j) = 9 If ph(j) > 10 Then ph(j) = 0 Next j For j = 6 To 7 ' FGA ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj pb(j) = "Z" If ph(j) < 0.025 Then ph(j) = 11 If ph(j) < 0.081 Then ph(j) = 1 If ph(j) < 0.224 Then ph(j) = 2 If ph(j) < 0.226 And ph(j) >= 0.224 Then pb(j) = "A" If ph(j) < 0.413 Then ph(j) = 3 If ph(j) < 0.415 And ph(j) >= 0.413 Then pb(j) = "B" If ph(j) < 0.58 Then ph(j) = 4 If ph(j) < 0.591 And ph(j) >= 0.58 Then pb(j) = "C" If ph(j) < 0.73 Then ph(j) = 5 If ph(j) < 0.734 And ph(j) >= 0.73 Then pb(j) = "D" If ph(j) < 0.88 Then ph(j) = 6 If ph(j) < 0.882 And ph(j) >= 0.88 Then pb(j) = "E" If ph(j) < 0.957 Then ph(j) = 7 If ph(j) < 0.992 Then ph(j) = 8 If ph(j) < 0.999 Then ph(j) = 9 If ph(j) < 1 And ph(j) >= 0.999 Then pb(j) = "F" If ph(j) > 10 Then ph(j) = 0 If pb(j) <> "Z" Then ph(j) = pb(j) Next j For j = 8 To 9 ' D21 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj pb(j) = "Z" If ph(j) < 0.001 Then pb(j) = "A" If ph(j) < 0.002 And ph(j) >= 0.001 Then pb(j) = "B" If ph(j) < 0.033 Then ph(j) = 11 If ph(j) < 0.193 Then ph(j) = 1 If ph(j) < 0.419 Then ph(j) = 2 If ph(j) < 0.677 Then ph(j) = 3 If ph(j) < 0.704 Then ph(j) = 4 If ph(j) < 0.773 Then ph(j) = 5 If ph(j) < 0.866 Then ph(j) = 6 If ph(j) < 0.884 Then ph(j) = 7 If ph(j) < 0.974 Then ph(j) = 8 If ph(j) < 0.975 And ph(j) >= 0.974 Then pb(j) = "C" If ph(j) < 0.997 Then ph(j) = 9 If ph(j) < 1 And ph(j) >= 0.997 Then pb(j) = "D" If ph(j) > 10 Then ph(j) = 0 If pb(j) <> "Z" Then ph(j) = pb(j) Next j For j = 10 To 11 ' D18 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj pb(j) = "Z" If ph(j) < 0.001 Then pb(j) = "A" If ph(j) < 0.009 And ph(j) >= 0.001 Then pb(j) = "B" If ph(j) < 0.021 Then ph(j) = 11 If ph(j) < 0.16 Then ph(j) = 1 If ph(j) < 0.285 Then ph(j) = 2 If ph(j) < 0.449 Then ph(j) = 3 If ph(j) < 0.594 Then ph(j) = 4 If ph(j) < 0.731 Then ph(j) = 5 If ph(j) < 0.846 Then ph(j) = 6 If ph(j) < 0.926 Then ph(j) = 7 If ph(j) < 0.967 Then ph(j) = 8 If ph(j) < 0.982 Then ph(j) = 9 If ph(j) < 0.992 And ph(j) >= 0.982 Then pb(j) = "C" If ph(j) < 0.997 And ph(j) >= 0.992 Then pb(j) = "D" If ph(j) < 0.998 And ph(j) >= 0.997 Then pb(j) = "E" If ph(j) < 1 And ph(j) >= 0.998 Then pb(j) = "F" ' allele 20 (C) reduced from .017 to .015 as allele ' frequencies summed to 1.002 If ph(j) > 10 Then ph(j) = 0 If pb(j) <> "Z" Then ph(j) = pb(j) Next j For j = 12 To 13 ' D2S1338 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj pb(j) = "Z" If ph(j) < 0.037 Then ph(j) = 11 If ph(j) < 0.222 Then ph(j) = 1 If ph(j) < 0.309 Then ph(j) = 2 If ph(j) < 0.419 Then ph(j) = 3 If ph(j) < 0.557 Then ph(j) = 4 If ph(j) < 0.589 Then ph(j) = 5 If ph(j) < 0.613 Then ph(j) = 6 If ph(j) < 0.725 Then ph(j) = 7 If ph(j) < 0.867 Then ph(j) = 8 If ph(j) < 0.978 Then ph(j) = 9 If ph(j) < 0.997 And ph(j) >= 0.978 Then pb(j) = "A" If ph(j) < 1 And ph(j) >= 0.997 Then pb(j) = "B" If ph(j) > 10 Then ph(j) = 0 If pb(j) <> "Z" Then ph(j) = pb(j) Next j For j = 14 To 15 ' D16 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj If ph(j) < 0.019 Then ph(j) = 11 If ph(j) < 0.148 Then ph(j) = 1 If ph(j) < 0.202 Then ph(j) = 2 If ph(j) < 0.491 Then ph(j) = 3 If ph(j) < 0.779 Then ph(j) = 4 If ph(j) < 0.965 Then ph(j) = 5 If ph(j) < 0.994 Then ph(j) = 6 If ph(j) < 1 Then ph(j) = 7 If ph(j) > 10 Then ph(j) = 0 Next j For j = 16 To 17 ' D19 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj pb(j) = "Z" If ph(j) < 0.087 Then ph(j) = 11 If ph(j) < 0.309 Then ph(j) = 1 If ph(j) < 0.322 Then ph(j) = 2 If ph(j) < 0.704 Then ph(j) = 3 If ph(j) < 0.719 Then ph(j) = 4 If ph(j) < 0.896 Then ph(j) = 5 If ph(j) < 0.934 Then ph(j) = 6 If ph(j) < 0.975 Then ph(j) = 7 If ph(j) < 0.992 Then ph(j) = 8 If ph(j) < 0.997 Then ph(j) = 9 If ph(j) < 0.999 And ph(j) >= 0.997 Then pb(j) = "A" If ph(j) < 1 And ph(j) >= 0.999 Then pb(j) = "B" If ph(j) > 10 Then ph(j) = 0 If pb(j) <> "Z" Then ph(j) = pb(j) Next j For j = 18 To 19 ' D3 ' RNG temp = x0 * a + c temp = temp / z x1 = (temp - Fix(temp)) * z x0 = x1 phj = x1 / z ph(j) = phj If ph(j) < 0.001 Then ph(j) = 11 If ph(j) < 0.007 Then ph(j) = 1 If ph(j) < 0.139 Then ph(j) = 2 If ph(j) < 0.404 Then ph(j) = 3 If ph(j) < 0.651 Then ph(j) = 4 If ph(j) < 0.846 Then ph(j) = 5 If ph(j) < 0.987 Then ph(j) = 6 If ph(j) < 1 Then ph(j) = 7 If ph(j) > 10 Then ph(j) = 0 Next j ' output the original generated file Write #1, ph(0) & ph(1) & ph(2) & ph(3) & ph(4) & ph(5) & ph(6) & ph(7) & ph(8) & ph(9) & ph(10) & ph(11) & ph(12) & ph(13) & ph(14) & ph(15) & ph(16) & ph(17) & ph(18) & ph(19) ' Because in real DNA profiles without further info ,no one ' knows which allele in each pair came from the mother or father ' by convention they are written smaller ,larger (or equal). ' The following directs each pair For j = 0 To 18 Step 2 If ph(j + 1) < ph(j) Then jjj = ph(j) ph(j) = ph(j + 1) ph(j + 1) = jjj End If Next j Write #10, ph(0) & ph(1) & ph(2) & ph(3) & ph(4) & ph(5) & ph(6) & ph(7) & ph(8) & ph(9) & ph(10) & ph(11) & ph(12) & ph(13) & ph(14) & ph(15) & ph(16) & ph(17) & ph(18) & ph(19) count0 = count0 + 1 Next x Close #10 Close #1 ' count file for data to fix for - next loops in sucessive dividings Open "feb26-c" For Output As #20 Write #20, 0, count0, 1, count1, 2, count2, 3, count3, 4, count4, 5, count5, 6, count6, 7, count7, 8, count8, 9, count9 Close #20
' number of allele matches to a given profile Dim ps As String Dim ph(20) ' Locus 1 temp = "feb26-d" temp0 = "feb26-dc" tempc = "feb26-d1c" Open temp For Input As #1 Open temp0 For Output As #10 count0 = 0 count1 = 0 Do Until (EOF(1) = True) count0 = 0 zz = 0 Input #1, ps a1$ = Mid(ps, 1, 1) ph(1) = Val(a1$) a2$ = Mid(ps, 2, 1) ph(2) = Val(a2$) xx=zz ' change these 2 lines for each locus If ph(1) = 3 Then zz = zz + 1 If ph(2) = 4 Then zz = zz + 1 If ph(1) = 4 Then zz = zz + 1 If ph(2) = 3 Then zz = zz + 1 ' for homozygotic pair situation , so as ' not to count twice If ph(1) = ph(2) and zz=xx+2 then zz = zz-1 ' Locus 2 a3$ = Mid(ps, 3, 1) ph(3) = Val(a3$) a4$ = Mid(ps, 4, 1) ph(4) = Val(a4$) xx=zz ' change these 2 lines for each locus If ph(3) = 2 Then zz = zz + 1 If ph(4) = 3 Then zz = zz + 1 If ph(3) = 3 Then zz = zz + 1 If ph(4) = 2 Then zz = zz + 1 If ph(3) = ph(4) and zz=xx+2 then zz = zz-1 ' Locus 3 a5$ = Mid(ps, 5, 1) ph(5) = Val(a5$) a6$ = Mid(ps, 6, 1) ph(6) = Val(a6$) xx=zz ' change these 2 lines for each locus If ph(5) = 7 Then zz = zz + 1 If ph(6) = 5 Then zz = zz + 1 If ph(5) = 5 Then zz = zz + 1 If ph(6) = 7 Then zz = zz + 1 If ph(5) = ph(6) and zz=xx+2then zz = zz-1 ' Locus 4 a7$ = Mid(ps, 7, 1) ph(7) = Val(a7$) a8$ = Mid(ps, 8, 1) ph(8) = Val(a8$) xx=zz ' change these 2 lines for each locus If ph(7) = 6 Then zz = zz + 1 If ph(8) = 4 Then zz = zz + 1 If ph(7) = 4 Then zz = zz + 1 If ph(8) = 6 Then zz = zz + 1 If ph(7) = ph(8) and zz=xx+2 then zz = zz-1 ' Locus 5 a9$ = Mid(ps, 9, 1) ph(9) = Val(a9$) a10$ = Mid(ps, 10, 1) ph(10) = Val(a10$) xx=zz ' change these 2 lines for each locus If ph(9) = 2 Then zz = zz + 1 If ph(10) = 3 Then zz = zz + 1 If ph(9) = 3 Then zz = zz + 1 If ph(10) = 2 Then zz = zz + 1 If ph(9) = ph(10)and zz=xx+2 then zz = zz-1 ' Locus 6 a11$ = Mid(ps, 11, 1) ph(11) = Val(a11$) a12$ = Mid(ps, 12, 1) ph(12) = Val(a12$) xx=zz ' change these 2 lines for each locus If ph(11) = 2 Then zz = zz + 1 If ph(12) = 6 Then zz = zz + 1 If ph(11) = 6 Then zz = zz + 1 If ph(12) = 2 Then zz = zz + 1 If ph(11) = ph(12) and zz=xx+2 then zz = zz-1 ' Locus 7 a13$ = Mid(ps, 13, 1) ph(13) = Val(a13$) a14$ = Mid(ps, 14, 1) ph(14) = Val(a14$) xx=zz ' change these 2 lines for each locus If ph(13) =1 Then zz = zz + 1 If ph(14) =3 Then zz = zz + 1 If ph(13) = 3 Then zz = zz + 1 If ph(14) = 1 Then zz = zz + 1 If ph(13) = ph(14) and zz=xx+2 then zz = zz-1 ' Locus 8 a15$ = Mid(ps, 15, 1) ph(15) = Val(a15$) a16$ = Mid(ps, 16, 1) ph(16) = Val(a16$) xx=zz ' change these 2 lines for each locus If ph(15) = 4 Then zz = zz + 1 If ph(16) = 5 Then zz = zz + 1 If ph(15) = 5 Then zz = zz + 1 If ph(16) = 4 Then zz = zz + 1 If ph(15) = ph(16) and zz=xx+2then zz = zz-1 ' Locus 9 a17$ = Mid(ps, 17, 1) ph(17) = Val(a17$) a18$ = Mid(ps, 18, 1) ph(18) = Val(a18$) xx=zz ' change these 2 lines for each locus If ph(17) = 3 Then zz = zz + 1 If ph(18) = 3 Then zz = zz + 1 ' Locus 10 a19$ = Mid(ps, 19, 1) ph(19) = Val(a19$) a20$ = Mid(ps, 20, 1) ph(20) = Val(a20$) xx=zz ' change these 2 lines for each locus If ph(19) = 5 Then zz = zz + 1 If ph(20) = 6 Then zz = zz + 1 If ph(19) = 6 Then zz = zz + 1 If ph(20) = 5 Then zz = zz + 1 If ph(19) = ph(20)and zz=xx+2 then zz = zz-1 If zz >= 10 Then Write #10, ps, zz count1 = count1 + 1 End If Loop Close (1) Close #1 Close #10


' Generating 10 loci x2 profiles with
' AF >= 8.7%
' directing pairs 
Dim ph(20)
Dim pb(20)
' initialising Random Number Generator - RNG
count9 = 0
count8 = 0
countf = 0

Randomize
a = 214013
c = 2531011
x0 = Timer
z = 2 ^ 24
'  1 file 'feb26-g' for original, un-directed pairs, source data.


Open "feb26-g" For Output As #1
' outputs directed and divided by first digit
Open "feb26-d" For Output As #10


' change for different total size eg 199999 for 200,000
For x = 0 To 999
flag = 0
For j = 0 To 1
' vWA ,first locus
' RNG random number generator
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z

ph(j) = phj
If ph(j) < 0.001 Then ph(j) = 11
If ph(j) < 0.106 Then ph(j) = 1
If ph(j) < 0.186 Then ph(j) = 2
If ph(j) < 0.402 Then ph(j) = 3
If ph(j) < 0.672 Then ph(j) = 4
If ph(j) < 0.891 Then ph(j) = 5
If ph(j) < 0.984 Then ph(j) = 6
If ph(j) < 0.998 Then ph(j) = 7
If ph(j) < 1 Then ph(j) = 8

If ph(j) > 10 Then ph(j) = 0

If ph(j) = "0" Then flag = 1
If ph(j) = "2" Then flag = 1
If ph(j) = "7" Then flag = 1
If ph(j) = "8" Then flag = 1


Next j

For j = 2 To 3
' THO1
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj

If ph(j) < 0.002 Then ph(j) = 11
If ph(j) < 0.243 Then ph(j) = 1
If ph(j) < 0.437 Then ph(j) = 2
If ph(j) < 0.545 Then ph(j) = 3
If ph(j) < 0.546 Then ph(j) = 4
If ph(j) < 0.686 Then ph(j) = 5
If ph(j) < 0.99 Then ph(j) = 6
If ph(j) < 1 Then ph(j) = 7

If ph(j) > 10 Then ph(j) = 0
If ph(j) = "0" Then flag = 1
If ph(j) = "4" Then flag = 1
If ph(j) = "7" Then flag = 1


Next j

For j = 4 To 5
' D8
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj

If ph(j) < 0.018 Then ph(j) = 11
If ph(j) < 0.031 Then ph(j) = 1
If ph(j) < 0.125 Then ph(j) = 2
If ph(j) < 0.191 Then ph(j) = 3
If ph(j) < 0.334 Then ph(j) = 4
If ph(j) < 0.667 Then ph(j) = 5
If ph(j) < 0.876 Then ph(j) = 6
If ph(j) < 0.964 Then ph(j) = 7
If ph(j) < 0.995 Then ph(j) = 8
If ph(j) < 1 Then ph(j) = 9
If ph(j) > 10 Then ph(j) = 0

If ph(j) = "0" Then flag = 1
If ph(j) = "1" Then flag = 1
If ph(j) = "3" Then flag = 1
If ph(j) = "8" Then flag = 1
If ph(j) = "9" Then flag = 1


Next j

For j = 6 To 7
' FGA
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj
pb(j) = "Z"
If ph(j) < 0.025 Then ph(j) = 11
If ph(j) < 0.081 Then ph(j) = 1
If ph(j) < 0.224 Then ph(j) = 2
If ph(j) < 0.226 And ph(j) >= 0.224 Then pb(j) = "A"
If ph(j) < 0.413 Then ph(j) = 3
If ph(j) < 0.415 And ph(j) >= 0.413 Then pb(j) = "B"
If ph(j) < 0.58 Then ph(j) = 4
If ph(j) < 0.591 And ph(j) >= 0.58 Then pb(j) = "C"
If ph(j) < 0.73 Then ph(j) = 5
If ph(j) < 0.734 And ph(j) >= 0.73 Then pb(j) = "D"
If ph(j) < 0.88 Then ph(j) = 6
If ph(j) < 0.882 And ph(j) >= 0.88 Then pb(j) = "E"
If ph(j) < 0.957 Then ph(j) = 7
If ph(j) < 0.992 Then ph(j) = 8
If ph(j) < 0.999 Then ph(j) = 9
If ph(j) < 1 And ph(j) >= 0.999 Then pb(j) = "F"

If ph(j) > 10 Then ph(j) = 0
If pb(j) <> "Z" Then ph(j) = pb(j)

If ph(j) = "0" Then flag = 1
If ph(j) = "1" Then flag = 1
If ph(j) = "7" Then flag = 1
If ph(j) = "8" Then flag = 1
If ph(j) = "9" Then flag = 1



If pb(j) = "A" Then flag = 1
If pb(j) = "B" Then flag = 1
If pb(j) = "C" Then flag = 1
If pb(j) = "D" Then flag = 1
If pb(j) = "E" Then flag = 1
If pb(j) = "F" Then flag = 1




Next j

For j = 8 To 9
' D21
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj
pb(j) = "Z"
If ph(j) < 0.001 Then pb(j) = "A"
If ph(j) < 0.002 And ph(j) >= 0.001 Then pb(j) = "B"
If ph(j) < 0.033 Then ph(j) = 11
If ph(j) < 0.193 Then ph(j) = 1
If ph(j) < 0.419 Then ph(j) = 2
If ph(j) < 0.677 Then ph(j) = 3
If ph(j) < 0.704 Then ph(j) = 4
If ph(j) < 0.773 Then ph(j) = 5
If ph(j) < 0.866 Then ph(j) = 6
If ph(j) < 0.884 Then ph(j) = 7
If ph(j) < 0.974 Then ph(j) = 8
If ph(j) < 0.975 And ph(j) >= 0.974 Then pb(j) = "C"
If ph(j) < 0.997 Then ph(j) = 9
If ph(j) < 1 And ph(j) >= 0.997 Then pb(j) = "D"

If ph(j) > 10 Then ph(j) = 0
If pb(j) <> "Z" Then ph(j) = pb(j)
If ph(j) = "0" Then flag = 1
If ph(j) = "4" Then flag = 1
If ph(j) = "5" Then flag = 1
If ph(j) = "7" Then flag = 1
If ph(j) = "9" Then flag = 1

If pb(j) = "A" Then flag = 1
If pb(j) = "B" Then flag = 1
If pb(j) = "C" Then flag = 1
If pb(j) = "D" Then flag = 1



Next j

For j = 10 To 11
' D18
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj
pb(j) = "Z"
If ph(j) < 0.001 Then pb(j) = "A"
If ph(j) < 0.009 And ph(j) >= 0.001 Then pb(j) = "B"
If ph(j) < 0.021 Then ph(j) = 11
If ph(j) < 0.16 Then ph(j) = 1
If ph(j) < 0.285 Then ph(j) = 2
If ph(j) < 0.449 Then ph(j) = 3
If ph(j) < 0.594 Then ph(j) = 4
If ph(j) < 0.731 Then ph(j) = 5
If ph(j) < 0.846 Then ph(j) = 6
If ph(j) < 0.926 Then ph(j) = 7
If ph(j) < 0.967 Then ph(j) = 8
If ph(j) < 0.982 Then ph(j) = 9
If ph(j) < 0.992 And ph(j) >= 0.982 Then pb(j) = "C"
If ph(j) < 0.997 And ph(j) >= 0.992 Then pb(j) = "D"
If ph(j) < 0.998 And ph(j) >= 0.997 Then pb(j) = "E"
If ph(j) < 1 And ph(j) >= 0.998 Then pb(j) = "F"
' allele 20 (C) reduced from .017 to .015 as allele
' frequencies summed to 1.002
If ph(j) > 10 Then ph(j) = 0
If pb(j) <> "Z" Then ph(j) = pb(j)
If ph(j) = "0" Then flag = 1
If ph(j) = "7" Then flag = 1
If ph(j) = "8" Then flag = 1
If ph(j) = "9" Then flag = 1


If pb(j) = "A" Then flag = 1
If pb(j) = "B" Then flag = 1
If pb(j) = "C" Then flag = 1
If pb(j) = "D" Then flag = 1
If pb(j) = "E" Then flag = 1
If pb(j) = "F" Then flag = 1


Next j





For j = 12 To 13
' D2S1338
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj
pb(j) = "Z"
If ph(j) < 0.037 Then ph(j) = 11
If ph(j) < 0.222 Then ph(j) = 1
If ph(j) < 0.309 Then ph(j) = 2
If ph(j) < 0.419 Then ph(j) = 3
If ph(j) < 0.557 Then ph(j) = 4
If ph(j) < 0.589 Then ph(j) = 5
If ph(j) < 0.613 Then ph(j) = 6
If ph(j) < 0.725 Then ph(j) = 7
If ph(j) < 0.867 Then ph(j) = 8
If ph(j) < 0.978 Then ph(j) = 9
If ph(j) < 0.997 And ph(j) >= 0.978 Then pb(j) = "A"
If ph(j) < 1 And ph(j) >= 0.997 Then pb(j) = "B"

If ph(j) > 10 Then ph(j) = 0
If pb(j) <> "Z" Then ph(j) = pb(j)
If ph(j) = "0" Then flag = 1
If ph(j) = "5" Then flag = 1
If ph(j) = "6" Then flag = 1



If pb(j) = "A" Then flag = 1
If pb(j) = "B" Then flag = 1

Next j


For j = 14 To 15
' D16
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj

If ph(j) < 0.019 Then ph(j) = 11
If ph(j) < 0.148 Then ph(j) = 1
If ph(j) < 0.202 Then ph(j) = 2
If ph(j) < 0.491 Then ph(j) = 3
If ph(j) < 0.779 Then ph(j) = 4
If ph(j) < 0.965 Then ph(j) = 5
If ph(j) < 0.994 Then ph(j) = 6
If ph(j) < 1 Then ph(j) = 7

If ph(j) > 10 Then ph(j) = 0
If ph(j) = "0" Then flag = 1
If ph(j) = "2" Then flag = 1
If ph(j) = "6" Then flag = 1
If ph(j) = "7" Then flag = 1


Next j

For j = 16 To 17
' D19
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj
pb(j) = "Z"
If ph(j) < 0.087 Then ph(j) = 11
If ph(j) < 0.309 Then ph(j) = 1
If ph(j) < 0.322 Then ph(j) = 2
If ph(j) < 0.704 Then ph(j) = 3
If ph(j) < 0.719 Then ph(j) = 4
If ph(j) < 0.896 Then ph(j) = 5
If ph(j) < 0.934 Then ph(j) = 6
If ph(j) < 0.975 Then ph(j) = 7
If ph(j) < 0.992 Then ph(j) = 8
If ph(j) < 0.997 Then ph(j) = 9
If ph(j) < 0.999 And ph(j) >= 0.997 Then pb(j) = "A"
If ph(j) < 1 And ph(j) >= 0.999 Then pb(j) = "B"
If ph(j) > 10 Then ph(j) = 0

If pb(j) <> "Z" Then ph(j) = pb(j)
If ph(j) = "2" Then flag = 1
If ph(j) = "4" Then flag = 1
If ph(j) = "6" Then flag = 1
If ph(j) = "7" Then flag = 1
If ph(j) = "8" Then flag = 1
If ph(j) = "9" Then flag = 1



If pb(j) = "A" Then flag = 1
If pb(j) = "B" Then flag = 1


Next j


For j = 18 To 19
' D3
' RNG
  temp = x0 * a + c
  temp = temp / z
  x1 = (temp - Fix(temp)) * z
  x0 = x1
  phj = x1 / z
ph(j) = phj

If ph(j) < 0.001 Then ph(j) = 11
If ph(j) < 0.007 Then ph(j) = 1
If ph(j) < 0.139 Then ph(j) = 2
If ph(j) < 0.404 Then ph(j) = 3
If ph(j) < 0.651 Then ph(j) = 4
If ph(j) < 0.846 Then ph(j) = 5
If ph(j) < 0.987 Then ph(j) = 6
If ph(j) < 1 Then ph(j) = 7

If ph(j) > 10 Then ph(j) = 0
If ph(j) = "0" Then flag = 1
If ph(j) = "1" Then flag = 1
If ph(j) = "7" Then flag = 1

Next j

If flag = 1 Then countf = countf + 1

If flag = 0 Then
' output the original generated file

Write #1, ph(0) & ph(1) & ph(2) & ph(3) & ph(4) & ph(5) & ph(6) & ph(7) & ph(8) & ph(9) & ph(10) & ph(11) & ph(12) & ph(13) & ph(14) & ph(15) & ph(16) & ph(17) & ph(18) & ph(19)



' Because in real DNA profiles without further info ,no one
' knows which allele in each pair came from the mother or father
' by convention they are written smaller ,larger (or equal).
' The following directs each pair


For j = 0 To 18 Step 2
If ph(j + 1) < ph(j) Then
jjj = ph(j)
ph(j) = ph(j + 1)
ph(j + 1) = jjj
End If
Next j

Write #10, ph(0) & ph(1) & ph(2) & ph(3) & ph(4) & ph(5) & ph(6) & ph(7) & ph(8) & ph(9) & ph(10) & ph(11) & ph(12) & ph(13) & ph(14) & ph(15) & ph(16) & ph(17) & ph(18) & ph(19)

End If
Next x
Close #10


Close #1


For generator with co-ancestry factor to match published 6 loci matches then 1,307,200 iterations generates about 100,000 such profiles. For 100,000 profiles, results were for a match to a specific but random profile was 10 alleles matching ; 9,3051 11 matching; 4,323 12 matching; 1,413 13 matching ;379 14 matching ; 76 15 matching ; 10 16 matching; 4 And of course all those 4 had 1 each of the 10 loci matching as well. You have to go down to the 13 out of 20 before you get a reasonable chance of 9 or less out of 10. For 10 randomly picked of the 13 allele matches 6 profiles had 1 in each of the 10 specific loci.

Email Paul Nutteing by removing 4 of the 5 dots
or email Paul Nutteing ,remove all but one dot

Or a message on usenet group uk.legal has got to me recently a couple of times.
A lot of the contents of this file plus other material 'peer reviewed' on the main forensic science usergroup

Background
A simulation of a large DNA profile database
A simulation of DNA profile 'families'
A simulation of DNA profile families with consanguinity
A simulation of DNA profile 'families' for 6 generations
dnas.htm revisited with all alleles represented
dnas.htm revisited for >8 percent allele frequency subset (similar ancestry )
Simulation of Taiwanese Tao and Rukai populations to explore the effect of within and without ancestral clusters
Basques autochthonous DNA profiles simulation, 9 loci
Australian Capital Caucasian 9 loci simulation
Australian Capital Caucasian 9 loci simulation, >= 5% allele frequency
CODIS, 13 Loci Caucasian Simulation
Automating the macros
Exploring other DNA profile match scenarios
Suspect familial matching
Return to co-ancestry factor in the NDNAD simulations
144 random matches in 65,000 -- ONLY?

Powered by counter.bloke.com