21  void median_smooth (std::vector<T>& data, 
unsigned ndim, 
unsigned wsize)
 
   23    std::vector<typename T::type> temp (data.size());
 
   24    for (
unsigned idim=0; idim<ndim; idim++)
 
   26      for (
unsigned idat=0; idat<data.size(); idat++)
 
   27        temp[idat] = data[idat][idim];
 
   28      median_smooth (temp, wsize);
 
   29      for (
unsigned idat=0; idat<data.size(); idat++)
 
   30        data[idat][idim] = temp[idat];
 
   35  void median_smooth (std::vector<T>& data, 
unsigned wsize)
 
   43    if (data.size() < wsize + 1)
 
   50    unsigned ipt = 0, jpt = 0;
 
   52    unsigned middle = wsize/2;
 
   53    std::vector<T> window (wsize);
 
   55    unsigned rsize = data.size() - wsize + 1;
 
   56    std::vector<T> result (data.size());
 
   58    unsigned truncated = 0;
 
   61    for (ipt=0; ipt < middle; ipt++)
 
   63      truncated = middle + 1 + ipt;
 
   65      for (jpt=0; jpt < truncated; jpt++)
 
   66        window[jpt] = data[jpt];
 
   67      std::nth_element (window.begin(), window.begin()+tmid, 
 
   68                        window.begin()+truncated);
 
   69      result[ipt] = window[tmid];
 
   72    for (ipt=0; ipt < rsize; ipt++)
 
   74      for (jpt=0; jpt<wsize; jpt++)
 
   75        window[jpt] = data[ipt+jpt];
 
   76      std::nth_element (window.begin(), window.begin()+middle, window.end());
 
   77      result[ipt+middle] = window[middle];
 
   81    for (ipt=rsize; ipt < data.size()-middle; ipt++)
 
   83      truncated = data.size() - ipt;
 
   85      for (jpt=0; jpt < truncated; jpt++)
 
   86        window[jpt] = data[ipt+jpt];
 
   87      std::nth_element (window.begin(), window.begin()+tmid,
 
   88                        window.begin()+truncated);
 
   89      result[ipt+middle] = window[tmid];
 
   92    for (ipt=0; ipt < data.size(); ipt++)
 
   93      data[ipt] = result[ipt];
 
   98  T absolute (T x) { 
if (x<0) 
return -x; 
return x; }
 
  101  void median_filter (std::vector<T>& data, 
unsigned wsize, T threshold)
 
  103    std::vector<T> copy (data);
 
  104    median_smooth (copy, wsize);
 
  106    const unsigned ndat = copy.size();
 
  109    for (
unsigned idat=0; idat < ndat; idat++)
 
  111      copy[idat] -= data[idat];
 
  112      copy[idat] *= copy[idat];
 
  113      variance += copy[idat];
 
  120    unsigned total_zapped = 0;
 
  124      T cutoff = threshold * threshold * variance;
 
  129      for (
unsigned idat=0; idat < ndat; idat++)
 
  131        if (copy[idat] > cutoff ||
 
  132            (idat && absolute(copy[idat]-copy[idat-1]) > 2*cutoff))
 
  134          variance -= copy[idat]/ndat;
 
  135          copy[idat] = data[idat] = 0;