File Coverage

blib/lib/Petrophysics/Units.pm
Criterion Covered Total %
statement 48 56 85.7
branch 13 16 81.2
condition n/a
subroutine 23 26 88.4
pod 0 22 0.0
total 84 120 70.0


line stmt bran cond sub pod time code
1             package Petrophysics::Units;
2              
3             # The following POSC (c) products were used in the creation of this work:
4             # - epsgUnits.xml
5             # - poscUnits.xml
6             # These files can be downloaded from http://www.posc.org. Please see
7             # http://www.posc.org/ebiz/pefxml/patternsobjects.html#units
8             #
9             # Due to the POSC Product License Agreement, these files are not
10             # distributed in their original form. This derivative work converted
11             # those files to perl objects, and added unit conversion functionality
12             # to the objects.
13              
14             # This file is part of the "OSPetro" project. Please see
15             # http://OSPetro.sourceforge.net for further details.
16             #
17             # Copyright (C) 2003 Bjarne Steinsbo
18             #
19             # This library is free software; you can redistribute it and/or modify
20             # it under the same terms as Perl itself.
21             #
22             # The author can be contacted at "steinsbo@users.sourceforge.net"
23              
24 1     1   17508 use 5.006;
  1         4  
  1         50  
25 1     1   7 use strict;
  1         2  
  1         343  
26 1     1   7 use warnings;
  1         7  
  1         1269  
27              
28             require Exporter;
29              
30             our @ISA = qw(Exporter);
31              
32             # Nothing exported
33             our @EXPORT_OK = ();
34             our @EXPORT = ();
35             our $VERSION = '0.01';
36              
37             # Read pre-formatted units database to class variable "@objects".
38             our @objects;
39             require 'units_database.inc';
40             # printf STDERR "%d objects in file\n", scalar @objects;
41              
42             # Make a lookup table by id
43             our %by_id = map { $_->id => $_ } @objects;
44             # And a similar one by short name (annotation)
45             our %by_annotation = map { $_->annotation => $_ } @objects;
46              
47              
48             # Lookup a unit by id
49             sub lookup {
50 3     3 0 7296 my ($class, $id) = @_;
51 3         12 return $by_id{$id};
52             }
53              
54             # Lookup a unit by annotation. Please note that annotation is not
55             # guaranteed to be unique, so the result is an arbitrary unit with the
56             # given annotation
57             sub lookup_annotation {
58 2     2 0 49 my ($class, $annotation) = @_;
59 2         10 return $by_annotation{$annotation};
60             }
61              
62             # Generic search
63             sub grep {
64 0     0 0 0 my ($class, $expr) = @_;
65             # Shift to package main namespace
66             package main;
67 1     1   7 no strict 'refs';
  1         2  
  1         2921  
68 0         0 return grep (&$expr, @{"${class}::objects"});
  0         0  
69             }
70              
71             # Return entire list
72             sub all_units {
73 0     0 0 0 return \@objects;
74             }
75              
76             # Are two units compatible?
77             sub is_compatible {
78 11     11 0 86 my ($self, $other) = @_;
79 11 100       24 my $b1 = $self->is_base_unit ? $self->id : $self->base_unit->id;
80 11 100       29 my $b2 = $other->is_base_unit ? $other->id : $other->base_unit->id;
81 11         51 return $b1 eq $b2;
82             }
83              
84             # Convert to base unit
85             sub convert_to_base {
86 5     5 0 9 my ($self, $nr) = @_;
87 5 100       8 return $self->is_base_unit ? $nr : (
88             ($self->A + $self->B * $nr) / ($self->C + $self->D * $nr)
89             );
90             }
91              
92             # Convert from one unit to another. Just one scalar value converted.
93             sub scalar_convert {
94 6     6 0 40 my ($self, $other, $nr) = @_;
95 6 100       14 return undef unless $self->is_compatible ($other);
96 5         12 $nr = $self->convert_to_base ($nr);
97 5 100       13 return $other->is_base_unit ? $nr : (
98             ($other->C * $nr - $other->A) / ($other->B - $other->D * $nr)
99             );
100             }
101              
102             # Convert from one unit to another. Convert an array of values.
103             # The user is probably using the array version for performance reasons,
104             # so take some care to reduce number of method invocations.
105             sub vector_convert {
106 1     1 0 3 my ($self, $other, $vec) = @_;
107 1         3 my @out;
108 1 50       5 return undef unless $self->is_compatible ($other);
109 1 50       4 if ($self->is_base_unit) {
110 0         0 @out = @$vec;
111             } else {
112 1         5 my ($A, $B, $C, $D) = ($self->A, $self->B, $self->C, $self->D);
113 1         4 @out = map { ($A + $B * $_) / ($C + $D * $_) } @$vec;
  4         14  
114             }
115 1 50       4 unless ($other->is_base_unit) {
116 0         0 my ($A, $B, $C, $D) = ($other->A, $other->B, $other->C, $other->D);
117 0         0 $_ = ($C * $_ - $A) / ($B - $D * $_) foreach (@out);
118             }
119 1         139 return \@out;
120             }
121              
122             # Accessor routines
123 987     987 0 3811 sub id { shift->{id} };
124 2     2 0 11 sub name { shift->{name} };
125 967     967 0 4109 sub annotation { shift->{annotation} };
126 2     2 0 9 sub quantity_type { shift->{quantity_type} };
127 2     2 0 12 sub catalog_name { shift->{catalog_name} };
128 2     2 0 9 sub catalog_symbol { shift->{catalog_symbol} };
129 0     0 0 0 sub description { shift->{description} };
130 12     12 0 26 sub base_unit { shift->{base_unit} };
131 2     2 0 8 sub display { shift->{display} };
132 9     9 0 33 sub A { shift->{A} };
133 9     9 0 37 sub B { shift->{B} };
134 9     9 0 27 sub C { shift->{C} };
135 9     9 0 34 sub D { shift->{D} };
136 36     36 0 162 sub is_base_unit { exists shift->{is_base} };
137              
138             1;
139             __END__