/* * Cutoff2MouseModule.java * * Created on November 10, 2005, 1:41 PM * * */ package org.das2.event; import org.das2.DasApplication; import org.das2.DasException; import org.das2.dataset.AverageTableRebinner; import org.das2.dataset.ClippedTableDataSet; import org.das2.dataset.DataSetConsumer; import org.das2.dataset.DataSetRebinner; import org.das2.dataset.DataSetUpdateEvent; import org.das2.dataset.RebinDescriptor; import org.das2.dataset.TableDataSetConsumer; import org.das2.datum.Datum; import org.das2.datum.DatumRange; import org.das2.datum.Units; import org.das2.graph.DasAxis; import org.das2.graph.DasCanvas; import org.das2.graph.DasColumn; import org.das2.graph.DasPlot; import org.das2.graph.DasRow; import org.das2.graph.SymbolLineRenderer; import org.das2.util.monitor.ProgressMonitor; import java.awt.Color; import java.beans.PropertyChangeEvent; import java.util.Collections; import javax.swing.JFrame; import org.das2.qds.DataSetOps; import org.das2.qds.DataSetUtil; import org.das2.qds.QDataSet; import org.das2.qds.SemanticOps; import org.das2.qds.ops.Ops; import org.das2.qds.util.DataSetBuilder; /** * * @author Jeremy */ public class CutoffMouseModule extends BoxSelectorMouseModule { DatumRange xrange; DatumRange yrange; String lastComment; CutoffSlicer cutoffSlicer; DasApplication application; public CutoffMouseModule( DasPlot parent, DataSetConsumer consumer ) { super( parent, parent.getXAxis(), parent.getYAxis(), consumer, new BoxRenderer(parent,true), "Cutoff" ); application= parent.getCanvas().getApplication(); this.dataSetConsumer= consumer; } @Override protected void fireBoxSelectionListenerBoxSelected(BoxSelectionEvent event) { DatumRange xrange0= xrange; DatumRange yrange0= yrange; xrange= event.getXRange(); yrange= event.getYRange(); synchronized (this) { if ( event.getPlane("keyChar")!=null ) { lastComment= (String)event.getPlane("keyChar"); } else { lastComment= null; } } try { recalculateSoon( ); } catch ( RuntimeException ex ) { xrange= xrange0; yrange= yrange0; throw ex; } } /** * return RebinDescriptor that is on descrete, repeatable boundaries. * get us2000, divide by resolution, truncate, multiply by resolution. */ private RebinDescriptor getRebinDescriptor( DatumRange range ) { double res= xResolution.doubleValue(Units.microseconds); double min= range.min().doubleValue(Units.us2000); min= Math.floor( min / res ); double max= range.max().doubleValue(Units.us2000); max= Math.ceil( max / res ); int nbin= (int)(max-min); RebinDescriptor ddx= new RebinDescriptor( min*res, max*res, Units.us2000, nbin, false ); return ddx; } private void recalculateSoon( ) { Runnable run= new Runnable() { public void run() { ProgressMonitor mon= application.getMonitorFactory().getMonitor( parent, "calculating cutoffs", "calculating cutoffs" ); recalculate( mon ); } }; new Thread( run, "digitizer recalculate" ).start(); } private synchronized void recalculate( ProgressMonitor mon) { QDataSet tds= (QDataSet)dataSetConsumer.getConsumedDataSet(); if ( tds==null ) return; if ( xrange==null ) return; tds= new ClippedTableDataSet( tds, xrange, yrange ); QDataSet yds= SemanticOps.ytagsDataSet(tds); QDataSet xds= SemanticOps.xtagsDataSet(tds); // average the data down to xResolution DataSetRebinner rebinner= new AverageTableRebinner(); DatumRange range= DataSetUtil.asDatumRange( SemanticOps.bounds(tds).slice(0), true ); RebinDescriptor ddx= getRebinDescriptor( range ); try { //TODO: why does rebin throw DasException? tds= (QDataSet)rebinner.rebin(tds, ddx, null, null ); } catch ( DasException e ) { throw new RuntimeException(e); } double fill= SemanticOps.getUnits(yds).getFillDouble(); DataSetBuilder builder= new DataSetBuilder( 1, 100 ); builder.putProperty( QDataSet.UNITS, SemanticOps.getUnits(yds) ); builder.putProperty( QDataSet.FILL_VALUE, fill ); DataSetBuilder xbuilder= new DataSetBuilder( 1, 100 ); xbuilder.putProperty( QDataSet.UNITS, SemanticOps.getUnits(xds) ); mon.setTaskSize( tds.length() ); mon.started(); for ( int i=0; i-1 ) { xbuilder.putValue( -1, xds.value(i) ); builder.putValue( -1, yds.value(icutoff) ); } else { xbuilder.putValue( -1, xds.value(i) ); builder.putValue( -1, fill ); } builder.nextRecord(); xbuilder.nextRecord(); } mon.finished(); if ( mon.isCancelled() ) return; String comment= "Ondrej:"+levelMin+":"+slopeMin+":"+nave; if ( lastComment!=null ) { comment= lastComment + " "+comment; } builder.putProperty( QDataSet.USER_PROPERTIES, Collections.singletonMap("comment",comment) ); xbuilder.putProperty( QDataSet.CADENCE, DataSetUtil.asDataSet(this.xResolution ) ); builder.putProperty( QDataSet.DEPEND_0, xbuilder.getDataSet() ); QDataSet vds= builder.getDataSet(); fireDataSetUpdateListenerDataSetUpdated( new DataSetUpdateEvent( vds ) ); } /** * slopeMin in the y units of ds. * levelMin in the y units of ds. * mult=-1 high cutoff, =1 low cutoff */ public int cutoff( QDataSet ds, Datum slopeMin, int nave, int mult, Datum levelMin ) { int nfr= ds.length(); if ( nfr < (nave+1) ) { throw new IllegalArgumentException("DataSet doesn't contain enough elements"); } double[] cumul= new double[nfr]; Units units= SemanticOps.getUnits(ds); double level= levelMin.doubleValue( units ); double slope= slopeMin.doubleValue( units ); cumul[0]= ds.value(0); for ( int i=1; i0 ? ave[j+k] : ave[j]; if ( uave <= level ) icof[j]=false; icofBuilder.putValue( -1, icof[j] ? 1: 0 ); icofBuilder.nextRecord(); xicofBuilder.putValue( -1, xds.value(j) ); xicofBuilder.nextRecord(); } } if ( cutoffSlicer!=null ) { slopeBuilder.putProperty( QDataSet.DEPEND_0, xslopeBuilder.getDataSet() ); cutoffSlicer.slopeRenderer.setDataSet( slopeBuilder.getDataSet() ); levelBuilder.putProperty( QDataSet.DEPEND_0, xlevelBuilder.getDataSet() ); cutoffSlicer.levelRenderer.setDataSet( levelBuilder.getDataSet() ); icofBuilder.putProperty( QDataSet.DEPEND_0, xicofBuilder.getDataSet() ); cutoffSlicer.icofRenderer.setDataSet( icofBuilder.getDataSet() ); } int icutOff=-1; for ( int j= ( mult<0 ? nfr-1 : 0 ); j>=0 && j= 0; i -= 2) { if (listeners[i]==java.beans.PropertyChangeListener.class) { ((java.beans.PropertyChangeListener)listeners[i+1]).propertyChange(event); } } } }