KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > instruments > PTCroquette


1 package JSci.instruments;
2
3 import JSci.swing.*;
4
5 import java.awt.*;
6 import java.awt.event.*;
7 import java.awt.geom.*;
8 import java.io.*;
9 import java.text.*;
10 import javax.swing.*;
11 import javax.swing.event.*;
12 import javax.swing.border.*;
13
14 /** an Effect that does the particle tracking in 3D, for symmetric images */
15 public class PTCroquette extends ImageFilterAdapter implements ParticleTracker, ROI {
16
17     /** Length of the arms of the cross */
18     public static int CROSS_L=32;
19     /** Width of the arms of the cross */
20     public static int CROSS_H=3;
21     /** Steps in z for calibration (microns) */
22     public static double CALIBR_STEP=0.5;
23     /** While calibrating, averages this number of frames */
24     public static int CALIBR_AVR=3;
25
26     public String JavaDoc getName() { return "PT 3D symmetric"; };
27
28     private PTCroquetteCross cross1,cross2;
29     private PositionControl pc = null;
30
31     private ParticleTrackerListener ptl = null;
32     public void setListener(ParticleTrackerListener ptl) {
33     this.ptl=ptl;
34     }
35
36     /** @param p the device that will control the motion of the microscope
37      */

38     public PTCroquette(PositionControl p) {
39     cross1 = new PTCroquetteCross(CROSS_L,CROSS_H,new Point(50,50),Color.MAGENTA);
40     cross2 = new PTCroquetteCross(CROSS_L,CROSS_H,new Point(50,120),Color.CYAN);
41     pc = p;
42     controlComponent = new PTControlComponent( new Control[] {pc,cross1,cross2} );
43     pc.addChangeListener((ChangeListener)cross1.getControlComponent());
44     pc.addChangeListener((ChangeListener)cross2.getControlComponent());
45     controlComponent = new PTControlComponent( new Control[] {pc,cross1,cross2} );
46     }
47
48     /** processes a frame. Do not call this directly.
49      * @param f the image that must be processed
50      */

51     public void filter(Image f) {
52     cross1.setBBox(new Rectangle(new Point(0,0),getSize()));
53     cross2.setBBox(new Rectangle(new Point(0,0),getSize()));
54     cross1.findXY(f);
55     cross2.findXY(f);
56     if (!calibrating) {
57         cross1.findZ(f);
58         cross2.findZ(f);
59     }
60     else {
61         cross1.calibrationSendImage(f);
62         cross2.calibrationSendImage(f);
63     }
64     if (ptl!=null)
65         ptl.receivePosition(f.getTimeStamp(),
66                 new int[] {0,1},
67                 new double[] {cross1.getLocation().getX(),cross2.getLocation().getX()},
68                 new double[] {cross1.getLocation().getY(),cross2.getLocation().getY()},
69                 new double[] {cross1.getZ()-pc.getPosition(),cross2.getZ()-pc.getPosition()}
70                 );
71     }
72
73
74     /* ------------------------------------------------------- */
75     /* ROI */
76     /* ------------------------------------------------------- */
77     
78     public Shape getShape() { return cross2; }
79            
80     public void paint(java.awt.Graphics JavaDoc g) {
81     Graphics2D g2= (Graphics2D)g;
82     g2.setColor(cross1.getColor());
83     g2.draw(cross1);
84     Point2D p = cross1.getLocation();
85     g2.drawString("Ref",(int)p.getX()+CROSS_H,(int)p.getY()+CROSS_L);
86     g2.setColor(cross2.getColor());
87     g2.draw(cross2);
88     }
89  
90     private Component mouseComponent;
91
92     /** Set the component that displays the image, so that
93      * the crosses can be moved with the mouse.
94      * @param c the component from which we want to get the mouse actions
95      */

96     public void setComponent(Component c) {
97     mouseComponent=c;
98     c.addMouseListener(new MouseHandler());
99     c.addMouseMotionListener(new MouseMotionHandler());
100     c.addMouseWheelListener(new MouseWheelHandler());
101     }
102
103
104
105     /* ------------------------------------------------------- */
106     /* Calibration */
107     /* ------------------------------------------------------- */
108
109     private boolean calibrating = false;
110
111     private void doCalibration(int zNum,int lNum,double minZ,double maxZ) {
112     calibrating=true;
113     cross1.calibrationStart(zNum,minZ,maxZ);
114     cross2.calibrationStart(zNum,minZ,maxZ);
115     for (int j=0;j<zNum;j++) {
116         pc.setPosition(j*(maxZ-minZ)/zNum+minZ);
117         pc.sleep();
118         for (int k=0;k<lNum;k++) {
119         cross1.calibrationRequest(j);
120         cross2.calibrationRequest(j);
121         cross1.calibrationWait();
122         cross2.calibrationWait();
123         }
124     }
125     cross1.calibrationEnd();
126     cross2.calibrationEnd();
127     calibrating=false;
128     }
129
130
131
132     /* ------------------------------------------------------- */
133     /* Control Component */
134     /* ------------------------------------------------------- */
135  
136     private PTControlComponent controlComponent;
137
138     /**
139      * @return the component with controls for the effect
140      */

141     public Component getFilterControlComponent() { return controlComponent; }
142
143     private class PTControlComponent extends JPanel {
144
145     private JButton calibrButton = new JButton("Calibrate");
146
147     private JButton setMin = new JButton("Set min");
148     private JButton setMax = new JButton("Set max");
149     private JSpinner calibrMin =
150         new JSpinner(new SpinnerNumberModel(0.0,pc.getMinimum(),pc.getMaximum(),0.1));
151     private JSpinner calibrMax =
152         new JSpinner(new SpinnerNumberModel(0.0,pc.getMinimum(),pc.getMaximum(),0.1));
153
154     public PTControlComponent(Control [] cc) {
155         super();
156         for (int j=0;j<cc.length;j++) add(cc[j].getControlComponent());
157         add(calibrButton);
158
159         calibrButton.addActionListener(new ActionListener() {
160             public void actionPerformed(ActionEvent e) {
161             Thread JavaDoc calibrThrd = new Thread JavaDoc(new Runnable JavaDoc() {
162                 public void run() {
163                     calibrButton.setEnabled(false);
164                     pc.getControlComponent().setEnabled(false);
165                     double min = ((Double JavaDoc)calibrMin.getValue()).doubleValue();
166                     double max = ((Double JavaDoc)calibrMax.getValue()).doubleValue();
167                     doCalibration((int)Math.round((max-min)/CALIBR_STEP),CALIBR_AVR,min,max);
168                     pc.getControlComponent().setEnabled(true);
169                     calibrButton.setEnabled(true);
170                 }
171                 });
172             calibrThrd.start();
173             }
174         });
175         
176         setMin.addActionListener(new ActionListener() {
177             public void actionPerformed(ActionEvent e) {
178             calibrMin.setValue(new Double JavaDoc(pc.getPosition()));
179             }
180         });
181         setMax.addActionListener(new ActionListener() {
182             public void actionPerformed(ActionEvent e) {
183             calibrMax.setValue(new Double JavaDoc(pc.getPosition()));
184             }
185         });
186         JPanel calibrPanel1 = new JPanel();
187         calibrPanel1.setLayout( new BorderLayout());
188         JPanel calibrPanel2 = new JPanel();
189         calibrPanel2.setLayout( new BorderLayout());
190         calibrPanel1.add("North",setMax);
191         calibrPanel2.add("North",calibrMax);
192         calibrPanel1.add("South",setMin);
193         calibrPanel2.add("South",calibrMin);
194         add(calibrPanel1);
195         add(calibrPanel2);
196     }
197     }
198
199
200     /* ------------------------------------------------------- */
201     /* Mouse Listeners */
202     /* ------------------------------------------------------- */
203  
204
205
206     private Point refPos = new Point();
207  
208
209     private class MouseHandler extends MouseAdapter {
210     public void mousePressed(MouseEvent event) {
211         if (cross1.getBounds().contains(event.getPoint())) {
212         cross1.setDragging(true);
213         refPos=new Point((int)cross1.getLocation().getX(),(int)cross1.getLocation().getY());
214         }
215         else if (cross2.getBounds().contains(event.getPoint())) {
216         cross2.setDragging(true);
217         refPos=new Point((int)cross2.getLocation().getX(),(int)cross2.getLocation().getY());
218         }
219         refPos.translate(-event.getPoint().x,-event.getPoint().y);
220     }
221     public void mouseReleased(MouseEvent event) {
222         cross1.setDragging(false);
223         cross2.setDragging(false);
224     }
225     }
226
227     private class MouseMotionHandler extends MouseMotionAdapter {
228     public void mouseMoved(MouseEvent event) {
229         if (
230         cross1.getBounds().contains(event.getPoint()) ||
231         cross2.getBounds().contains(event.getPoint())
232         )
233         mouseComponent.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
234         else
235         mouseComponent.setCursor(Cursor.getDefaultCursor());
236     }
237     public void mouseDragged(MouseEvent event) {
238         if (cross1.isDragging()) cross1.setLocation(new Point(event.getPoint().x+refPos.x,event.getPoint().y+refPos.y));
239         if (cross2.isDragging()) cross2.setLocation(new Point(event.getPoint().x+refPos.x,event.getPoint().y+refPos.y));
240     }
241     }
242
243     private class MouseWheelHandler implements MouseWheelListener {
244     public void mouseWheelMoved(MouseWheelEvent e) {
245         if (calibrating) return;
246         double p=pc.getPosition();
247         p-=e.getWheelRotation()*0.1;
248         pc.setPosition(p);
249     }
250     }
251
252
253
254     ///////////////////////////////////////////////////////////////////////////////////
255
// MAIN - an example that uses some simulated controls.
256

257     public static void main(String JavaDoc args[]) {
258     PositionControl pc = new DummyPositionControl() {
259         protected void doSetPosition(double p) {
260             Simulated.z=p;
261             super.doSetPosition(p);
262         }
263         };
264     Simulated.z=pc.getPosition();
265     PTCroquette filter = new PTCroquette(pc);
266     ImageSource source = new Simulated();
267     Player player = new Player();
268     player.addROI(filter);
269     source.setSink(filter);
270     filter.setSink(player);
271     player.start();
272
273     final NumberFormat formatter = NumberFormat.getNumberInstance();
274     { formatter.setMaximumFractionDigits(3);
275     formatter.setMinimumFractionDigits(1);
276     formatter.setMinimumIntegerDigits(1);
277     formatter.setMaximumIntegerDigits(4);
278     }
279     ParticleTrackerListener ptl = new ParticleTrackerListener() {
280         public void receivePosition(long time,int[] n,double[] x,double[] y,double[] z) {
281             System.out.println(time+" "+x[0]+" "+y[0]+" "+z[0]+" "+x[1]+" "+y[1]+" "+z[1]);
282         }
283         };
284     filter.setListener(ptl);
285
286
287
288     }
289
290
291 }
292
293
294
295
296
297
298 ////////////////////////////////////////////////////////////////////////////////////////
299
// Other classes ONLY for simulations and tests
300

