use
vars
qw($FieldDelim $AlleleDelim $NoHeader)
;
(
$FieldDelim
,
$AlleleDelim
,
$NoHeader
) =(
','
,
'\s+'
,0);
sub
_initialize {
my
(
$self
,
@args
) =
@_
;
$Bio::PopGen::Genotype::BlankAlleles
=
''
;
my
(
$fieldsep
,
$all_sep
,
$noheader
) =
$self
->_rearrange([
qw(FIELD_DELIMITER
ALLELE_DELIMITER
NO_HEADER)
],
@args
);
$self
->flag(
'no_header'
,
defined
$noheader
?
$noheader
:
$NoHeader
);
$self
->flag(
'field_delimiter'
,
defined
$fieldsep
?
$fieldsep
:
$FieldDelim
);
$self
->flag(
'allele_delimiter'
,
defined
$all_sep
?
$all_sep
:
$AlleleDelim
);
$self
->{
'_header'
} =
undef
;
return
1;
}
sub
flag {
my
$self
=
shift
;
my
$fieldname
=
shift
;
return
unless
defined
$fieldname
;
return
$self
->{
'_flag'
}->{
$fieldname
} =
shift
if
@_
;
return
$self
->{
'_flag'
}->{
$fieldname
};
}
sub
next_individual {
my
(
$self
) =
@_
;
my
(
$sam
,
@marker_results
,
$number_of_ids
,
$number_of_markers
,
$marker_positions
,
$micro_snp
);
while
(
defined
(
$_
=
$self
->_readline) ) {
next
if
( /^\s+$/ || !
length
(
$_
) );
last
;
}
return
unless
defined
$_
;
if
(
$self
->flag(
'no_header'
) ||
defined
$self
->{
'_header'
} ) {
if
(!
$self
->{
'_count'
} && /^\s*\d+$/){
$self
->flag(
'number_of_ids'
,
$_
);
$self
->{
'_count'
}++;
return
$self
->next_individual;
}
elsif
(
$self
->{
'_count'
} == 1 && /^\s*\d+$/){
$self
->flag(
'number_of_markers'
,
$_
);
$self
->{
'_count'
}++;
return
$self
->next_individual;
}
elsif
(
$self
->{
'_count'
} == 2 && /^\s
*P
\s\d/){
$self
->flag(
'marker_positions'
,
$_
);
$self
->{
'_count'
}++;
return
$self
->next_individual;
}
elsif
(
$self
->{
'_count'
} == 3 && /^\s*(M|S)+\s*$/i){
$self
->flag(
'micro_snp'
,
$_
);
$self
->{
'_count'
}++;
return
$self
->next_individual;
}
elsif
(/^\s*\
(
$self
->{
'_sam'
}) = /^\s*\
$self
->{
'_count'
}++;
return
$self
->next_individual;
}
else
{
chomp
$_
;
if
(
$self
->{
'_row1'
} ) {
@{
$self
->{
'_second_row'
}} =
split
(
$self
->flag(
'field_delimiter'
),
$_
);
for
my
$i
(0 .. $
push
(@{
$self
->{
'_marker_results'
}},
$self
->{
'_first_row'
}->[
$i
].
$self
->flag(
'field_delimiter'
).
$self
->{
'_second_row'
}->[
$i
]);
}
$self
->{
'_row1'
} = 0;
}
else
{
@{
$self
->{
'_marker_results'
}} = ();
@{
$self
->{
'_first_row'
}} =
split
(
$self
->flag(
'field_delimiter'
),
$_
);
$self
->{
'_row1'
} = 1;
return
$self
->next_individual;
}
}
my
$i
= 1;
foreach
my
$m
( @{
$self
->{
'_marker_results'
}} ) {
$m
=~ s/^\s+//;
$m
=~ s/\s+$//;
my
$markername
;
if
(
defined
$self
->{
'_header'
} ) {
$markername
=
$self
->{
'_header'
}->[
$i
] ||
"Marker$i"
;
}
else
{
$markername
=
"Marker$i"
;
}
$self
->debug(
"markername is $markername alleles are $m\n"
);
my
@alleles
=
split
(
$self
->flag(
'allele_delimiter'
),
$m
);
$m
= new Bio::PopGen::Genotype(
-alleles
=>\
@alleles
,
-marker_name
=>
$markername
,
-individual_id
=>
$self
->{
'_sam'
});
$i
++;
}
return
new Bio::PopGen::Individual(
-unique_id
=>
$self
->{
'_sam'
},
-genotypes
=>\@{
$self
->{
'_marker_results'
}},
);
}
else
{
chomp
;
$self
->{
'_header'
} = [
split
(
$self
->flag(
'field_delimiter'
),
$_
)];
return
$self
->next_individual;
}
return
;
}
sub
next_population{
my
(
$self
) =
@_
;
my
@inds
;
while
(
my
$ind
=
$self
->next_individual ) {
push
@inds
,
$ind
;
}
Bio::PopGen::Population->new(
-individuals
=> \
@inds
);
}
sub
write_individual {
my
(
$self
,
@inds
) =
@_
;
my
$fielddelim
=
$self
->flag(
'field_delimiter'
);
my
$alleledelim
=
$self
->flag(
'allele_delimiter'
);
foreach
my
$ind
(
@inds
) {
if
(!
ref
(
$ind
) || !
$ind
->isa(
'Bio::PopGen::IndividualI'
) ) {
$self
->
warn
(
"Cannot write an object that is not a Bio::PopGen::IndividualI object ($ind)"
);
next
;
}
my
@marker_names
=
sort
$ind
->get_marker_names;
if
( !
$self
->flag(
'no_header'
) &&
!
$self
->flag(
'header_written'
) ) {
$self
->_print(
join
(
$fielddelim
, (
'SAM'
,
@marker_names
)),
"\n"
);
$self
->flag(
'header_written'
,1);
}
my
(
@row1
,
@row2
);
for
(
@marker_names
){
my
$geno
=
$ind
->get_Genotypes(
-marker
=>
$_
);
my
@alleles
=
$geno
->get_Alleles();
push
(
@row1
,
$alleles
[0]);
push
(
@row2
,
$alleles
[1]);
}
$self
->_print(
"#"
,
$ind
->unique_id,
"\n"
,
join
(
$fielddelim
,
@row1
),
"\n"
,
join
(
$fielddelim
,
@row2
),
"\n"
);
}
}
sub
write_population {
my
(
$self
,
@pops
) =
@_
;
my
$fielddelim
=
$self
->flag(
'field_delimiter'
);
my
$alleledelim
=
$self
->flag(
'allele_delimiter'
);
foreach
my
$pop
(
@pops
) {
if
(!
ref
(
$pop
) || !
$pop
->isa(
'Bio::PopGen::PopulationI'
) ) {
$self
->
warn
(
"Cannot write an object that is not a Bio::PopGen::PopulationI object"
);
next
;
}
my
@marker_names
=
sort
$pop
->get_marker_names;
if
( !
$self
->flag(
'no_header'
) &&
!
$self
->flag(
'header_written'
) ) {
$self
->_print(
join
(
$fielddelim
, (
'SAM'
,
@marker_names
)),
"\n"
);
$self
->flag(
'header_written'
,1);
}
foreach
my
$ind
(
$pop
->get_Individuals ) {
my
(
@row1
,
@row2
);
for
(
@marker_names
){
my
$geno
=
$ind
->get_Genotypes(
-marker
=>
$_
);
my
@alleles
=
$geno
->get_Alleles();
push
(
@row1
,
$alleles
[0]);
push
(
@row2
,
$alleles
[1]);
}
$self
->_print(
"#"
,
$ind
->unique_id,
"\n"
,
join
(
$fielddelim
,
@row1
),
"\n"
,
join
(
$fielddelim
,
@row2
),
"\n"
);
}
}
}
1;