IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 23, 2008, 4:54:09 PM (18 years ago)
Author:
Paul Price
Message:

Supporting type = "hostname".

File:
1 edited

Legend:

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

    r17602 r17799  
    11# Copyright (c) 2006  Paul Price, Joshua Hoblitt
    22#
    3 # $Id: Stats.pm,v 1.28 2008-05-09 21:02:21 eugene Exp $
     3# $Id: Stats.pm,v 1.29 2008-05-24 02:54:09 price Exp $
    44
    55package PS::IPP::Metadata::Stats;
     
    1212use Carp qw( carp );
    1313use Statistics::Descriptive;
     14use Sys::Hostname;
    1415
    1516use PS::IPP::Config qw(
     
    2425
    2526use base qw( Class::Accessor::Fast );
    26 __PACKAGE__->mk_accessors( qw( 
    27                                results
    28                                ) );
     27__PACKAGE__->mk_accessors( qw(
     28                               results
     29                               ) );
    2930
    3031#$::RD_TRACE = 1;
     
    3334
    3435sub new {
    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
     36    my $class = shift;          # Class name
     37    my $entries = shift;        # Array of values to extract
     38
     39    my $self = {
     40        entries => $entries, # Array of values that should be constant through the FPA
     41        data => {}              # The data
    4142    };
    42    
     43
    4344    # add a hash for storage
    4445    foreach my $entry (@$entries) {
     46        if ($entry->{type} eq "hostname") {
     47            $entry->{value} = hostname();
     48            next;
     49        }
    4550        $entry->{data} = [];
    4651    }
     
    5661
    5762    # apply the needed calculation to the data based on the type
    58    
     63
    5964    my $cmdflags;
    6065    my $entries = $self->{entries};
    61    
     66
    6267    foreach my $entry (@$entries) {
    63         my $value = $entry->{value};
    64         my $flag = $entry->{flag};
    65         next unless defined $value and defined $flag;
    66         if ($value =~ m|\S+\s+\S+|) {
    67             # protect values with whitespace
    68             $cmdflags .= " $flag '$value'";
    69         } else {
    70             $cmdflags .= " $flag $value";
    71         }
     68        my $value = $entry->{value};
     69        my $flag = $entry->{flag};
     70        next unless defined $value and defined $flag;
     71        if ($value =~ m|\S+\s+\S+|) {
     72            # protect values with whitespace
     73            $cmdflags .= " $flag '$value'";
     74        } else {
     75            $cmdflags .= " $flag $value";
     76        }
    7277    }
    7378
     
    8792
    8893    foreach my $entry (@$entries) {
    89         my $type = $entry->{type};
    90         my $data = $entry->{data};
    91 
    92         if ($type eq "constant") {
    93             if (not defined $entry->{value}) {
    94                 $self->_null_for_type ($entry);
    95             }
    96             next;
    97         }
    98 
    99         if ($type eq "mean") {
    100             if (scalar @$data > 0) {
    101                 # Get statistics on the value
    102                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    103                 $stats->add_data(@$data);
    104                 $entry->{value} = $stats->mean();
    105             } else {
    106                 $self->_null_for_type ($entry);
    107             }
    108             next;
    109         }
    110 
    111         # calculate a 3-sigma clipped mean (if Nvalues > 8, reject > 3sigma outliers)
    112         if ($type eq "clipmean") {
    113             if (scalar @$data > 0) {
    114                 # Get statistics on the value
    115                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    116                 $stats->add_data(@$data);
    117                 my $rawMean = $stats->mean();
    118                 my $rawStdev = $stats->standard_deviation();
    119                 my $rawLimit = 3.0*$rawStdev;
    120 
    121                 # clip, if we can
    122                 if (scalar @$data > 8) {
    123                     my @clipdata = ();
    124                     foreach my $value (@$data){
    125                         my $delta = abs($value - $rawMean);
    126                         if ($delta > $rawLimit) { next; }
    127                         push @clipdata, $value;
    128                     }
    129                     my $clipstats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    130                     $clipstats->add_data(@clipdata);
    131                     $entry->{value} = $clipstats->mean();
    132                 } else {
    133                     $entry->{value} = $stats->mean();
    134                 }
    135             } else {
    136                 $self->_null_for_type ($entry);
    137             }
    138             next;
    139         }
    140 
    141         if ($type eq "stdev") {
     94        my $type = $entry->{type};
     95        my $data = $entry->{data};
     96
     97        if ($entry->{type} eq "hostname") {
     98            # Dealt with in new()
     99            next;
     100        }
     101
     102        if ($type eq "constant") {
     103            if (not defined $entry->{value}) {
     104                $self->_null_for_type ($entry);
     105            }
     106            next;
     107        }
     108
     109        if ($type eq "mean") {
     110            if (scalar @$data > 0) {
     111                # Get statistics on the value
     112                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     113                $stats->add_data(@$data);
     114                $entry->{value} = $stats->mean();
     115            } else {
     116                $self->_null_for_type ($entry);
     117            }
     118            next;
     119        }
     120
     121        # calculate a 3-sigma clipped mean (if Nvalues > 8, reject > 3sigma outliers)
     122        if ($type eq "clipmean") {
     123            if (scalar @$data > 0) {
     124                # Get statistics on the value
     125                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     126                $stats->add_data(@$data);
     127                my $rawMean = $stats->mean();
     128                my $rawStdev = $stats->standard_deviation();
     129                my $rawLimit = 3.0*$rawStdev;
     130
     131                # clip, if we can
     132                if (scalar @$data > 8) {
     133                    my @clipdata = ();
     134                    foreach my $value (@$data){
     135                        my $delta = abs($value - $rawMean);
     136                        if ($delta > $rawLimit) { next; }
     137                        push @clipdata, $value;
     138                    }
     139                    my $clipstats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     140                    $clipstats->add_data(@clipdata);
     141                    $entry->{value} = $clipstats->mean();
     142                } else {
     143                    $entry->{value} = $stats->mean();
     144                }
     145            } else {
     146                $self->_null_for_type ($entry);
     147            }
     148            next;
     149        }
     150
     151        if ($type eq "stdev") {
    142152            if (scalar @$data > 1) {
    143                 # Get statistics on the value
    144                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    145                 $stats->add_data(@$data);
    146                 $entry->{value} = $stats->standard_deviation();
    147                 next;
    148             }
    149             if (scalar @$data == 1) {
    150                 $entry->{value} = 0.0;
    151                 next;
    152             }
    153             $self->_null_for_type ($entry);
    154             next;
    155         }
    156 
    157         # calculate a 3-sigma clipped stdev (if Nvalues > 8, reject > 3sigma outliers)
    158         if ($type eq "clipstdev") {
    159             if (scalar @$data > 0) {
    160                 # Get statistics on the value
    161                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    162                 $stats->add_data(@$data);
    163                 my $rawMean = $stats->mean();
    164                 my $rawStdev = $stats->standard_deviation();
    165                 my $rawLimit = 3.0*$rawStdev;
    166 
    167                 # clip, if we can
    168                 if (scalar @$data > 8) {
    169                     my @clipdata = ();
    170                     foreach my $value (@$data){
    171                         my $delta = abs($value - $rawMean);
    172                         if ($delta > $rawLimit) { next; }
    173                         push @clipdata, $value;
    174                     }
    175                     my $clipstats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    176                     $clipstats->add_data(@clipdata);
    177                     $entry->{value} = $clipstats->standard_deviation();
    178                 } else {
    179                     $entry->{value} = $stats->standard_deviation();
    180                 }
    181             } else {
    182                 $self->_null_for_type ($entry);
    183             }
    184             next;
    185         }
    186 
    187         if ($type eq "rms") {
    188             if (scalar @$data > 0) {
    189                 # Get statistics on the value
    190                 # for rmsStats, we pushed the value^2 on the data array
    191                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    192                 $stats->add_data(@$data);
    193                 $entry->{value} = sqrt($stats->mean());
    194             } else {
    195                 $self->_null_for_type ($entry);
    196             }
    197             next;
    198         }
    199 
    200         if ($type eq "sum") {
    201             if (scalar @$data > 0) {
    202                 # Get statistics on the value
    203                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    204                 $stats->add_data(@$data);
    205                 $entry->{value} = $stats->sum();
    206             } else {
    207                 $self->_null_for_type ($entry);
    208             }
    209             next;
    210         }
    211 
    212         if ($type eq "max") {
    213             if (scalar @$data > 0) {
    214                 # Get statistics on the value
    215                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    216                 $stats->add_data(@$data);
    217                 $entry->{value} = $stats->max();
    218             } else {
    219                 $self->_null_for_type ($entry);
    220             }
    221             next;
    222         }
    223 
    224         if ($type eq "min") {
    225             if (scalar @$data > 0) {
    226                 # Get statistics on the value
    227                 my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
    228                 $stats->add_data(@$data);
    229                 $entry->{value} = $stats->min();
    230             } else {
    231                 $self->_null_for_type ($entry);
    232             }
    233             next;
    234         }
     153                # Get statistics on the value
     154                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     155                $stats->add_data(@$data);
     156                $entry->{value} = $stats->standard_deviation();
     157                next;
     158            }
     159            if (scalar @$data == 1) {
     160                $entry->{value} = 0.0;
     161                next;
     162            }
     163            $self->_null_for_type ($entry);
     164            next;
     165        }
     166
     167        # calculate a 3-sigma clipped stdev (if Nvalues > 8, reject > 3sigma outliers)
     168        if ($type eq "clipstdev") {
     169            if (scalar @$data > 0) {
     170                # Get statistics on the value
     171                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     172                $stats->add_data(@$data);
     173                my $rawMean = $stats->mean();
     174                my $rawStdev = $stats->standard_deviation();
     175                my $rawLimit = 3.0*$rawStdev;
     176
     177                # clip, if we can
     178                if (scalar @$data > 8) {
     179                    my @clipdata = ();
     180                    foreach my $value (@$data){
     181                        my $delta = abs($value - $rawMean);
     182                        if ($delta > $rawLimit) { next; }
     183                        push @clipdata, $value;
     184                    }
     185                    my $clipstats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     186                    $clipstats->add_data(@clipdata);
     187                    $entry->{value} = $clipstats->standard_deviation();
     188                } else {
     189                    $entry->{value} = $stats->standard_deviation();
     190                }
     191            } else {
     192                $self->_null_for_type ($entry);
     193            }
     194            next;
     195        }
     196
     197        if ($type eq "rms") {
     198            if (scalar @$data > 0) {
     199                # Get statistics on the value
     200                # for rmsStats, we pushed the value^2 on the data array
     201                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     202                $stats->add_data(@$data);
     203                $entry->{value} = sqrt($stats->mean());
     204            } else {
     205                $self->_null_for_type ($entry);
     206            }
     207            next;
     208        }
     209
     210        if ($type eq "sum") {
     211            if (scalar @$data > 0) {
     212                # Get statistics on the value
     213                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     214                $stats->add_data(@$data);
     215                $entry->{value} = $stats->sum();
     216            } else {
     217                $self->_null_for_type ($entry);
     218            }
     219            next;
     220        }
     221
     222        if ($type eq "max") {
     223            if (scalar @$data > 0) {
     224                # Get statistics on the value
     225                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     226                $stats->add_data(@$data);
     227                $entry->{value} = $stats->max();
     228            } else {
     229                $self->_null_for_type ($entry);
     230            }
     231            next;
     232        }
     233
     234        if ($type eq "min") {
     235            if (scalar @$data > 0) {
     236                # Get statistics on the value
     237                my $stats = Statistics::Descriptive::Sparse->new(); # Statistics calculator
     238                $stats->add_data(@$data);
     239                $entry->{value} = $stats->min();
     240            } else {
     241                $self->_null_for_type ($entry);
     242            }
     243            next;
     244        }
    235245
    236246    }
     
    242252sub _is_null_for_type
    243253{
    244     my ($item) = @_;            # Metadata item
     254    my ($item) = @_;            # Metadata item
    245255
    246256    return 1 unless defined $item->{type} and defined $item->{value};
    247257
    248258    if (($item->{type} eq "F32" or $item->{type} eq "F64") and lc($item->{value} eq 'nan')) {
    249         return 1;
     259        return 1;
    250260    }
    251261    if ($item->{type} eq "STR" and lc($item->{value}) eq 'null') {
    252         return 1;
     262        return 1;
    253263    }
    254264    return 0;
     
    260270
    261271    if ($entry->{dtype} eq "float") {
    262         $entry->{value} = 'NAN';
    263         return;
     272        $entry->{value} = 'NAN';
     273        return;
    264274    }
    265275    if ($entry->{dtype} eq "int") {
    266         $entry->{value} = '0';
    267         return;
     276        $entry->{value} = '0';
     277        return;
    268278    }
    269279    if ($entry->{dtype} eq "string") {
    270         $entry->{value} = 'NULL';
    271         return;
     280        $entry->{value} = 'NULL';
     281        return;
    272282    }
    273283    $entry->{value} = 'NAN';
     
    279289    my ($self, $md) = @_;
    280290
    281     # descend through the fpa       
     291    # descend through the fpa
    282292    foreach my $entry (@$md) {
    283293        # recurse on nested metadata
     
    285295            $self->_parse_metadata_stats($entry->{value});
    286296        }
    287         #if (defined $entry->{value}) {
    288         #    print STDERR "found $entry->{name} : $entry->{value}\n";
    289         #}
    290         $self->_check_values($entry);
     297        #if (defined $entry->{value}) {
     298        #    print STDERR "found $entry->{name} : $entry->{value}\n";
     299        #}
     300        $self->_check_values($entry);
    291301   }
    292302
     
    301311    my $name = $mdItem->{name};        # Name of the item
    302312    my $value = $mdItem->{value}; # Value of the item
    303    
     313
    304314    if ( _is_null_for_type($mdItem) and $mdItem->{class} eq 'scalar' ) {
    305         # print "Stats: Ignoring NULL entry $name\n";
    306         return;
    307     }
    308        
     315        # print "Stats: Ignoring NULL entry $name\n";
     316        return;
     317    }
     318
    309319    my $entries = $self->{entries};        # The data
    310320
    311321    # we may request the value more than once (different stats on the same value)
    312322    foreach my $entry (@$entries) {
    313         if ($entry->{name} eq $name) {
    314 
    315             my $type = $entry->{type}; # Type of the item: constant or variable
    316             my $data = $entry->{data}; # Array containing all the values
    317 
    318             if ($type eq 'constant') {
    319                 if (defined $entry->{value} && ($entry->{value} ne $value)) {
    320                     carp "Warning: different value for ", $name, " found: ", $entry->{value}, " (old) vs ", $value, " (new).  Ignoring new value.\n";
    321                     next;
    322                 }
    323                 $entry->{value} = $value;
    324                 next;
    325             }
    326 
    327             if ($type eq 'mean') {
    328                 push @$data, $value;
    329                 next;
    330             }
    331 
    332             if ($type eq 'clipmean') {
    333                 push @$data, $value;
    334                 next;
    335             }
    336 
    337             if ($type eq 'stdev') {
    338                 push @$data, $value;
    339                 next;
    340             }
    341 
    342             if ($type eq 'clipstdev') {
    343                 push @$data, $value;
    344                 next;
    345             }
    346 
    347             if ($type eq 'rms') {
    348                 push @$data, ($value**2);
    349                 next;
    350             }
    351 
    352             if ($type eq 'sum') {
    353                 push @$data, $value;
    354                 next;
    355             }
    356 
    357             if ($type eq 'max' or $type eq 'min') {
    358                 push @$data, $value;
    359                 next;
    360             }
    361 
    362             carp "Unrecognised type (", $type, ") for value of ", $name, "\n";
    363             exit($PS_EXIT_PROG_ERROR);
    364         }
     323        if ($entry->{name} eq $name) {
     324
     325            my $type = $entry->{type}; # Type of the item: constant or variable
     326            my $data = $entry->{data}; # Array containing all the values
     327
     328            if ($type eq 'constant') {
     329                if (defined $entry->{value} && ($entry->{value} ne $value)) {
     330                    carp "Warning: different value for ", $name, " found: ", $entry->{value}, " (old) vs ", $value, " (new).  Ignoring new value.\n";
     331                    next;
     332                }
     333                $entry->{value} = $value;
     334                next;
     335            }
     336
     337            if ($type eq 'mean') {
     338                push @$data, $value;
     339                next;
     340            }
     341
     342            if ($type eq 'clipmean') {
     343                push @$data, $value;
     344                next;
     345            }
     346
     347            if ($type eq 'stdev') {
     348                push @$data, $value;
     349                next;
     350            }
     351
     352            if ($type eq 'clipstdev') {
     353                push @$data, $value;
     354                next;
     355            }
     356
     357            if ($type eq 'rms') {
     358                push @$data, ($value**2);
     359                next;
     360            }
     361
     362            if ($type eq 'sum') {
     363                push @$data, $value;
     364                next;
     365            }
     366
     367            if ($type eq 'max' or $type eq 'min') {
     368                push @$data, $value;
     369                next;
     370            }
     371
     372            carp "Unrecognised type (", $type, ") for value of ", $name, "\n";
     373            exit($PS_EXIT_PROG_ERROR);
     374        }
    365375    }
    366376
     
    376386
    377387    foreach my $entry (@$entries) {
    378         if ($flag eq $entry->{flag}) {
    379             return $entry->{value};
    380         }
    381     }
    382     return 'NULL'; # 
     388        if ($flag eq $entry->{flag}) {
     389            return $entry->{value};
     390        }
     391    }
     392    return 'NULL'; #
    383393}
    384394
Note: See TracChangeset for help on using the changeset viewer.