The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 07
META.yml 22
Makefile.PL 22
lib/Bio/MAGETAB/Types.pm 34
lib/Bio/MAGETAB/Util/Reader/SDRF.pm 3546
lib/Bio/MAGETAB.pm 22
t/013_sdrf.t 39
t/examples/affy_sdrf.txt 55
8 files changed (This is a version diff) 5277
@@ -1,6 +1,13 @@
 Changelog for Bio::MAGETAB
 --------------------------
 
+1.31    Bio::MAGETAB-1.31.tar.gz        Replacing the old DateTime::Format::DateManip module
+                                          with DateTime::Format::Flexible, which appears to be
+                                          maintained more responsively.
+
+1.30    Bio::MAGETAB-1.30.tar.gz        Fix for FactorValue and Characteristics Measurement bug
+                                          (https://rt.cpan.org/Public/Bug/Display.html?id=94398).
+
 1.28    Bio::MAGETAB-1.28.tar.gz        Minor bug fixes for assorted test case failures;
                                           no substantive changes in code behaviour.
 
@@ -29,7 +29,7 @@ recommends:
 requires:
   Date::Manip: 5.44
   DateTime: 0.4302
-  DateTime::Format::DateManip: 0.04
+  DateTime::Format::Flexible: 0.21
   Email::Valid: 0.179
   Moose: 0.43
   MooseX::FollowPBP: 0.04
@@ -41,4 +41,4 @@ requires:
   perl: 5.8.1
 resources:
   license: http://opensource.org/licenses/gpl-license.php
-version: 1.28
+version: 1.31
@@ -17,7 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with Bio::MAGETAB.  If not, see <http://www.gnu.org/licenses/>.
 #
-# $Id: Makefile.PL 366 2011-07-17 10:52:45Z tfrayner $
+# $Id: Makefile.PL 386 2014-04-11 14:54:54Z tfrayner $
 
 use strict;
 use warnings;
@@ -33,7 +33,7 @@ requires 'Params::Coerce'              => '0.14';
 requires 'URI'                         => '1.35';
 requires 'Date::Manip'                 => '5.44';
 requires 'DateTime'                    => '0.4302';
-requires 'DateTime::Format::DateManip' => '0.04';
+requires 'DateTime::Format::Flexible'  => '0.21';
 requires 'Email::Valid'                => '0.179';
 requires 'Parse::RecDescent'           => '1.965001';
 requires 'Text::CSV_XS'                => '0.32';
@@ -15,7 +15,7 @@
 # You should have received a copy of the GNU General Public License
 # along with Bio::MAGETAB.  If not, see <http://www.gnu.org/licenses/>.
 #
-# $Id: Types.pm 359 2011-04-15 13:14:26Z tfrayner $
+# $Id: Types.pm 386 2014-04-11 14:54:54Z tfrayner $
 
 use strict;
 use warnings;
@@ -84,8 +84,9 @@ coerce Date,
 
     from Str,
     via {
-        require DateTime::Format::DateManip;
-        DateTime::Format::DateManip->parse_datetime($_)
+        require DateTime::Format::Flexible;
+        my $parser = DateTime::Format::Flexible->new();
+        $parser->parse_datetime($_)
             or croak(qq{Cannot parse date format "$_"; try YYYY-MM-DD});
     };
 
@@ -15,7 +15,7 @@
 # You should have received a copy of the GNU General Public License
 # along with Bio::MAGETAB.  If not, see <http://www.gnu.org/licenses/>.
 #
-# $Id: SDRF.pm 375 2012-10-11 10:11:13Z tfrayner $
+# $Id: SDRF.pm 385 2014-04-08 09:28:43Z tfrayner $
 
 package Bio::MAGETAB::Util::Reader::SDRF;
 
@@ -444,21 +444,17 @@ sub _create_characteristic_value {
     return $term;
 }
 
-sub _create_characteristic_measurement {
+sub _create_characteristic_measurementhash {
 
     my ( $self, $type, $value, $material ) = @_;
 
     return if ( ! $material || ! defined $value || $value =~ $BLANK );
 
-    my $measurement = $self->get_builder()->find_or_create_measurement({
+    return {
         measurementType  => $type,
         value            => $value,
         object           => $material,
-    });
-    
-    $self->_add_characteristic_to_material( $measurement, $material ) if $material;
-
-    return $measurement;
+    };
 }
 
 sub _create_material_type {
@@ -1110,21 +1106,21 @@ sub _create_factorvalue_value {
     return $factorvalue;
 }
 
-sub _create_factorvalue_measurement {
+sub _create_factorvalue_measurementhash {
 
-    my ( $self, $factorname, $altcategory, $value ) = @_;
+    my ( $self, $factorname, $value, $altcategory ) = @_;
 
     return if ( ! defined $value || $value =~ $BLANK );
 
-    my $exp_factor = $self->get_builder()->get_factor({
+    my $exp_factor  = $self->get_builder()->get_factor({
         name => $factorname,
     });
 
     my $category;
     if ( $altcategory ) {
 
-	# If we're given a category in parentheses, use it.
-	$category = $altcategory;
+        # If we're given a category in parentheses, use it.
+        $category = $altcategory;
     }
     else {
 
@@ -1132,23 +1128,31 @@ sub _create_factorvalue_measurement {
         $category = $self->_get_fv_category_from_factor( $exp_factor );
     }
 
-    # Note that this isn't quite perfect; identical measurements will
-    # be mapped to the same object so altering values post-creation
-    # will alter all of the matching values. I think this is
-    # unintuitive (although similar to controlled term processing) so FIXME.
-    my $measurement = $self->get_builder()->find_or_create_measurement({
+    return {
         measurementType  => $category,
         value            => $value,
+    };
+}
+
+sub _create_factorvalue_measurement {
+
+    my ( $self, $meashash, $factorname ) = @_;
+
+    return if ( ! defined $meashash );
+
+    my $exp_factor  = $self->get_builder()->get_factor({
+        name => $factorname,
     });
 
-    my $factorvalue = $self->get_builder()->find_or_create_factor_value({
+    my $fvmeas = $self->get_builder->find_or_create_measurement($meashash);
+
+    my $fv = $self->get_builder()->find_or_create_factor_value({
         factor      => $exp_factor,
-        measurement => $measurement,
+        measurement => $fvmeas,
     });
+    $self->get_builder()->update( $fv );
 
-    $self->get_builder()->update( $factorvalue );
-
-    return $factorvalue;
+    return $fv;
 }
 
 sub _add_comment_to_thing {
@@ -1527,14 +1531,21 @@ __DATA__
                                          my $material = shift;
 
                                          # Add a measurement with unit to the material.
-                                         my $char = $::sdrf->_create_characteristic_measurement(
+                                         my $charhash = $::sdrf->_create_characteristic_measurementhash(
                                              $item[3], shift, $material,
                                          );
 
-                                         unshift( @_, $char );
+                                         unshift(@_, $charhash);
                                          my $unit = &{ $item[5] };
 
-                                         return $char;
+                                         if ( defined $charhash ) {
+                                             my $char = $::sdrf->get_builder->find_or_create_measurement($charhash);
+                                             $::sdrf->_add_characteristic_to_material($char, $material);
+                                             return $char;
+                                         }
+                                         else {
+                                             return;
+                                         }
                                      };
                                    }
 
@@ -1587,17 +1598,17 @@ __DATA__
                                          # Value
                                          my $value = shift;
 
-                                         # Attach the unit to the measurement.
-                                         my $fv = $::sdrf->_create_factorvalue_measurement(
-                                             $item[3],
-                                             $item[4][0],
-                                             $value,
-                                         );
+                                         my $meashash = $::sdrf->_create_factorvalue_measurementhash( $item[3], $value, $item[4][0]  );
 
-                                         unshift( @_, $fv );
+                                         # Attach the unit to the measurement.
+                                         unshift(@_, $meashash);
                                          my $unit = &{ $item[6] };
-
-                                         return $fv;
+                                         if ( defined $meashash ) {
+                                             return $::sdrf->_create_factorvalue_measurement($meashash, $item[3]);
+                                         }
+                                         else {
+                                             return;
+                                         }
                                      };
                                    }
 
@@ -15,7 +15,7 @@
 # You should have received a copy of the GNU General Public License
 # along with Bio::MAGETAB.  If not, see <http://www.gnu.org/licenses/>.
 #
-# $Id: MAGETAB.pm 383 2013-11-26 11:07:05Z tfrayner $
+# $Id: MAGETAB.pm 386 2014-04-11 14:54:54Z tfrayner $
 
 # Convenience class for module loading and object tracking.
 package Bio::MAGETAB;
@@ -31,7 +31,7 @@ use List::Util qw(first);
 
 use MooseX::Types::Moose qw( HashRef );
 
-our $VERSION = 1.28;
+our $VERSION = 1.31;
 
 # This cache is used to store all the Bio::MAGETAB objects registered
 # with this instance (which, by default, is all of them).
@@ -17,7 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with Bio::MAGETAB.  If not, see <http://www.gnu.org/licenses/>.
 #
-# $Id: 013_sdrf.t 375 2012-10-11 10:11:13Z tfrayner $
+# $Id: 013_sdrf.t 384 2014-04-04 16:15:47Z tfrayner $
 
 use strict;
 use warnings;
@@ -88,7 +88,13 @@ lives_ok( sub { $sdrf = test_parse( $sdrf_reader ) }, 'parsing completes without
 
 # Check that FV->measurement creation is behaving more or less correctly.
 my @fvs = grep { $_->get_factor()->get_name() eq 'EF2' } $sdrf->get_ClassContainer->get_factorValues();
-is( scalar @fvs, 2, 'recognising the correct number of Measurement FVs');
+is( scalar @fvs, 3, 'recognising the correct number of Measurement FVs');
+
+my @fv_vals = sort map { int($_->get_measurement()->get_value()) } @fvs;
+is_deeply(\@fv_vals, [0, 10, 10],  'with the correct values');
+
+my @fv_units = sort map { $_->get_measurement()->get_unit()->get_value() } @fvs;
+is_deeply(\@fv_units, ['mM', 'mg_per_mL', 'mg_per_mL'],  'and the correct units');
 
 # Test parsing into a supplied magetab_object.
 use Bio::MAGETAB::SDRF;
@@ -163,6 +169,6 @@ __DATA__
 Source Name	Provider	Characteristics[ OrganismPart ]	Characteristics[DiseaseState]	Term Source REF:test namespace	Term Accession Number	Material Type	Description	Comment[MyNVT]	Sample Name	Characteristics[Age]	Unit[TimeUnit]	Term Source REF	Material Type	Comment[sample comment]	Protocol REF	Performer	Parameter Value[Extracted Product]	Date	Comment[P_COMM]	Extract Name	Material Type	LabeledExtract Name	MaterialType	Term Source REF	Label	Term Source REF	Protocol REF	Term Source REF	Hybridization Name	Comment[some comment about the hyb]	Array Design REF	Comment[some comment about the array]	Protocol REF:made-up namespace:	Scan Name	Image File	Comment [scan comment here]	Array Data File	Comment[raw data comment]	Protocol REF	Normalization Name	Comment[data smoothness]	Derived Array Data File	Factor Value [EF1](Prognosis)	Term Source REF	Term Accession Number	Factor Value [EF2]	Unit[ConcentrationUnit]	Term Source REF
 my source	the guy in the next room	root	hemophilia	NCI META	CL:111111	organism_part	description_text	mycomment	my sample	6	hours	MO	cell	sample comment value	EXTPRTCL10654	the guy in the next room	total RNA	2007-02-21	This did not happen. I was not here.	my extract	not_a_MO_term	my LE1	total_RNA	MO	Cy3	MO	P-XMPL-7	ArrayExpress	my hybridization	hyb conditions were suboptimal	A-TEST-1	My favourite array design	scanning protocol	my scan	imagefile1.TIFF	this was a great picture	Data1.txt		TRANPRTCL10656	my norm	high	NormData1.txt	ill	NCI META	CL:0123345	10	mg_per_mL	MO
 my source	the guy in the next room	root	hemophilia	NCI META	CL:111111	organism_part	description_text	mycomment	my sample	6	hours	MO	cell	sample comment value	EXTPRTCL10654	the guy in the next room	total RNA	2007-02-21	This did not happen. I was not here.	my extract	not_a_MO_term	my LE2	total_RNA	MO	Cy5	MO	P-XMPL-7	ArrayExpress	my hybridization	hyb conditions were suboptimal	A-TEST-1	My favourite array design	scanning protocol	my scan	imagefile1.TIFF	this was a great picture	Data2.txt	not as good as the picture	TRANPRTCL10656	my norm	low	NormData2.txt	healthy	NCI META	CL:2347689	0	mg_per_mL	MO
-sparse source 1			normal		blah blah ignore me										EXTPRTCL10654		polyA RNA					sparse LE Cy5			Cy5		P-XMPL-11	ArrayExpress	sparse hyb		A-TEST-1			sparse scan1	testing.jpg		Data3.txt		TRANPRTCL10656	norm 3		NormData3.txt	pained expression					
+sparse source 1			normal		blah blah ignore me										EXTPRTCL10654		polyA RNA					sparse LE Cy5			Cy5		P-XMPL-11	ArrayExpress	sparse hyb		A-TEST-1			sparse scan1	testing.jpg		Data3.txt		TRANPRTCL10656	norm 3		NormData3.txt	pained expression			10	mM	MO
 sparse source 2			normal												EXTPRTCL10654		polyA RNA					sparse LE Cy3			Cy3		P-XMPL-11	ArrayExpress	sparse hyb		A-TEST-1			sparse scan2			Data4.txt		TRANPRTCL10656	norm 3		NormData3.txt	pregnant pause					
 sparse source 3			normal												EXTPRTCL10654		polyA RNA					sparse LE biotin			biotin		P-XMPL-11	ArrayExpress	sparse hyb b		A-TEST-1		scanning protocol	sparse scan3	imagefile2.TIFF	a bit blurry			TRANPRTCL10656	norm 4		NormData4.txt	preternatural calm					
@@ -1,5 +1,5 @@
-"Source Name"	"Material Type"	"Term Source REF"	"Characteristics [Genotype]"	"Characteristics[Organism]"	"Term Source REF"	"Characteristics[BioSourceType]"	"Term Source REF"	"Characteristics[CellType]"	"Term Source REF"	"Characteristics[CellLine]"	"Protocol REF"	"Parameter Value [media]"	"Sample Name"	"Protocol REF"	"Parameter Value [Input RNA]"	"Unit [MassUnit]"	"Term Source REF"	"Parameter Value [Extracted Product]"	"Term Source REF"	"Parameter Value [Amplification]"	"Extract Name"	"Protocol REF"	"Term Source REF"	"Labeled Extract Name"	"Label"	"Protocol REF:Affymetrix:Protocol:"	"Hybridization Name"	"Array Design REF"	"Term Source REF"	"Protocol REF:Affymetrix:Protocol:"	"Scan Name"	"Array Data File"	"Comment[EXP]"	"Protocol REF"	"Normalization Name"	"Derived Array Data File"	"Factor Value [EF1](genotype)"	"Normalization Name"	"Derived Array Data Matrix File"	"Comment[CDF]"
-"TK6 replicate 1"	"cell"	"MO"	"wild_type"	"Homo sapiens"	"ncbitax"	"fresh_sample"	"MO"	"B_lymphoblast"	"CTO"	"TK6"	"GROWTHPRTCL10653"	"RPMI 1640 medium supplemented with 10% horse serum"	"TK6 replicate 1"	"EXTPRTCL10654"	5	"ug"	"MO"	"total RNA"	"MO"	"none"	"TK6 replicate 1"	"P-AFFY-2"	"ArrayExpress"	"TK6 replicate 1"	"biotin"		"H_TK6 replicate 1"	"A-AFFY-44"	"ArrayExpress"		"TK6 replicate 1"	"Data1.CEL"	"Data1.EXP"		"TK6 replicate 1"	"Data1.CHP"	"wild_type"	"combined data"	"affy_dm.txt"	"HG-U133A_Plus_2.CDF"
-"TK6 replicate 2"	"cell"	"MO"	"wild_type"	"Homo sapiens"	"ncbitax"	"fresh_sample"	"MO"	"B_lymphoblast"	"CTO"	"TK6"	"GROWTHPRTCL10653"	"RPMI 1640 medium supplemented with 10% horse serum"	"TK6 replicate 2"	"EXTPRTCL10654"	5	"ug"	"MO"	"total RNA"	"MO"	"none"	"TK6 replicate 2"	"P-AFFY-2"	"ArrayExpress"	"TK6 replicate 2"	"biotin"		"H_TK6 replicate 2"	"A-AFFY-44"	"ArrayExpress"		"TK6 replicate 2"	"Data2.CEL"	"Data2.EXP"		"TK6 replicate 2"	"Data2.CHP"	"wild_type"	"combined data"	"affy_dm.txt"	"HG-U133A_Plus_2.CDF"
-"TK6MDR1 replicate 1"	"cell"	"MO"	"SF91m3 oncoretrovirus"	"Homo sapiens"	"ncbitax"	"fresh_sample"	"MO"	"B_lymphoblast"	"CTO"	"TK6"	"GROWTHPRTCL10653"	"RPMI 1640 medium supplemented with 10% horse serum"	"TK6MDR1 replicate 1"	"EXTPRTCL10654"	5	"ug"	"MO"	"total RNA"	"MO"	"none"	"TK6MDR1 replicate 1"	"P-AFFY-2"	"ArrayExpress"	"TK6MDR1 replicate 1"	"biotin"	"Hybridization-EukGE-WS2v5"	"H_TK6MDR1 replicate 1"	"A-AFFY-44"	"ArrayExpress"	"Scan"	"TK6MDR1 replicate 1"	"Data3.CEL"	"Data3.EXP"	"TRANPRTCL10656"	"TK6MDR1 replicate 1"	"Data3.CHP"	"SF91m3 oncoretrovirus"	"combined data"	"affy_dm.txt"	"HG-U133A_Plus_2.CDF"
-"TK6MDR1 replicate 2"	"cell"	"MO"	"SF91m3 oncoretrovirus"	"Homo sapiens"	"ncbitax"	"fresh_sample"	"MO"	"B_lymphoblast"	"CTO"	"TK6"	"GROWTHPRTCL10653"	"RPMI 1640 medium supplemented with 10% horse serum"	"TK6MDR1 replicate 2"	"EXTPRTCL10654"	5	"ug"	"MO"	"total RNA"	"MO"	"none"	"TK6MDR1 replicate 2"	"P-AFFY-2"	"ArrayExpress"	"TK6MDR1 replicate 2"	"biotin"	"Hybridization-EukGE-WS2v5"	"H_TK6MDR1 replicate 2"	"A-AFFY-44"	"ArrayExpress"	"Scan"	"TK6MDR1 replicate 2"	"Data4.CEL"	"Data4.EXP"	"TRANPRTCL10656"	"TK6MDR1 replicate 2"	"Data4.CHP"	"SF91m3 oncoretrovirus"	"combined data"	"affy_dm.txt"	"HG-U133A_Plus_2.CDF"
+Source Name	Material Type	Term Source REF	Characteristics [Genotype]	Characteristics[Organism]	Term Source REF	Characteristics[BioSourceType]	Term Source REF	Characteristics[CellType]	Term Source REF	Characteristics[CellLine]	Protocol REF	Parameter Value [media]	Sample Name	Protocol REF	Parameter Value [Input RNA]	Unit [MassUnit]	Term Source REF	Parameter Value [Extracted Product]	Term Source REF	Parameter Value [Amplification]	Extract Name	Protocol REF	Term Source REF	Labeled Extract Name	Label	Protocol REF:Affymetrix:Protocol:	Hybridization Name	Array Design REF	Term Source REF	Protocol REF:Affymetrix:Protocol:	Scan Name	Array Data File	Comment[EXP]	Protocol REF	Normalization Name	Derived Array Data File	Factor Value [EF1](genotype)	Normalization Name	Derived Array Data Matrix File	Comment[CDF]
+TK6 replicate 1	cell	MO	wild_type	Homo sapiens	ncbitax	fresh_sample	MO	B_lymphoblast	CTO	TK6	GROWTHPRTCL10653	RPMI 1640 medium supplemented with 10% horse serum	TK6 replicate 1	EXTPRTCL10654	5	ug	MO	total RNA	MO	none	TK6 replicate 1	P-AFFY-2	ArrayExpress	TK6 replicate 1	biotin		H_TK6 replicate 1	A-AFFY-44	ArrayExpress		TK6 replicate 1	Data1.CEL	Data1.EXP		TK6 replicate 1	Data1.CHP	wild_type	combined data	affy_dm.txt	HG-U133A_Plus_2.CDF
+TK6 replicate 2	cell	MO	wild_type	Homo sapiens	ncbitax	fresh_sample	MO	B_lymphoblast	CTO	TK6	GROWTHPRTCL10653	RPMI 1640 medium supplemented with 10% horse serum	TK6 replicate 2	EXTPRTCL10654	5	ug	MO	total RNA	MO	none	TK6 replicate 2	P-AFFY-2	ArrayExpress	TK6 replicate 2	biotin		H_TK6 replicate 2	A-AFFY-44	ArrayExpress		TK6 replicate 2	Data2.CEL	Data2.EXP		TK6 replicate 2	Data2.CHP	wild_type	combined data	affy_dm.txt	HG-U133A_Plus_2.CDF
+TK6MDR1 replicate 1	cell	MO	SF91m3 oncoretrovirus	Homo sapiens	ncbitax	fresh_sample	MO	B_lymphoblast	CTO	TK6	GROWTHPRTCL10653	RPMI 1640 medium supplemented with 10% horse serum	TK6MDR1 replicate 1	EXTPRTCL10654	5	mg	MO	total RNA	MO	none	TK6MDR1 replicate 1	P-AFFY-2	ArrayExpress	TK6MDR1 replicate 1	biotin	Hybridization-EukGE-WS2v5	H_TK6MDR1 replicate 1	A-AFFY-44	ArrayExpress	Scan	TK6MDR1 replicate 1	Data3.CEL	Data3.EXP	TRANPRTCL10656	TK6MDR1 replicate 1	Data3.CHP	SF91m3 oncoretrovirus	combined data	affy_dm.txt	HG-U133A_Plus_2.CDF
+TK6MDR1 replicate 2	cell	MO	SF91m3 oncoretrovirus	Homo sapiens	ncbitax	fresh_sample	MO	B_lymphoblast	CTO	TK6	GROWTHPRTCL10653	RPMI 1640 medium supplemented with 10% horse serum	TK6MDR1 replicate 2	EXTPRTCL10654	5	mg	MO	total RNA	MO	none	TK6MDR1 replicate 2	P-AFFY-2	ArrayExpress	TK6MDR1 replicate 2	biotin	Hybridization-EukGE-WS2v5	H_TK6MDR1 replicate 2	A-AFFY-44	ArrayExpress	Scan	TK6MDR1 replicate 2	Data4.CEL	Data4.EXP	TRANPRTCL10656	TK6MDR1 replicate 2	Data4.CHP	SF91m3 oncoretrovirus	combined data	affy_dm.txt	HG-U133A_Plus_2.CDF