MS
view release on metacpan or search on metacpan
lib/MS/Reader/MzXML/Spectrum.pm view on Meta::CPAN
sub _post_load {
my ($self) = @_;
# Nested scans don't work with the current infrastructure (plus we never
# use this format). Could be supported in future if there was demand.
croak "Nested scans in mzXML not currently supported!"
if (exists $self->{scan}->{scan});
}
sub ms_level {
my ($self) = @_;
croak "Invalid mzXML (missing msLevel property)"
if (! defined $self->{msLevel});
return $self->{msLevel};
}
sub rt {
my ($self) = @_;
return undef if (! defined $self->{retentionTime});
if ($self->{retentionTime} =~ /^PT(?:([\d\.]+)M)?(?:([\d\.]+)S)?/) {
my $s = 0;
$s += $1*60 if (defined $1);
$s += $2 if (defined $2);
return $s;
}
croak "Unexpected retention time format: $self->{retentionTime}";
}
sub scan_number {
my ($self) = @_;
croak "Invalid mzXML (missing scan number property)"
if (! defined $self->{num});
return $self->{num};
}
sub precursor {
my ($self) = @_;
croak "precursor() only valid for MS2 spectra"
if ($self->{msLevel} < 2);
croak "precursor() only valid for single precursor spectra, use direct access.\n"
if (scalar @{$self->{precursorMz}} != 1);
my $pre = $self->{precursorMz}->[0];
my $id = $pre->{precursorScanNum};
my $mono_mz = $pre->{pcdata};
my $iso_mz = $mono_mz;
my $iso_lower = $iso_mz - $pre->{windowWideness}/2;
my $iso_upper = $iso_mz + $pre->{windowWideness}/2;
my $charge = $pre->{precursorCharge};
my $int = $pre->{precursorIntensity};
croak "missing monoisotopic m/z" if (! defined $mono_mz);
return {
scan_id => $id,
iso_mz => $iso_mz,
iso_lower => $iso_lower,
iso_upper => $iso_upper,
mono_mz => $mono_mz,
charge => $charge,
intensity => $int,
};
}
sub mz {
my ($self) = @_;
return $self->{__mz} if (exists $self->{__mz});
if (defined $self->{peaks}->{'m/z'}) {
$self->{__mz} = $self->get_array('m/z');
}
elsif (defined $self->{peaks}->{'m/z-int'}) {
my $v = $self->get_array('m/z-int');
my $l = scalar(@$v)/2;
croak "Odd-numbered m/z-int array" if ( ($l%2) != 0);
$self->{__mz} = [ map {$v->[$_]} map {$_*2} (0..$l-1) ];
$self->{__int} = [ map {$v->[$_]} map {$_*2+1} (0..$l-1) ];
}
else {
croak "m/z array undefined";
}
return $self->{__mz};
}
sub int {
my ($self) = @_;
return $self->{__int} if (exists $self->{__int});
if (defined $self->{peaks}->{'intensity'}) {
$self->{__int} = $self->get_array('intensity');
}
elsif (defined $self->{peaks}->{'m/z-int'}) {
my $v = $self->get_array('m/z-int');
my $l = scalar(@$v)/2;
croak "Odd-numbered m/z-int array" if ( ($l%2) != 0);
$self->{__mz} = [ map {$v->[$_]} map {$_*2} (0..$l-1) ];
$self->{__int} = [ map {$v->[$_]} map {$_*2+1} (0..$l-1) ];
}
else {
croak "intensity array undefined";
}
return $self->{__int};
}
sub get_array {
my ($self, $type) = @_;
my $ref = $self->{peaks}->{$type};
croak "Undefined array type $type" if (! defined $ref);
my $data = decode_base64( $ref->{pcdata} );
$data = uncompress($data) if ($ref->{compressionType} eq 'zlib');
my $code = $ref->{precision} eq '64' ? 'd>' : 'f>';
return [ unpack "$code*", $data ];
}
sub scan_window {
my ($self) = @_;
my $l = $self->{startMz} // $self->{lowMz};
my $r = $self->{endMZ} // $self->{highMz};
return undef if (! defined $l || ! defined $r);
return [$l, $r];
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
MS::Reader::MzXML::Spectrum - An MzXML spectrum object
=head1 SYNOPSIS
use MS::Reader::MzXML;
my $run = MS::Reader::MzXML->new('run.mzXML');
while (my $spectrum = $run->next_spectrum) {
# Note that these two methods are functionally identical
my $id = $spectrum->id;
my $scan_num = $spectrum->scan_number;
my $rt = $spectrum->rt;
my $mz = $spectrum->mz;
my $int = $spectrum->int;
my $lvl = $spectrum->ms_level;
# $spectrum inherits from MS::Reader::MzML::Record, so you can do:
my $tc = $spectrum->param(MS_TOTAL_ION_CURRENT);
my $sn = $spectrum->get_array(MS_CHARGE_ARRAY); # if present
# in addition,
my $z = $spectrum->get_array('charge'); # if present
my $precursor = $spectrum->precursor;
my $pre_mz = $precursor->{mono_mz};
my $pre_mz = $precursor->{mono_mz};
# or access the guts directly (yes, it's okay!)
my $current = $spectrum->{totIonCurrent};
( run in 0.988 second using v1.01-cache-2.11-cpan-39bf76dae61 )