virtual void stream_body(wi_run_state &run_state) override {
		
		run_state.start_substream(0.0);
		thread main_t(&vdif_assembler::run, assembler);
			
		for (;;) {	
			float *intensity;
			float *weights;
			ssize_t stride;
			bool zero_flag = false;
			
			run_state.setup_write(nt_maxwrite, intensity, weights, stride, zero_flag);
			
			assembler->get_intensity_chunk(intensity,stride);
			
			//initialize weight to 1.0
			for (int i = 0; i < nfreq; i++) {
				for (int j = 0; j < nt_maxwrite; j++) {		
					weights[i*stride + j] = 1.0;
				}
			}
			//cout << "Bonsai received a chunk." << endl;

			run_state.finalize_write(nt_maxwrite);
					
		}
		run_state.end_substream();
		
		main_t.join();
	}
void psrfits_stream::stream_body(wi_run_state &run_state)
{
    // FIXME psrfits_stream currently sets the initial time of the stream to zero.
    // What's a sensible way to determine an initial time from a 'struct psrfits'?
    double t0 = 0.0;
    run_state.start_substream(t0);

    while (!p->eof) {
	float *intensity;
	float *weights;
	ssize_t stride;
	bool zero_flag = false;
	run_state.setup_write(this->nt_maxwrite, intensity, weights, stride, zero_flag);

	// Transpose and convert uint8 -> float
	for (ssize_t it = 0; it < nt_maxwrite; it++)
	    for (ssize_t ifreq = 0; ifreq < nfreq; ifreq++)
		intensity[ifreq*stride + it] = (float)p->data[it*nfreq + ifreq];

	// psrfits weights are per-(frequency,chunk), not per-(frequency,sample)
	for (ssize_t ifreq = 0; ifreq < nfreq; ifreq++) {
	    float w = p->freq_weights[ifreq];
	    if (w < 0.0)
		throw runtime_error(p->filename + ": negative weight in file, this is currently treated as an error");
	
	    for (ssize_t it = 0; it < nt_maxwrite; it++)
		weights[ifreq*stride + it] = w;
	}

	run_state.finalize_write(this->nt_maxwrite);
	p->read_next_row();
    }

    run_state.end_substream();
}
    //
    // This overrides the pure virtual function wi_stream::stream_body() and defines the stream.
    // For a high-level overview, see comments in rf_pipelines.hpp (in class wi_stream).
    // The 'run_state' argument contains ring buffers which the stream will write data into.
    //
    virtual void stream_body(wi_run_state &run_state) override
    {
	std::random_device rd;
	std::mt19937 rng(rd());
	std::normal_distribution<float> dist(0, sample_rms);

	// In general a stream can be composed of multiple "substreams" (see rf_pipelines.hpp).
	// Here we put everything into a single stream, with nominal starting time t=0.
	run_state.start_substream(0.0);
	
	// Current position in stream (such that 0 <= it0 < nt_tot, where nt_tot is the stream length)
	ssize_t it0 = 0;

	while (it0 < nt_tot) {
	    // Number of samples to write in this block
	    ssize_t nt = min(nt_maxwrite, nt_tot-it0);
	    
	    // Call wi_run_state::setup_write() to reserve space in the ring buffers.
	    // For details, see comments in rf_pipelines.hpp (in class wi_run_state).
	    float *intensity;
	    float *weights;
	    ssize_t stride;
	    bool zero_flag = false;   // no need to zero buffers, since we'll overwrite them shortly
	    run_state.setup_write(nt, intensity, weights, stride, zero_flag);

	    // After setup_write() returns, the 'intensity' and 'weights' pointers point to memory
	    // regions in the ring buffers.  These are logical 2D arrays of shape (nfreq,nt), laid
	    // out in memory so that time samples are adjacent, but frequencies are separated by
	    // offset 'stride'.  Therefore, the memory location of the intensity array element with
	    // (frequency,time) indices (ifreq,it) is intensity[ifreq*stride+it], and similarly for
	    // the weights.

	    // Fill the intensity array with Gaussian random numbers, and initialize the weights to 1.
	    for (ssize_t ifreq = 0; ifreq < nfreq; ifreq++) {
		for (ssize_t it = 0; it < nt; it++) {
		    intensity[ifreq*stride + it] = dist(rng);
		    weights[ifreq*stride + it] = 1.0;
		}
	    }

	    // Call wi_run_state::finalize_write() after filling the arrays, to advance the ring buffers.
	    // After finalize_write() returns, the intensity and weights pointers are no longer valid.
	    run_state.finalize_write(nt);

	    it0 += nt;
	}

	run_state.end_substream();
    }