Work less, produce same

UPDATE: All the files have been added to my GitHub
UPDATE 2: Some change were made, details in the end of the post

I’m somewhat lazy, but I also try to be productive, the result of that is when I have an assignment a lot of time is spent trying to find how to accomplish the job quicker, over actually doing the work. The good thing for you, is that the time I spent can make your work faster too.

“I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.”

quote commonly attributed to Bill Gates, but just like most of the quotes you see on Facebook, he probably never said it (although it does fit the spirit of this article).

These are general guidelines, its unlikely that your workflow is exactly like mine, hopefully you can still apply some of these tips to your workflow.
In my work I use a program called cell profiler it lets you analyze picture of cells from the microscope, and I will show my optimization process for it.

this is the unoptimized workflow:

1.Open the picture.

pic 1: dashboard

2. Make the picture full screen.

pic 2: full screen

3. Click the zoom button.

pic 3: zoom button

4. Zoom in the part that interest me (in this case the tip of the root).

pic 4: zooming in

5. Click the zoom button to get out of zoom mode.

pic 5: out of zoom mode

6. Press F to go to freehand select mode.

pic 6: F has been pressed

7. Select the silhouette of the root.

pic 6: silhouette

8. Press done.

pic 8: done button

Rinse and repeat until all the pictures have been analyzed (they come in batches of a thousand).

I wanted to make this faster by using shortcuts, the first thing was looking in the documentation for shortcuts that were already in the program, after all F does something I thought that every action could be performed with the keyboard, it could not, so I just had to make my own shortcuts using Autohotkey.

Autohotkey is a program that lets you complete actions using keystrokes . You can set CTRL+J to write your full name for example, I will show you how to use it and as you’ll see the options are limitless.

This is how you write a script:

parts of this were taken from the autohotkey documentation for a full tutorial give them a visit.

1.download Autohotkey.

pic 9: download

2. after downloading, right click on your desktop go to new and Autohotkey script.

pic 10: new script

3. A new file will appear, rename it if you want, then right click on it and go to edit script

pic 11: edit script

4. A new notepad window should appear, we are going to write the script under all of that text.

pic 12: the script is open

the basic syntax of the program is:

 the keystroke ::
the resulting action
return

“ :: ” separates the trigger keystroke from the rest, Anything to the left of “ :: ” are the keys you need to press.

“return ” has to be in the end of end of every script, it stops the code from going any further. This will prevent many issues when you start having a lot of stuff in your scripts.

Here is a very basic script containing a hotkey which types text using the “Send” command when the hotkey is pressed:

^j::
Send, My First Script
return

“ ^ ” means the “ctrl” key in your keyboard, so in this script every time you press “ctrl” and “ j ” the program will write “My First Script” .

Try it out to check that everything is working, don’t forget the comma after the send command.

5. This is how it should look like

pic 12: the script is written

6. Press close and save.
double click in the file, now your script is running, an icon should appear on the bottom right of your screen (beside the clock) if it doesn’t appear press the ^ beside it, it could be hiding there.

pic 13: icon

7. Press “ ctrl+j ” in any palce that accepts texts, if its working it should write “My First Script”

pic 14: test

8. To make the script stop running right click on the icon and press exit.

pic 15: exit

now that we can write basic scripts, we can go to actually useful stuff. The first step in my work after the image is open is :

2. Make the picture full screen.

So I just googled “autohotkey make window full screen” and the first result tells me about the “WinMaximize” command and how to use it:

 WinMaximize , WinTitle, WinText, ExcludeTitle, ExcludeText

we can ignore most of the variable, the only relevant for us are “WinMaximize” (the command itself) and “WinTitle” (which window to maximize).
I want to use the “ g ” key to make the active window (the window I’m using) full screen, so:

g::
WinMaximize, A
return

“A” tells the program that the window that I want maximized is the one I’m using.

next step to optimize:

3. Click the zoom button.

this one is a little trickier it requires the mouse to go to a specific point in the screen and click it, just like the last one I googled “autohotkey mouse click”

MouseClick , WhichButton, X, Y, ClickCount, Speed, DownOrUp, Relative

now we need to find the XY coordinates of the zoom button, after researching a bit I found that Autohotkey comes with “Window spy” that will tell us exactly that.

I typed window spy in the start menu, and there it was

pic 16: window spy

checked “follow mouse” put the mouse over the button and wrote down the coordinates (in my case 143, 38).

pic 17: window spy open

I want both actions to happen together so I added it to the previous command this is how it looks like:

g::
WinMaximize, A
MouseClick, left, 143, 38
return

now “g” will make the window full screen and after that will click on the zoom button.
The next step:

4. Zoom to the part that interest me (in this case the tip of the root).

cannot be automated so:

5. Click the zoom button to get out of zoom mode.

6. Press F to go to freehand select mode.

same as before, this time with the “ r” key.

r::
MouseClick, left, 143, 38
send, f
return

step 7 is:

7. Select the silhouette of the root.

also cannot be automated so:

8. Press done.

e::
MouseClick, left, 890, 983
return

but since the next step is going back to the first, I can add the first and second steps to this command

e::
MouseClick, left, 890, 983
WinMaximize, A
MouseClick, left, 143, 38
return

so the final result is:

1. Press “g”
2. Zoom
3. Press “r”
4. Draw
5. Press “e”

this is the first cycle, the subsequent one is different because “e” performs step 1, so it becomes:

1. Zoom
2. Press “r”
3. draw
4. Press “e”

much shorter than what we started with, right?

Eight steps, that involved moving the mouse to out of the frame, became four in which the mouse stays on the picture the whole time (making the process even faster).

I measured how long it took before and after.
The before average was 01:30 for ten pictures making 9 seconds per picture on average (tested three times and averaged).
After the optimization the average became 58 seconds making the new average 5.8 seconds per picture which doesn't sound like a huge time saver but since I have to do on average a thousand pictures, before it would take me one hour and 50 minutes while now it takes me 1 hour 36, and considering I have to do this twice a month (sometimes more) it really stacks up.

Hope you liked that and let me know if you have any questions and tell me how you optimized your workflow, would love to hear it.

I’ve been tweaking the AutoHotKey script, one thing that bothered me is that every time an automated click happen the cursor would be at where the click happened, so I would have to reposition the cursor every time from the top of the page, so first I just experimented with the command:

MouseMove, 719, 427

which takes the mouse to the center of the screen, but it was still jarring, I still had to look for the cursor, so I searched for a command that would click and then come back to where the cursor was before, after a bit of searching I found it:

MouseGetPos CurX, CurY      ;Saves the position of the cursor
MouseClick, left, 2012, 437 ;Click on the desired place
MouseMove %CurX%, %CurY%, 0 ;Return to the place you saved before

Its surprisingly simple, this is how it looks in context:

g::
WinMaximize, A ;
MouseGetPos CurX, CurY
MouseClick, left, 143, 38 ;
MouseMove %CurX%, %CurY%, 0
return ;
r::
MouseGetPos CurX, CurY
MouseClick, left, 143, 38 ;
MouseMove %CurX%, %CurY%, 0
send, f ;
return ;
e::
MouseGetPos CurX, CurY
MouseClick, left, 890, 983 ;
sleep, 250 ;wait a little
WinMaximize, A ;f
MouseClick, left, 143, 38 ;
MouseMove %CurX%, %CurY%, 0
return ;

Um Biólogo que gosta de escrever