Changes between Version 2 and Version 3 of BossaExampleThree


Ignore:
Timestamp:
Jul 30, 2008, 11:51:12 AM (16 years ago)
Author:
davea
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • BossaExampleThree

    v2 v3  
     1= Example 3: Calibration jobs and adaptive replication =
     2
     3This example uses a more refined replication policy:
     4instead of doing 2-fold replication,
     5we estimate the error rate of volunteers using calibration tasks,
     6and do enough instance of each job so that the overall probability of error
     7is below a threshold.
     8
     9We'll track the error rate separately for positive and negative jobs
     10(i.e., images with and without an ellipse).
     11The opaque data structure for users has components:
     12
     13'''nneg''': # of negative calibration jobs completed
     14
     15'''nneg_err''': of those, the number of errors
     16
     17'''npos''': # of positive calibration jobs completed
     18
     19'''npos_err''': of those, the number of errors
     20
     21From these we will derive:
     22
     23'''neg_err_rate''': error rate for negative cases
     24'''pos_err_rate''': error rate for positive cases
     25
     26Our replication policy is:
     27
     28 * A job is marked Done if either
     29  * There are N positive instances that match within 20 pixels, and for which the product of pos_err_rate (for the corresponding users) is less than 1e-3, or
     30  * there are N negative instances and the product of neg_err_rate is less than 1e-3.
     31 * Else a job is marked Inconclusive if there are 10 finished instances
     32
     33These policies are implemented in '''job_finished()''':
    134{{{
    2 function job_finished($job, $inst, $user) {
    3     $response = null;
    4     if (get_str('submit', true)) {
    5         $response->have_ellipse = 0;
    6     } else {
    7         $response->have_ellipse = 1;
    8         $response->cx = get_int('pic_x');
    9         $response->cy = get_int('pic_y');
    10     }
    11     $inst->update_info($response);
    12 
    13     if ($job->calibration) {
    14         $b = $user->bossa;
    15         $info = $job->get_info();
    16         $answer = $info->answer;
    17         $u = $b->get_info();
    18         if (!$u) {
    19             $u->npos = 0;
    20             $u->npos_err = 0;
    21             $u->nneg = 0;
    22             $u->nneg_err = 0;
    23         }
    24         if (compatible($response, $answer)) {
    25             if ($answer->have_ellipse) {
    26                 $u->npos++;
    27             } else {
    28                 $u->nneg++;
    29             }
    30         } else {
    31             if ($answer->have_ellipse) {
    32                 $u->npos++;
    33                 $u->npos_err++;
    34             } else {
    35                 $u->nneg++;
    36                 $u->nneg_err++;
    37             }
    38         }
    39         $b->update_info($u);
    40         return;
    41     }
    42 
    43     // see if job is done
    44     //
    45     $insts = $job->get_finished_instances();
    46     $n = count($insts);
    47 
    48     $results = null;
    49     $users = null;
    50     foreach ($insts as $inst) {
    51         $results[] = $inst->get_info();
    52         $u = $inst->get_user();
    53         $users[] = $u->bossa->get_info();
    54     }
    55 
    56     // see if there's a negative consensus
    57     //
    58     $prob = 1;
    59     for ($i=0; $i<$n; $i++) {
    60         $r = $results[$i];
    61         if ($r1->have_ellipse) continue;
    62         $u = $users[$i];
    63         $prob *= $u->neg_err_rate;
    64     }
    65     if ($prob < PROB_LIMIT) {
    66         $job->update_state(BOSSA_JOB_DONE);
    67         return;
    68     }
    69 
    70     // see if there's a positive consensus
    71     //
    72     for ($i=0; $i<$n; $i++) {
    73         $r1 = $results[$i];
    74         $u = $users[$i];
    75         $prob = $u->pos_error_rate;
    76         for ($j=0; $j<$n; $j++) {
    77             if ($j == $i) continue;
    78             $r2 = $results[$j];
    79             if (compatible($r1, $r2)) {
    80                 $u2 = $users[$j];
    81                 $prob *= $u2->pos_err_rate;
    82             }
    83         }
    84         if ($prob < PROB_LIMIT) {
    85             $job->update_state(BOSSA_JOB_DONE);
    86             return;
    87         }
    88     }
    89 
    90     // see if there are too many instances without a consensus
    91     //
    92     if ($n >= 10) {
    93         $job->update_state(BOSSA_JOB_INCONCLUSIVE);
    94         return;
    95     }
    96 }
     35    50  function job_finished($job, $inst, $user) {
     36    51      $response = null;
     37    52      if (get_str('submit', true)) {
     38    53          $response->have_ellipse = 0;
     39    54      } else {
     40    55          $response->have_ellipse = 1;
     41    56          $response->cx = get_int('pic_x');
     42    57          $response->cy = get_int('pic_y');
     43    58      }
     44    59      $inst->set_opaque_data($response);
     45    60
     46    61      // if this is a calibration job, update user's opaque data
     47    62      //
     48    63      if ($job->calibration) {
     49    64          $b = $user->bossa;
     50    65          $info = $job->get_opaque_data();
     51    66          $answer = $info->answer;
     52    67          $u = $b->get_opaque_data();
     53    68          if (!$u) {
     54    69              $u->npos = 0;
     55    70              $u->npos_err = 0;
     56    71              $u->nneg = 0;
     57    72              $u->nneg_err = 0;
     58    73          }
     59    74          if (compatible($response, $answer)) {
     60    75              if ($answer->have_ellipse) {
     61    76                  $u->npos++;
     62    77              } else {
     63    78                  $u->nneg++;
     64    79              }
     65    80          } else {
     66    81              if ($answer->have_ellipse) {
     67    82                  $u->npos++;
     68    83                  $u->npos_err++;
     69    84              } else {
     70    85                  $u->nneg++;
     71    86                  $u->nneg_err++;
     72    87              }
     73    88          }
     74    89          $b->set_opaque_data($u);
     75    90          return;
     76    91      }
     77    92
     78    93      // now see if job is done
     79    94      //
     80    95      $insts = $job->get_finished_instances();
     81    96      $n = count($insts);
     82    97
     83    98      $results = null;
     84    99      $users = null;
     85   100      foreach ($insts as $inst) {
     86   101          $results[] = $inst->get_opaque_data();
     87   102          $u = $inst->get_user();
     88   103          $users[] = $u->bossa->get_opaque_data();
     89   104      }
     90   105
     91   106      // see if there's a negative consensus
     92   107      //
     93   108      $prob = 1;
     94   109      for ($i=0; $i<$n; $i++) {
     95   110          $r = $results[$i];
     96   111          if ($r1->have_ellipse) continue;
     97   112          $u = $users[$i];
     98   113          $prob *= $u->neg_err_rate;
     99   114      }
     100   115      if ($prob < PROB_LIMIT) {
     101   116          $job->set_state(BOSSA_JOB_DONE);
     102   117          return;
     103   118      }
     104   119
     105   120      // see if there's a positive consensus
     106   121      //
     107   122      for ($i=0; $i<$n; $i++) {
     108   123          $r1 = $results[$i];
     109   124          $u = $users[$i];
     110   125          $prob = $u->pos_error_rate;
     111   126          for ($j=0; $j<$n; $j++) {
     112   127              if ($j == $i) continue;
     113   128              $r2 = $results[$j];
     114   129              if (compatible($r1, $r2)) {
     115   130                  $u2 = $users[$j];
     116   131                  $prob *= $u2->pos_err_rate;
     117   132              }
     118   133          }
     119   134          if ($prob < PROB_LIMIT) {
     120   135              $job->set_state(BOSSA_JOB_DONE);
     121   136              return;
     122   137          }
     123   138      }
     124   139
     125   140      // see if there are too many instances without a consensus
     126   141      //
     127   142      if ($n >= 10) {
     128   143          $job->set_state(BOSSA_JOB_INCONCLUSIVE);
     129   144          return;
     130   145      }
     131   146
     132   147      // still looking for consensus - get another instance
     133   148      //
     134   149      $job->set_priority(2);
     135   150
     136   151  }
    97137}}}
    98138
     139We also supply a callback function to show
     140a user's opaque data on administrative web pages:
    99141{{{
    100142function user_summary($user) {