// provide a gain corrected slice of the data
public class DataSlice() {
    int number = 0; // Use this as a slice serial number
    
    protected SharcScan scan;
    protected GainStage gainStage;

    protected index = 0;
    protected int[] t, bol;
    protected float[] value;
    
    public DataSlice() {}
    
    public DataSlice(GainStage stage) { gainStage = stage; }
    
    public DataPoint getEstimator() {
	double sum = 0.0, sumw = 0.0;
	for(int i=0; i < value.length; i++) {
	    final double w = scan.weightAt(t[i], bol[i]);	    
	    sum += w * value[i]; 
	    sumw += w;
	}
	if(sumw > 0.0) sum /= sumw;
	
	return new DataPoint(sum, Math.sqrt(1.0/sumw));
    }

    public GainStage getGainStage() { return gainStage; }

    public void toGainStage(GainStage newStage) {
	for(int i=0; i < value.length; i++)
	    value[i] *= gainStage.gain(scan, t[i], bol[i]) / newStage(scan, t[i], bol[i]);
	gainStage = newStage;
    }


    public void inject(double value) {
	for(int i=0; i < value.length; i++)
	    scan.frame[t[i]].readout[bol[i]] += gainStage.gain(scan, t[i], bol[i]) * value;
    }

    public void remove(double value) {
	for(int i=0; i < value.length; i++)
	    scan.frame[t[i]].readout[bol[i]] -= gainStage.gain(scan, t[i], bol[i]) * value;
    }

    
    public void reset() {
	for(int i=0; i < value.length; i++) value[i] = 0.0F;
	index = 0;
    }

    public void setScan(SharcScan aScan) { scan = aScan; } 

    public SharcScan getScan() { return scan; }
    
    public void addPoint(int at, int abol, float avalue) { 
	t[index]  = at;
	bol[index] = abol;
	value[index++] = avalue;
    }

    public void setSize(int size) {
	t = new int[size];
	bol = new int[size];
	value = new int[size];
    }
}
