Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
User Manual 6
Manual manipulation of the handles
At this moment, it is important to highlight that algorithms can perform many tasks, consistently and at a speed that human observers are not able to process. However, it is very hard for an algorithm to have the power of a human observer. So, it may be the case that you have processed your files with the tracking algorithms, you display them and realised that maybe there are a few things that could be improved. It may be the case that there are very short tracks that do not really contribute to your analysis. It may be that there are some tracks that belong to a single neutrophil, but for a variety of reasons (there was a collision between neutrophils, there was a drop in the fluorescent intensity, the neutrophil moved up or down in the z-dimension, etc.) these tracks were broken, or perhaps you simply want to observe a track and its characteristics. This section introduces some tools for a user to interact manually with the tracks.
The command "selectNeutrophilsM" is a utility that allows you to select an individual track, and display its basic characteristics: initial and final position in X, Y, Z, T its number in the handles as well as the position of a point selected by the user.
To manually manipulate a track set you need to have a set with handles and a wound region previously selected, and then display it with plotTracks:
load('C:\Documents and Settings\Example1_mat_Ha\handles.mat') plotTracks(handles,2); view(6,30)
Once you have displayed the tracks, rotate them to a suitable angle of view, either with the command view(angle,elevation) or using the 3D rotation that is obtained when clicking the rotate3D on the main menu of the figure (red arrow). Then execute selectNeutrophilsM
selectNeutrophilsM will open a new window where the characteristics are displayed. Initially all values will be zero, but when you move the mouse and click next to any track, two dots will appear on the track, one on the initial point of the track, and one on the selected vertex of the track.
Please note that selectNeutrophilsM uses the subfunction select3D (http://www.mathworks.com/matlabcentral/fileexchange/11305-springlab/content/select3d.m).
For every track that is selected, the position together with other parameters will be displayed in the new window.
The Tortuosity is calculated as the ratio of the distance of the track (that is, the absolute distance that the neutrophil moves at every hop between time frames) and the distance between initial and final positions of the track. Thus a perfect straight line will have a Tortuosity of 1 and anything else will have values greater than 1. The Meandering Index sometimes also called Meandering Ratio is the inverse of the tortuosity and has a range of [0-1].
Look at the examples below, where tracks 5, 8, and 7 have been selected:
This last example presents an important observation. The Tortuosity of the track is 10.67 while the track seems to be straight. If we zoom into the figure, we can see that this line meanders considerably, but it is only when zoomed that it can be properly observed:
axis([60 90 91 96 1 handles.numFrames])
You can select as many points in the figure as you like. You can then move again the figure to a suitable view angle. After you have rotated the figure you need to deselect the rotate3D icon from the figure. Once you have selected (and taken note of track numbers, see below) just close the figure for the data and continue working.
Perhaps you might have noted that two tracks (red and dark blue) of this figure seem to be very closely positioned and the yellow track crosses in between them.
Very probably these tracks were created by 2 neutrophils that collided; the yellow track was kept intact but the blue and red were too far apart for the algorithms to join automatically. Once you have identified the number of the tracks (4 and 8 in this case), you merge them with the following command:
handles=joinTwoTracks(handles,4,8,woundRegion); figure plotTracks(handles,2); view(6,30)
There is a single track (light orange) instead of the previous ones. In the same way, it is possible to delete a track (say the brown on the right hand side) with the following command:
figure plotTracks(handles,2); view(6,30)
It may be the case that errors were made at the tracking process, most probably due to neutrophil collisions where the two neutrophils (let's call them neutrophils A and B) were too close to be properly identified. This will in turn create tracks where the neutrophil jumps from neutrophil A's path into the path of neutrophil B. In those cases it is necessary to break the track into two separate tracks and then proceed to join the tracks correctly.
To break a track, you need to identify the track to be broken AND the time at which it needs to be broken, that is, the frame at which the error occurred. For this purpose, selectNeutrophilsM, can be used as described above.
In the present example, we will break track number 2 at time 54:
handles = breakOneTrack(handles,2,54);
When we re-plot the data, we can see a shorter track and a new one where the last section of track 2 was.
At this point, it is handy to plot the tracks with their associated track numbers. Rather than using selectNeutrophilsM, you can use the plotting option 10 instead of 2 with plotTracks:
After this, you can join the tracks to correct the tracking problems:
handles = joinTwoTracks(handles,2,7);
And so on:
handles = joinTwoTracks(handles,1,9); handles = joinTwoTracks(handles,1,7); handles = joinTwoTracks(handles,1,7);
Notice how the track numbers go changing with every procedure, so when tracks 1 and 7 were joined, the one that was called 8 becomes 7 and then can be joined to the merger of 1 and 7 which was called 1.
In some cases, PhagoSight may generate a large amount of tracks, which span a considerable number of time points. In those cases, visualisation may become a complex and sometimes confusing process. There are several ways to deal with cases like these ones. Take for instance the image below, it contains 168 tracks that span 1,800 time points.
The first technique that can help the visualistion of these tracks is to reduce the field of view, by zooming in with the command 'view' like this:
axis([100 900 100 800 1 400])
With the current field of view it is easier to distinguish the tracks individually. If necessary we can repeat as many times as required:
axis([100 900 100 800 200 400])
At this moment we can call selectNeutrophilsM as previously and join/break/delete tracks. However, it is pretty evident than finding pairs between a large number of tracks can be considerably time consuming. To join a large number of tracks with one single instruction you can use 'joinMultipleTracks' in the following way:
handles = joinMultipleTracks(handles);
joinMultipleTracks looks for pairs of tracks that could be linked together by measuring the distance between the end of one track and the beginning of the other and at the same time looks for other candidate tracks that could be close by. Several selection criteria are employed to determined a distance beyond which two tracks cannot be linked, a minimum distance at which two possible candidates can be compared and one selected, etc. This function then calls joinTwoTracks for each pair of candidate Tracks. It can link many tracks in one go, in the previous example it can join more than 100. You can call this function several times as once two tracks have been linked, it is possible that others can be considered. If we look at the results with the previous example, we can see that fewer tracks (27) are present now.
Again we can reduce the field of view to compare with our previous case
axis([100 900 100 800 200 400])
All these changes are stored in the variable "handles", and once you delete a track or join two, the previous configuration is lost, i.e. THERE IS NO UNDO! So, it may be a good idea to keep the tracks in a separate variable just in case you do want to "undo" something so before you start doing any changes, store the handles in a different variable, for instance:
handlesPreManualLink = handles;
Then, do all the changes, and finally, save the two variables (and any other you want) into the new final handles file: