View Javadoc
1   package com.github.celldynamics.quimp.plugin.protanalysis;
2   
3   import java.awt.Point;
4   import java.awt.Polygon;
5   import java.io.IOException;
6   import java.io.Writer;
7   import java.util.ArrayList;
8   import java.util.Collections;
9   import java.util.Iterator;
10  import java.util.List;
11  
12  import org.apache.commons.lang3.tuple.ImmutablePair;
13  import org.apache.commons.lang3.tuple.Pair;
14  
15  /**
16   * Represent collection of tracks.
17   *
18   * @author p.baniukiewicz
19   * @see Track
20   */
21  public class TrackCollection {
22    /**
23     * Collection of pairs of tracks. Every pair originates from the same starting
24     * point. First element is backward tracks, second forward. Tracks can be empty
25     * but never null. Every track has different id.
26     */
27    private ArrayList<Pair<Track, Track>> bf;
28  
29    /**
30     * Indicates whether Track stored in this collection have initial point on first
31     * entry.
32     */
33    private boolean isInitialPointIncluded;
34  
35    /**
36     * Check if initial point is included in tracking.
37     *
38     * @return the isInitialPointIncluded
39     */
40    public boolean isInitialPointIncluded() {
41      return isInitialPointIncluded;
42    }
43  
44    private int nextId = 0;
45  
46    /**
47     * Instantiates a new track collection.
48     *
49     * @param isInitialPointIncluded the is initial point included
50     */
51    public TrackCollection(boolean isInitialPointIncluded) {
52      bf = new ArrayList<>();
53      this.isInitialPointIncluded = isInitialPointIncluded;
54    }
55  
56    /**
57     * Add pair of tracks to collection backwardTrack,forwardTrack.
58     *
59     * @param backward backward track
60     * @param forward  forward track
61     * @see #addPair(List, List)
62     */
63    public void addPair(Polygon backward, Polygon forward) {
64      Trackmics/quimp/plugin/protanalysis/Track.html#Track">Track tmpB = new Track(nextId++, null);
65      for (int i = 0; i < backward.npoints; i++) {
66        tmpB.add(new Point(backward.xpoints[i], backward.ypoints[i]));
67      }
68      Trackmics/quimp/plugin/protanalysis/Track.html#Track">Track tmpF = new Track(nextId++, null);
69      for (int i = 0; i < forward.npoints; i++) {
70        tmpF.add(new Point(forward.xpoints[i], forward.ypoints[i]));
71      }
72      bf.add(new ImmutablePair<Track, Track>(tmpB, tmpF));
73    }
74  
75    /**
76     * Add pair of tracks to collection.
77     *
78     * @param backward backward track points
79     * @param forward  forward track points
80     * @see #addPair(Polygon, Polygon)
81     */
82    public void addPair(List<Point> backward, List<Point> forward) {
83      Trackynamics/quimp/plugin/protanalysis/Track.html#Track">Track b = new Track(backward, nextId++, null);
84      b.type = Track.TrackType.BACKWARD;
85      Trackynamics/quimp/plugin/protanalysis/Track.html#Track">Track f = new Track(forward, nextId++, null);
86      f.type = Track.TrackType.FORWARD;
87      bf.add(new ImmutablePair<Track, Track>(b, f));
88  
89    }
90  
91    /**
92     * Get iterator over pairs of tracks (related to one starting point).
93     *
94     * @return iterator
95     */
96    public Iterator<Pair<Track, Track>> iterator() {
97      return bf.iterator();
98    }
99  
100   /**
101    * Get iterator over all tracks in collection.
102    *
103    * @return iterator
104    */
105   public Iterator<Track> iteratorTrack() {
106     List<Track> ret = new ArrayList<>();
107     for (Pair<Track, Track> p : bf) {
108       ret.add(p.getLeft());
109       ret.add(p.getRight());
110     }
111     return ret.iterator();
112   }
113 
114   /**
115    * Get unmodifiable list of all tracks.
116    *
117    * @return the bf list of all tracks (forward,backward)
118    */
119   public List<Pair<Track, Track>> getBf() {
120     return Collections.unmodifiableList(bf);
121   }
122 
123   /**
124    * Save tracks to csv file.
125    *
126    * <p>
127    * Format of the file is:
128    *
129    * <pre>
130    * Point 000 backward;[frame],10.0,11.0
131    * Point 000 backward;[index],110.0,111.0
132    * Point 000 forward;[frame],0.0,1.0,2.0
133    * Point 000 forward;[index],100.0,101.0,102.0
134    * Point 001 backward;[frame],30.0,31.0,32.0,33.0,34.0
135    * Point 001 backward;[index],130.0,131.0,132.0,133.0,134.0
136    * Point 001 forward;[frame],20.0,21.0,22.0,23.0
137    * Point 001 forward;[index],120.0,121.0,122.0,123.0
138    * </pre>
139    *
140    * <p>
141    * First columns is legend, next columns are indexes of rows and columns in maps
142    * returned from Q-Analysis. To obtain screen coordinates one can use xCoord and
143    * yCorrd maps. Tracks for each point are saved alternately in the order
144    * Backward - Forward. Each track occupies two rows for frame and outline
145    * position coordinates.
146    *
147    * @param writer where to save
148    * @throws IOException on error
149    */
150   public void saveTracks(Writer writer) throws IOException {
151     Iterator<Pair<Track, Track>> iter = iterator();
152     int pointno = 0;
153     // description
154     writer.write("# Each tracked point has two tracks connected to it: backward and forward\n");
155     writer.write("# Each track is defined by two coordinates: frame nummber and outline position\n");
156     writer.write("# Numbers are indexes of maQP arrays taht can be extracted from QCONF\n");
157     writer.write("# by FormatConverter.\n");
158     while (iter.hasNext()) {
159       Pair<Track, Track> track = iter.next();
160       StringBuilder sb = new StringBuilder();
161 
162       sb.append(String.format("Point %03d backward;[frame]", pointno));
163       sb.append(',');
164       for (Point p : track.getLeft()) {
165         sb.append(p.x);
166         sb.append(',');
167       }
168       sb.deleteCharAt(sb.length() - 1);
169       sb.append('\n');
170 
171       sb.append(String.format("Point %03d backward;[index]", pointno));
172       sb.append(',');
173       for (Point p : track.getLeft()) {
174         sb.append(p.y);
175         sb.append(',');
176       }
177       sb.deleteCharAt(sb.length() - 1);
178       sb.append('\n');
179 
180       sb.append(String.format("Point %03d forward;[frame]", pointno));
181       sb.append(',');
182       for (Point p : track.getRight()) {
183         sb.append(p.x);
184         sb.append(',');
185       }
186       sb.deleteCharAt(sb.length() - 1);
187       sb.append('\n');
188 
189       sb.append(String.format("Point %03d forward;[index]", pointno));
190       sb.append(',');
191       for (Point p : track.getRight()) {
192         sb.append(p.y);
193         sb.append(',');
194       }
195       sb.deleteCharAt(sb.length() - 1);
196       sb.append('\n');
197 
198       writer.write(sb.toString());
199       pointno++;
200     }
201   }
202 
203 }