package dmrgvisu2;

import info.monitorenter.gui.chart.TracePoint2D;
import info.monitorenter.gui.chart.ITrace2D;
import info.monitorenter.gui.chart.io.ADataCollector;

public class DmrgCollector extends ADataCollector
{
	private static final long serialVersionUID = 1L;
	public visu visuRef;
	
	public DmrgCollector(ITrace2D Energy, long latency)
	{
		super(Energy, latency);
	}
	
	public void SetVisu(visu visuRef)
	{
		this.visuRef = visuRef;
	}
	
	public TracePoint2D collectData()
	{
		// Maximale Anzahl an Sweeps erreicht? ==> Stop
		if (this.visuRef.DmrgRef.CurrentSweep == this.visuRef.Sweeps)
			this.visuRef.stopData();
			
		// Erzeuge neue Daten
		int y = this.visuRef.DmrgRef.DoNextStep();

		// Erzeuge den neuen Energie-Punkt
		TracePoint2D Point = new TracePoint2D(y, this.visuRef.DmrgRef.CurrentEnergy);
		this.visuRef.getEnergyTrace().addPoint(Point);
		
		// Aktualisiere die Spur der Dichtematrix
		this.visuRef.getDmTrace().removeAllPoints();
		for (int i = 0; i<this.visuRef.DmrgRef.CurrentDm.length; i++)
			this.visuRef.getDmTrace().addPoint(i, this.visuRef.DmrgRef.CurrentDm[i]);
			
		// Aktualisieren der Erwartungswerte für Sx und Sz
		for (int i=0; i<this.visuRef.Site; i++)
		{
			this.visuRef.getErwSzTrace().addPoint(i, this.visuRef.DmrgRef.CurrentSzExV[i]);
			this.visuRef.getErwSxTrace().addPoint(i, this.visuRef.DmrgRef.CurrentSxExV[i]);
		}		

		// Bestimme die entanglement entropy
		double enen = 0.0;
		for (int i = 0; i<this.visuRef.DmrgRef.CurrentDm.length; i++)
			enen = enen + this.visuRef.DmrgRef.CurrentDm[i]*(Math.log(this.visuRef.DmrgRef.CurrentDm[i])/Math.log(2.0));
		this.visuRef.getEeTrace().addPoint(y+0.5*(this.visuRef.DmrgRef.Direction==false?1:-1),-enen);
		
		// Aktualisiere Text-Ausgabe
		if (this.visuRef.DmrgRef.CurrentEnergy < this.visuRef.DmrgRef.MinEnergy)
		{
			this.visuRef.DmrgRef.MinEnergy = this.visuRef.DmrgRef.CurrentEnergy;
			this.visuRef.DmrgRef.EnergyText.setText("Minimal energy: " + (this.visuRef.DmrgRef.MinEnergy));
		}
		this.visuRef.DmrgRef.SweepText.setText("Current sweep: " + (this.visuRef.DmrgRef.CurrentSweep));
		this.visuRef.DmrgRef.SiteText.setText("Current site: " + (y));
		
		// Positionsanzeige Energy-Trace
		double x = this.visuRef.getEnergyTrace().getMinY()+(this.visuRef.getEnergyTrace().getMaxY()-this.visuRef.getEnergyTrace().getMinY())/2.0;
		this.visuRef.getEnergyPosTrace().addPoint(y-0.4, x);
		this.visuRef.getEnergyPosTrace().addPoint(y+0.4, x);
		
		// Positionsanzeige Erwartungswert-Trace
		x = (this.visuRef.getErwSxTrace().getMinY()<this.visuRef.getErwSzTrace().getMinY()?this.visuRef.getErwSxTrace().getMinY():this.visuRef.getErwSzTrace().getMinY())+((this.visuRef.getErwSxTrace().getMaxY()>this.visuRef.getErwSzTrace().getMaxY()?this.visuRef.getErwSxTrace().getMaxY():this.visuRef.getErwSzTrace().getMaxY())-(this.visuRef.getErwSxTrace().getMinY()<this.visuRef.getErwSzTrace().getMinY()?this.visuRef.getErwSxTrace().getMinY():this.visuRef.getErwSzTrace().getMinY()))/2.0;
		this.visuRef.getErwPosTrace().addPoint(y-0.4, x);
		this.visuRef.getErwPosTrace().addPoint(y+0.4, x);
	
		return Point;
	}
}
