IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 14013


Ignore:
Timestamp:
Jul 4, 2007, 1:57:12 PM (19 years ago)
Author:
eugene
Message:

complete rework of this function : does not require information about the data being examined

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/PS-IPP-Config/lib/PS/IPP/Metadata/Stats.pm

    r13977 r14013  
    11# Copyright (c) 2006  Paul Price, Joshua Hoblitt
    22#
    3 # $Id: Stats.pm,v 1.17 2007-06-26 01:39:16 eugene Exp $
     3# $Id: Stats.pm,v 1.18 2007-07-04 23:57:12 eugene Exp $
    44
    55package PS::IPP::Metadata::Stats;
     
    2424
    2525use base qw( Class::Accessor::Fast );
    26 __PACKAGE__->mk_accessors( qw( bg_mean
    27                                bg_stdev
    28                                bg_mean_stdev
    29                                fringe_mean
    30                                fringe_mean_stdev
    31                                fringe_err
    32                                dfringe_mean
    33                                dfringe_mean_stdev
    34                                dfringe_err
    35                                constants
    36                                variables
     26__PACKAGE__->mk_accessors( qw(
     27                               results
    3728                               ) );
    3829
     
    4233
    4334sub new {
    44     my $class = shift;                # Class name
    45     my $constants = shift;        # Array of values that should be constant through the FPA
    46     my $variables = shift;        # Array of values that may be variable through the FPA
    47 
    48     my $self = { bg_mean => undef,        # Mean of the mean backgrounds
    49                  bg_stdev => undef,       # Standard deviation of the mean backgrounds
    50                  bg_mean_stdev => undef,  # Mean of the standard deviation of the backgrounds
    51                  fringe_mean => [],       # Fringe amplitudes
    52                  fringe_err => [],        # Fringe amplitude errors
    53                  fringe_mean_stdev => [], # Fringe amplitude stdev
    54                  dfringe_mean => [],      # Fringe residual amplitudes
    55                  dfringe_err => [],       # Fringe residual amplitude errors
    56                  dfringe_mean_stdev => [], # Fringe residual amplitude stdev
    57                  constants => $constants, # Array of values that should be constant through the FPA
    58                  variables => $variables, # Array of values that may be variable through the FPA
    59                  bg_data => [],           # Array of background values
    60                  bg_stdev_data => [],     # Array of background standard deviations
    61                  fringe_data => [],       # Fringe amplitudes each component
    62                  fringe_err_data => [],   # Fringe errors for each component
    63                  dfringe_data => [],      # Fringe residual amplitudes each component
    64                  dfringe_err_data => [],  # Fringe residual errors for each component
    65                  data => {}               # The data
    66              };
     35    my $class = shift;          # Class name
     36    my $entries = shift;        # Array of values to extract
     37
     38    my $self = {
     39        entries => $entries, # Array of values that should be constant through the FPA
     40        data => {}              # The data
     41    };
    6742   
    68     # Populate object
    69     foreach my $constant (@$constants) {
    70         $self->{data}->{$constant} = { type => 'constant', # Type of value (constant/variable)
    71                                        value => undef # The actual variable
    72                                        };
    73     }
    74     foreach my $variable (@$variables) {
    75         $self->{data}->{$variable} = { type => 'variable', # Type of value (constant/variable)
    76                                        data => [], # Array of data values
    77                                        mean => undef, # Mean of data values
    78                                        stdev => undef # Standard deviation of data values
    79                                        };
     43    # add a hash for storage
     44    foreach my $entry (@$entries) {
     45        $entry->{data} = [];
    8046    }
    8147
     
    9056    my $md = shift;                # Parsed metadata, from PS::IPP::Metadata::Config
    9157
    92     # count of parse errors
    93     my $errors = 0;
    94 
    95     # $self->_parse_megacam($md);
    96     $self->_parse_braindead($md);
    97 
    98     # Check that we found everything for the constants
    99     my $constants = $self->constants();        # Array of constants
    100     if (defined $constants) {
    101         foreach my $constant (@$constants) {
    102             if (not defined $self->{data}->{$constant}->{value}) {
    103                 carp "Unable to find value for ", $constant, "\n";
    104                 $errors++;
    105             }
    106         }
     58    $self->_parse_metadata_stats($md);
     59
     60    # apply the needed calculation to the data based on the type
     61
     62    my $entries = $self->{entries};
     63
     64    foreach my $entry (@$entries) {
     65        my $type = $entry->{type};
     66        my $data = $entry->{data};
     67       
     68        if ($type eq "constant") {
     69            if (not defined $entry->{value}) {
     70                $entry->{value} = 'NAN';
     71            }
     72            next;
     73        }
     74
     75        if ($type eq "mean") {
     76            if (scalar @$data > 0) {
     77                # Get statistics on the value
     78                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     79                $stats->add_data(@$data);
     80                $entry->{value} = $stats->mean();
     81            } else {
     82                $entry->{value} = 'NAN';
     83            }
     84            next;
     85        }
     86
     87        if ($type eq "stdev") {
     88            if (scalar @$data > 1) {
     89                # Get statistics on the value
     90                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     91                $stats->add_data(@$data);
     92                $entry->{value} = $stats->stdev();
     93                next;
     94            }
     95            if (scalar @$data == 1) {
     96                $entry->{value} = 0.0;
     97                next;
     98            }
     99            $entry->{value} = 'NAN';
     100            next;
     101        }
     102
     103        if ($type eq "rms") {
     104            if (scalar @$data > 0) {
     105                # Get statistics on the value
     106                # for rmsStats, we pushed the value^2 on the data array
     107                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     108                $stats->add_data(@$data);
     109                $entry->{value} = sqrt($stats->mean());
     110            } else {
     111                $entry->{value} = 'NAN';
     112            }
     113        }
     114
     115        if ($type eq "sum") {
     116            if (scalar @$data > 0) {
     117                # Get statistics on the value
     118                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     119                $stats->add_data(@$data);
     120                $entry->{value} = $stats->sum();
     121            } else {
     122                $entry->{value} = 'NAN';
     123            }
     124        }
    107125    }
    108126
    109     # Get mean, stdev for the variables
    110     my $variables = $self->variables();        # Array of variables
    111     if (defined $variables) {
    112         foreach my $variable (@$variables) {
    113             my $info = $self->{data}->{$variable}; # The information about this particular variable
    114             my $array = $info->{data}; # The array of values collected
    115             if (scalar @$array == 0) {
    116                 carp "Unable to find any values for ", $variable, "\n";
    117                 $errors++;
    118                 next;
    119             }
    120 
    121             # Get statistics on the value
    122             my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    123             $stats->add_data(@$array);
    124             $info->{mean} = $stats->mean();
    125             $info->{stdev} = $stats->standard_deviation();
    126         }
    127     }
    128    
    129     # Get mean, stdev, mean stdev for the background
    130     if (scalar @{$self->{bg_data}} > 0) {
    131         my $stats = Statistics::Descriptive::Sparse->new(); # Statistics for mean
    132         $stats->add_data(@{$self->{bg_data}});
    133         $self->bg_mean($stats->mean());
    134         $self->bg_mean_stdev($stats->standard_deviation() || 0);
    135         print STDERR "mean_stdev: " . $self->bg_mean_stdev() . "\n";
    136         # the stdev of a set of 1 is undefined.  that doesn't do
    137         # us much good so I'm changing undef to 0
    138     } else {
    139         # if we have no data to measure the value, return NAN
    140         $self->bg_mean('NAN');
    141         $self->bg_mean_stdev('NAN');
    142     }
    143     if (scalar @{$self->{bg_stdev_data}} > 0) {
    144         my $stats = Statistics::Descriptive::Sparse->new(); # Statistics for standard deviation
    145         my @variances;
    146         foreach my $number (@{$self->{bg_stdev_data}}) {
    147             push @variances, $number**2;
    148         }
    149         $stats->add_data(@variances);
    150         $self->bg_stdev( sqrt( $stats->mean() ) );
    151     } else {
    152         $self->bg_stdev('NAN');
    153     }
    154 
    155     # Get fringe measurements
    156     if (scalar @{$self->{fringe_data}} > 0) {
    157         foreach my $array (@{$self->{fringe_data}}) {
    158             my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    159             $stats->add_data(@$array);
    160             push @{$self->{fringe_mean}}, $stats->mean();
    161             push @{$self->{fringe_mean_stdev}}, ($stats->standard_deviation() || 0);
    162             # the stdev of a set of 1 is undefined.  that doesn't do
    163             # us much good so I'm changing undef to 0
    164         }
    165     } else {
    166         # create a single NAN entry
    167         push @{$self->{fringe_mean}}, 'NAN';
    168         push @{$self->{fringe_mean_stdev}}, 'NAN';
    169     }
    170     if (scalar @{$self->{fringe_err_data}} > 0) {
    171         foreach my $array (@{$self->{fringe_err_data}}) {
    172             my @variances;
    173             foreach my $value (@$array) {
    174                 push @variances, $value**2;
    175             }
    176             my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    177             $stats->add_data(@variances);
    178             push @{$self->{fringe_err}}, sqrt($stats->mean());
    179         }
    180     } else {
    181         push @{$self->{fringe_err}}, 'NAN';
    182     }
    183 
    184     # Get fringe residual measurements
    185     if (scalar @{$self->{dfringe_data}} > 0) {
    186         foreach my $array (@{$self->{dfringe_data}}) {
    187             my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    188             $stats->add_data(@$array);
    189             push @{$self->{dfringe_mean}}, $stats->mean();
    190             push @{$self->{dfringe_mean_stdev}}, ($stats->standard_deviation() || 0);
    191             # the stdev of a set of 1 is undefined.  that doesn't do
    192             # us much good so I'm changing undef to 0
    193         }
    194     } else {
    195         # create a single NAN entry
    196         push @{$self->{dfringe_mean}}, 'NAN';
    197         push @{$self->{dfringe_mean_stdev}}, 'NAN';
    198     }
    199     if (scalar @{$self->{dfringe_err_data}} > 0) {
    200         foreach my $array (@{$self->{dfringe_err_data}}) {
    201             my @variances;
    202             foreach my $value (@$array) {
    203                 push @variances, $value**2;
    204             }
    205             my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    206             $stats->add_data(@variances);
    207             push @{$self->{dfringe_err}}, sqrt($stats->mean());
    208         }
    209     } else {
    210         push @{$self->{dfringe_err}}, 'NAN';
    211     }
    212 
    213     if ($errors) {
    214         carp "a total of $errors parse errors occured";
    215         return;
    216     }
    217 
    218127    return $self;
    219128}
    220129
    221 sub _parse_megacam
    222 {
    223     my ($self, $md) = @_;
    224 
    225     # Descend the FPA hierarchy
    226     foreach my $fpaItem (@$md) {
    227         if ($fpaItem->{class} eq "metadata") {
    228             my $chipName = $fpaItem->{name}; # Name of chip
    229             my $chipData = $fpaItem->{value}; # Chip-level data
    230             foreach my $chipItem (@$chipData) {
    231                 if ($chipItem->{class} eq "metadata") {
    232                     my $cellName = $chipItem->{name}; # Name of cell
    233                     my $cellData = $chipItem->{value}; # Cell-level data
    234                     my $bgName; # Name of the value we measured
    235                     my $bgStdevName; # Name of the stdev we measured
    236                     foreach my $cellItem (@$cellData) {
    237                         if ($cellItem->{name} =~ /^(SAMPLE|ROBUST|FITTED|CLIPPED)_/) {
    238                             # It's a statistic of some sort
    239                             if ($cellItem->{name} =~ /_STDEV$/) {
    240                                 if (defined $bgStdevName) {
    241                                     carp "Ignoring duplicate background stdev (", $cellItem->{name}, "). ",
    242                                     "Original is ", $bgStdevName, "\n";
    243                                     next;
    244                                 }
    245                                 $bgStdevName = $cellItem->{name};
    246                                 push @{$self->{bg_stdev_data}}, $cellItem->{value};
    247                             } else {
    248                                 if (defined $bgName) {
    249                                     carp "Ignoring duplicate background value (", $cellItem->{name}, "). ",
    250                                     "Original is ", $bgName, "\n";
    251                                     next;
    252                                 }
    253                                 $bgName = $cellItem->{name};
    254                                 push @{$self->{bg_data}}, $cellItem->{value};
    255                             }
    256                         } else {
    257                             $self->_check_values($cellItem);
    258                         }
    259                     }
    260                 } else {
    261                     $self->_check_values($chipItem);
    262                 }
    263             }
    264         } else {
    265             $self->_check_values($fpaItem);
    266         }
    267     }
    268    
    269     return $self;
    270 }
    271 
    272 sub _parse_braindead
     130sub _parse_metadata_stats
    273131{
    274132    my ($self, $md) = @_;
     
    278136        # recurse on nested metadata
    279137        if ($entry->{class} eq 'metadata') {
    280             $self->_parse_braindead($entry->{value});
     138            $self->_parse_metadata_stats($entry->{value});
    281139        }
    282 
    283         if ($entry->{name} =~ /^(SAMPLE|ROBUST|FITTED|CLIPPED)_/) {
    284             # It's a statistic of some sort
    285             if ($entry->{name} =~ /_STDEV$/) {
    286                 push @{$self->{bg_stdev_data}}, $entry->{value};
    287             } else {
    288                 push @{$self->{bg_data}}, $entry->{value};
    289             }
    290             next;
    291         }
    292         if ($entry->{name} =~ /^FRINGE_RESID/) {
    293             my ($num) = $entry->{name} =~ /_(\d+)$/; # Component number
    294             if ($entry->{name} =~ /_ERR_/) {
    295                 my $arrayRef = ${$self->{dfringe_err_data}}[$num];
    296                 unless (defined $arrayRef) {
    297                     my @array;
    298                     $arrayRef = \@array;
    299                     ${$self->{dfringe_err_data}}[$num] = $arrayRef;
    300                 }
    301                 push @$arrayRef, $entry->{value};
    302             } else {
    303                 my $arrayRef = ${$self->{dfringe_data}}[$num];
    304                 unless (defined $arrayRef) {
    305                     my @array;
    306                     $arrayRef = \@array;
    307                     ${$self->{dfringe_data}}[$num] = $arrayRef;
    308                 }
    309                 push @$arrayRef, $entry->{value};
    310             }
    311             next;
    312         }
    313         if ($entry->{name} =~ /^FRINGE/) {
    314             my ($num) = $entry->{name} =~ /_(\d+)$/; # Component number
    315             if ($entry->{name} =~ /_ERR_/) {
    316                 my $arrayRef = ${$self->{fringe_err_data}}[$num];
    317                 unless (defined $arrayRef) {
    318                     my @array;
    319                     $arrayRef = \@array;
    320                     ${$self->{fringe_err_data}}[$num] = $arrayRef;
    321                 }
    322                 push @$arrayRef, $entry->{value};
    323             } else {
    324                 my $arrayRef = ${$self->{fringe_data}}[$num];
    325                 unless (defined $arrayRef) {
    326                     my @array;
    327                     $arrayRef = \@array;
    328                     ${$self->{fringe_data}}[$num] = $arrayRef;
    329                 }
    330                 push @$arrayRef, $entry->{value};
    331             }
    332             next;
    333         }
     140        print STDERR "found $entry->{name} : $entry->{value}\n";
    334141        $self->_check_values($entry);
    335     }
     142   }
    336143
    337144    return $self;
     
    346153    my $value = $mdItem->{value}; # Value of the item
    347154
    348     my $data = $self->{data};        # The data
    349     return if not defined $data->{$name}; # Not interested
    350     my $type = $data->{$name}->{type}; # Type of the item: constant or variable
    351 
    352     if ($type eq 'constant') {
    353         if (defined $data->{$name}->{value} && ($data->{$name}->{value} ne $value)) {
    354             carp "Warning: different value for ", $name, " found: ", $data->{$name}->{value}, " (old) vs ",
    355             $value, " (new).  Ignoring new value.\n";
    356             return;
    357         }
    358         $data->{$name}->{value} = $value;
    359         return;
     155    my $entries = $self->{entries};        # The data
     156
     157    # we may request the value more than once (different stats on the same value)
     158    foreach my $entry (@$entries) {
     159        if ($entry->{name} eq $name) {
     160
     161            my $type = $entry->{type}; # Type of the item: constant or variable
     162            my $data = $entry->{data}; # Array containing all the values
     163
     164            if ($type eq 'constant') {
     165                if (defined $entry->{value} && ($entry->{value} ne $value)) {
     166                    carp "Warning: different value for ", $name, " found: ", $entry->{value}, " (old) vs ", $value, " (new).  Ignoring new value.\n";
     167                    next;
     168                }
     169                $entry->{value} = $value;
     170                next;
     171            }
     172
     173            if ($type eq 'mean') {
     174                push @$data, $value;
     175                next;
     176            }
     177
     178            if ($type eq 'stdev') {
     179                push @$data, $value;
     180                next;
     181            }
     182
     183            if ($type eq 'rms') {
     184                push @$data, ($value**2);
     185                next;
     186            }
     187
     188            if ($type eq 'sum') {
     189                push @$data, $value;
     190                next;
     191            }
     192            carp "Unrecognised type (", $type, ") for value of ", $name, "\n";
     193            exit($PS_EXIT_PROG_ERROR);
     194        }
    360195    }
    361196
    362     if ($type eq 'variable') {
    363         my $array = $data->{$name}->{data}; # Array containing all the values
    364         push @$array, $value;
    365         return;
    366     }
    367 
    368     carp "Unrecognised type (", $type, ") for value of ", $name, "\n";
    369     exit($PS_EXIT_PROG_ERROR);
    370197    return;
    371198}
Note: See TracChangeset for help on using the changeset viewer.