301
302
303 ///////////////////////////////////////////////////////////////////////////////////////
304
// Simulated image ImageSource
305

306 class Simulated implements ImageSource,Runnable JavaDoc {
307
308
309
310     private Dimension dim = new Dimension(600,500);
311
312     public Simulated() {
313     Thread JavaDoc t = new Thread JavaDoc(this);
314     t.setDaemon(true);
315     t.start();
316     }
317
318     private ImageSink sink;
319     /** set the object that must read the frames through receive() method.
320      * @param fs the object that reads the frames
321      */

322     public void setSink(ImageSink fs) {
323     if (sink!=fs) {
324         sink=fs;
325         sink.setSource(this);
326     }
327     }
328
329     public void run() {
330     int num = 0;
331     while (true) {
332         Image f = getImage();
333         if (sink!=null) sink.receive(f);
334         try { Thread.sleep(100); }
335         catch (InterruptedException JavaDoc e) {}
336     }
337     }
338
339     /** @return the width of the image */
340     public int getWidth() { return dim.width; }
341     
342     /** @return the height of the image */
343     public int getHeight() { return dim.height; }
344     
345     /** @return the dimension of the image */
346     public Dimension getSize() { return dim; }
347
348     /** @return the component that controls the object that implements
349     this interface */

350     public Component getControlComponent() {
351     JPanel p = new JPanel();
352     p.setLayout(new BorderLayout());
353     final JButton oscillButton = new JButton("Oscillate");
354     oscillButton.addActionListener(new ActionListener() {
355         public void actionPerformed(ActionEvent e) {
356             boolean state = ! Simulated.getOscillating();
357             Simulated.setOscillating(state);
358             if (state) oscillButton.setText("Stop");
359             else oscillButton.setText("Oscillate");
360         }
361         });
362     p.add(BorderLayout.NORTH,new JLabel("Test"));
363     p.add(BorderLayout.SOUTH,oscillButton);
364     Border etched = BorderFactory.createEtchedBorder();
365     Border titled = BorderFactory.createTitledBorder(etched,"source");
366     p.setBorder(titled);
367     return p;
368     }
369
370
371     // generate the images
372

373     public static double z;
374     private long num=0;
375
376     private double theta = 0.0, vs,vc,dh;
377     private final double R=100.0;
378     private double f(double x) {
379     return 1.0/(1.0-Math.pow(x,2)+Math.pow(x,4));
380     }
381     private double g(double x,double y) {
382     return f(Math.sqrt(Math.pow(x-vc,2)+Math.pow(y-vs,2))/(5.0+(z+dh)/4.0));
383     }
384
385     private Image getImage() {
386     double x1,y1,z1,x2,y2,z2;
387     vs=0.0;
388     theta+=0.04;
389     final byte[] ba = new byte[600*500];
390     for (int j=0;j<500*600;j++) ba[j]=0;
391     vc=R*Math.cos(theta);
392     if (oscillate) dh=Math.sin(theta*1.3);
393     else dh=0.0;
394     for (int j=170;j<430;j++)
395         for (int k=320;k<380;k++)
396         ba[j+k*600]=(byte)(160.0*g(j-300.0,k-350.0));
397     x1=300.0+vc;y1=350;z1=dh;
398     theta+=2.0;
399     vc=R*Math.cos(theta);
400     theta-=2.0;
401     if (oscillate) dh=Math.cos(theta*1.3);
402     else dh=0.0;
403     for (int j=170;j<430;j++)
404         for (int k=120;k<180;k++)
405         ba[j+k*600]=(byte)(100.0*g(j-300.0,k-150.0));
406     x2=300.0+vc;y2=150;z2=dh;
407
408     final long t = System.currentTimeMillis();
409     final Dimension dim = new Dimension(getWidth(),getHeight());
410     Image f = new Image() {
411         public byte[] getData() { return ba; }
412         public Dimension getSize() { return dim; }
413         public long getTimeStamp() { return t; }
414         };
415
416     System.out.println("#Simulated: "+num+" "+
417                +x1+" "+y1+" "+z1+" "+
418                x2+" "+y2+" "+z2
419                );
420
421     return f;
422     }
423
424     static private boolean oscillate;
425     static public void setOscillating(boolean o) {oscillate=o;}
426     static public boolean getOscillating() {return oscillate;}
427
428 }
429
Popular Tags