 
 
 #define EPS (1e-3)
-static unsigned pipeline_get_output_width(pipeline_t self, const double inwidth);
+static unsigned pipeline_get_output_width(pipeline_t self, const double inwidth)
 { const double d=inwidth/self->samples_per_scan; // 1 - duty
-  TRY(-EPS<d && d<=(0.5+EPS));
   //max derivative of the cosine warp adjusted to cos(2pi*(d/2)) is the zero point
   //and the positive part of the warp function goes from 0 to 1.
   const double maxslope=M_PI*(1.0-d)/inwidth/cos(M_PI*d);
   const double amplitude=1.0/maxslope;
-  const unsigned w=self->align*(unsigned)(amplitude/self->align);
+  const unsigned w=self->alignment*(unsigned)(amplitude/(float)self->downsample/self->alignment);
+  TRY(-EPS<d && d<=(0.5+EPS));
   TRY(0<w && w<inwidth);
   return w;
 Error:

    CUTRY(cudaFree(self->ctx.lut_fpart));
    CUTRY(cudaFree(self->ctx.lut_norms));
  }
  CUNEW(unsgined,self->ctx.lut,        inwidth);
  CUNEW(float   ,self->ctx.lut_fpart,  inwidth);
  CUNEW(float   ,self->ctx.lut_norms,2*inwidth);
  return 1;

  unsigned * __restrict__ lut;         ///< look up table for unwarp (ctx.w/2 number of elements).  Set by launch on first call or if width changes.
  float    * __restrict__ lut_fpart;   ///< fractional part of pixel position for lut.  If a smaple is mapped to 4.6, then this is 0.6.  0.4 of the sample will go to pixel 4, and 0.6 will go to pixel 5
  float    * __restrict__ lut_norms;   ///< weight contributed by an input sample to it's main pixel and the neighbor.  Should be interleaved.  Should sum to 1 for each output pixel.
  float    norm,        ///< 1.0/the frame count as a float - set by launcher (eg. for ctx.every=4, this should be 0.25)
           m,b;         ///< slope and intercept for intensity scaling
  unsigned istride,     ///< number of elements between rows of source.
           ostride;     ///< number of elements between rows of output.
