
public class ChoppingData {
	LabocaScan scan;
	LabocaPixel channel;
	public double halfBeam = 9.0*Unit.arcsec;
	
	WeightedPoint left = new WeightedPoint();
	WeightedPoint right = new WeightedPoint();
	
	public ChoppingData(LabocaScan scan, LabocaPixel channel) {
		this.scan = scan;
		this.channel = channel;
	}

	public WeightedPoint getLeftValue() {
		//System.err.print(" [" + scan.serialNo + "|" + (scan.subscanNo+1) + "] L" + (channel.backendIndex+1) + ": ");
		getData();
		WeightedPoint value = new WeightedPoint(left);
		value.subtract(right);
		//System.err.println(value.toString(Util.e3));
		return value;
	}
	
	public WeightedPoint getRightValue() {
		//System.err.print(" [" + scan.serialNo + "|" + (scan.subscanNo+1) + "] R" + (channel.backendIndex+1) + ": ");
		getData();		
		WeightedPoint value = new WeightedPoint(right);
		value.subtract(left);
		//System.err.println(value.toString(Util.e3));
		return value;
	}
	
	public void getData() {
		WeightedPoint point = new WeightedPoint();
		
		for(int t=0; t<scan.frames; t++) {
			LabocaFrame exposure = scan.frame[t];
			if(exposure != null) if((exposure.flag & LabocaFrame.MODELING_FLAGS) == 0)  {
				// Careful, chopper position has opposite sign from offsets!
				boolean leftPhase = Math.abs(exposure.chopperPosition - scan.chopperThrow) < halfBeam;
				boolean rightPhase = Math.abs(exposure.chopperPosition + scan.chopperThrow) < halfBeam;
				
				if(leftPhase | rightPhase) {
					final double g = exposure.transmission * channel.mainBeamEfficiency * channel.gain;
					final double wg = channel.weight * g;	
					point.value = exposure.data[channel.index] / g;
					point.weight = wg * g;	
				}
				
				if(leftPhase) left.average(point);
				else right.average(point);
			}
			
		}
		
	}
	
}
