Lab Automation

How To Write A Hitpick Method in Hamilton Venus

Previous Article
Automation Tube List
Next Article
Robot Vacuum List
Comments (29)
  1. Tim says:

    Keiran,
    thanks for your great insight. In principal, how do you deal with EOF/BOF errors on SQL queries, e.g. when there is no hit?
    Best regards,
    Tim

  2. Keiran says:

    Hi Tim,

    The way I deal with the EOF/BOF errors when the SQL query has no matches is to use the error handling by user commands. What I do is wrap the file command in the error handler and then I have a few options. I can just proceed with the method writing a line to the logfile like “No hits found”, I can have the error handler warn the user that something is wrong and abort the method, or I can have everything in a loop and force the user back to the beginning to select a valid hitpick source file. It all depends on what the goal of the method is. One thing to note is that when using error handling by user it will trigger for every error on that step, which in a file command is ok cause any error will lead to the method crash.

    Hope that makes sense and thanks for reading!

  3. Tim says:

    Hi Keiran,
    thanks for your Reply. I’ll give it a try.
    Regards,
    Tim

  4. KRISTOF says:

    Hello Everyone,
    I am making a Method which requires a csv file which include a Source Plate, Source Well, Value to be Aspirated and the Destination of Dispense. Is anyone already made this method program? Can you be able to share the idea?

  5. Keiran says:

    Hi Kristof,

    I don’t have a method like that which I can share but I have written them before. Basically you would make the method as outlined aboved but you would also be making a destination sequence in addition to the source sequence. Same library and same steps. Then you run your aspirate from seq_source to seq_dest. Now you have volumes in that file as well so when you are reading in the file you should take those volumes and add them to arrays arr_source_vol and arr_dest_vol. When you do your aspirate and dispense you will use that array instead of the volume.

  6. KRISTOF says:

    Hello Keiran, Thank you for the reply. I will try to make the method now.

    By the way, regarding with the SequenceTool <– I am actually trying to make my own as it's not available in my system.

    Thanks a lot!
    Kristof

  7. Keiran says:

    I got the SequenceTool from our local Hamilton applications specialist, if you reached out to yours they would probably provide it.

  8. Heather says:

    Hello Keiran!
    I have tried to write this procedure for-ev-er! and finally have some success, so thank you! Has anyone else had issues opening .xls files (tells me can’t find the object but the path is correct). Ham manual, tutorials all differ as to whether to name the Sheet Name “Sheet1″, Sheet 1”, “Sheet1$” and I have tried them all. I did have success reading my data as a .csv, but the first column name reads in with a prepended set of characters like “i>>?SourcePlate” (but the ? is upsidedown). Apparently this is something called a UTF8 BOM, which is above my programming knowledge. Any idea how to get the first column heading to read without those characters? If I use the Column Spec Helper I just leave the characters in and it works, but would like to get rid of it.
    Thank you!

    1. Keiran says:

      Hey Heather,

      Yeah the manuals are a bit of a mess and it varies based on the type of file you are trying to read. In my experience csv is the easiest format as well but xls is possible. I use “Sheet1$” which is currently working in a number of methods I’m running. I tend to rename the sheets to something else like “PickingData” or something so it would be “PickingData$”.

      As to the first column issue, I’ve seen that too with files provided by my end users when they have generated the file in excel. Most of the files I used are outputs from other systems so we have control over the encoding and don’t see this issue. What I’ll often do for end users who are generating their own files is that I require them to also add a column titled “Index” as the first column with incrementing numbers from 1 to x. When I read the file in then the first column that has the issue is one that we aren’t actually using so I just ignore it and all the important information is in the other columns. This is of course a workaround but it works when you need to accept files that are being manually manipulated by end users where there is a high incident of the files having these little oddities. I can’t think of a file I’ve had issues with that were generated by another Hamilton or by one of our internal informatics systems.

      Hope that helps, thanks for reading!

  9. Heather Kundzicz says:

    Thank you! This is a work in progress, and I appreciate your input.

  10. Flamur Bytyqi says:

    is there a way to use a variable in the SQL statement?

  11. Flamur Bytyqi says:

    is there a way to use a variable in the SQL statement?
    I would like to use a variable in the SQL statement instead of [HitpickFile.csv]. I tried declaring the variable in the method and then use it in the SQL, but it does not work.

    [HitpickFile.csv]

    thank you
    Flamur

    1. Keiran says:

      Absolutely! You would want to use the string library and do something like this. Do not miss the single quotes that you need around the value in order for the query to be valid.

      str_SQLQuery is concatenated from the following 3 lines
      Line 1 = “SELECT * FROM [HitpickFile.csv] WHERE [Result >='”
      Line 2 = flt_Value (this is your variable)
      Line 3 = “‘”

      If you wanted to vary the file name instead then

      str_SQLQuery is concatenated from the following 3 lines
      Line 1 = “SELECT * FROM [”
      Line 2 = str_filepath (full path to your file making sure to have the double slashes that Hamilton wants)
      Line 3 = “] WHERE [Result >=’10.3′”

  12. Flamur says:

    Thank you very much for the explanation

    Somehow, I still get an error when I use a variable inside of the SQL statement

    thanks,
    Flamur

    1. Keiran says:

      I suggest tracing out the str_sql that you concatenated and seeing if it is correctly formatted. It is easy in complicated concatenations to miss a single ‘ and if you do then the whole query becomes invalid. If you are connecting to a database and not a file a very easy way is to copy the query from the trace and run it on the server. If it doesn’t work then the query is formatted wrong. If you post the query from the trace here I’m happy to take a look and see if I can pinpoint what is wrong.

  13. Flamur says:

    Thank you very much, Keiran, for your help.
    It looks like it is working now. For the current method that I wrote, when we start the method, I am having users navigate to the file location, and on line 2, I am still using a variable, however, instead of entering the full path, I am having users when they start the method to enter the “filename.csv” (whatever the file name is). This way is working fine.

    Thanks,

  14. Flamur says:

    I am getting another error. For some reason, it does not iterate over the .csv file. It always starts at the beginning of the .csv file. What am I doing wrong? I tried to paste the code here, but it does not let me.

    thanks,
    Flamur

    1. Keiran says:

      I’d probably need to see the method to troubleshoot that but my guess is either your sql query is specific to only the top line or that you are not looping over the file. Every time you open the file it will start at the top line, you need to open it and then loop over the file and do your reads inside the loop as follows.

      You want to do a File: Open and then name it something like “FILE_CSV_READ” then you want to loop over “FILE_CSV_READ” and then have the File: Read command inside that loop and the File: Close command outside the loop.

      You can send me an e-mail with more details since posting it doesn’t work here and I can take a look. Images or text from a log file. Do not send me a package file or actual method files as I will not import code from an unknown source onto one of my systems.

  15. Flamur says:

    Thank you very much for the explanation.
    For the aspirate dispense, I was using golden steps (Simple steps). And with the golden steps, it was not iterating over the file. It was always starting at the top line.
    When I changed to smart steps, now, it is iterating correctly. I am assuming that it has to do with the golden steps. I set the controlling sequence the same in both steps (in this example is AllHits)

    Thanks,

  16. A says:

    Hi Friends,
    I’m working on building sequences on a tilt station and find the tilt library to be difficult and inaccurate with the locations. I’ve been looping incremental virtual labware offsets to account for the change in Z and the change in -x (to get to the “corner” of the well where the liquid collects). The problem I have with this approach is that it applies the offset to all the positions in the sequence, but in reality each column has a slightly higher Z and a slightly smaller -X offset (cuz tilt). Is there a way I can systematically add offsets to each well independently?

    Thanks!

    1. Keiran says:

      Hi A,

      That’s a very interesting question and not a scenario I’ve needed to personally deal with. I think the way I would try and do this is to have the offsets being set as variables int_offsetX and int_offsetZ and then do math on each loop through the sequence where int_offsetX = int_offsetX + A or int_offsetZ = int_offsetZ – B. That only works if your offset changes per column and therefore you just need to tweak it at every loop. If your offset changes by row and therefore you need multiple offsets per loop then it gets more complicated.

      You could design a series of custom labwares with the offsets built into them and stack them on top of each other over on the tilt station then make a single sequence of that. You’d need to make a labware for each column or row, depending on where the offset changed, and then adjust the X and Z heights to have that built in. It’d be a pain to create the first time but once done you could save it to a template deck layout and have it ready to go all the time. Of course if you labware changes on the tilt station that means doing it for multiple types and it’s again gonna get annoying. Messing with Z like that could also have some complications with cLLD if you aren’t careful. I guess you could also make a carrier with 96 positions all at the different heights with a 9×9 raster and then make a tiny rack with a single container that fits there and populate it that way. Again a pain to do but I think it’d work once you got the dimensions right.

      If you figure out something novel here we’d love to hear what you did and how it worked out.

      Thanks for reading!

  17. A says:

    Hi Keiran,
    Yeah so we had been using 6 well plates where we needed to access each well in multiple locations (think multiple tips per well) throughout the method to both mix and to aspirate the liquid out of the well. In those cases we used a txt file to list the XYZ of each position. The key for that implementation was to create a rack at the origin (x0,y0,z0) and add “containers” with the XYZ offset which actually corresponds to the whole position (as opposed to the traditional use where it is an offset from the labware definition that’s built into the deck position). Hopefully that makes sense. This is hard to teach, it’s a lot to maintain and a pain to set up initially.
    For this particular question I wanted to simplify the process and use a defined 12 well labware and apply offsets when the plate is tilted since we only access 1 channel per well in this format. Considerations for this is, each column needs a different offset so we have adjust for each column AND we have to remove all the offsets when we lay the plate down flat so we can handle the lid. Lastly, we need to move to a hit pick so the offset will be dependent on which column the chosen wells are in. I have done layered labware before, but that gets messy, and I don’t want to have dangling config files for each method because our systems are heavily integrated.
    As I’m thinking about this more deeply I think a simple sequence definition for the tilted labware on the deck with the defined well corner positions is probably the most elegant but not super dynamic.

  18. Heather says:

    Hi Keiran,
    This site has helped me with HitPicks, and given me great info. I wish the Ham Venus forum was more expansive! I am now interested in learning to use the virtual labware library. There are no help files that come along with it, and I would love to see a simple sample program, heavily commented, lol. I’ve been messing with it in simulation but I’m not really sure what is happening (and I have limited instrument access time). If anyone is willing to share a .pkg file with me for something generic, that would be so cool. Never hurts to ask:)

    1. Keiran says:

      Hi Heather,

      I don’t usually make package files and share them on the net, mostly as I wouldn’t ever import a method onto one of my systems that wasn’t provided to me by someone I work with or a Hamilton representative.

      That being said we were talking about doing some deeper dive videos as training courses for specific advanced topics (hitpicks, dynamic deck loading, library creation, etc) and hosting those on a site like Udemy. We don’t really have the ability to do straight up walkthroughs on this blog but doing a narrated screen capture of me actually walking through step by step and constructing a demo method I think might be something really useful to our automation audience. Course that all takes a bit longer then writing up a blog post so realistically it’ll be a few months before I have the bandwidth to try it out.

      I just looked through my systems and unfortunately none of them have a help file for the virtual labware library either. For the most part it’s not terrible to use and whoever wrote it used good nomenclature to signal if a variable is an input or output and what type they are. A description of why you should care about a command with examples of why to use it or what the bind return value is would be nice.

      You should be able to string up a series of commands and then trace the outputs to the log file to see what it’s doing. If you aren’t sure what type of variable it’s outputting you can also use the string library to get the variable type. The one feature I do use a lot from this library is Move Sequence command. That lets you specify an X/Y/Z offset to make a sequence virtually move that direction. This is useful if say you want to pick up a plate off center. You move the source and destination sequence +10mm in X so now the iSwap will pick up the plate off center. You just need to remember to move both the source and destination back -10mm after the move else when you go to pipette the channels will be off as well. One nice thing is that the library does update the visual on the deck layout in simulation for these moves so you can clearly see what it is doing as it does it.

  19. Heather says:

    Keiran,
    Thank you so much. Even that last paragraph may have helped get my head into the Virtual LW process. I also would not open a random .pkg file for obvious reasons. A Udemy-type presentation would be great on any of these topics, and your readers would be so grateful, but as you noted, it takes time to put those together. I appreciate all your efforts so far:) ~H

  20. Christie says:

    Hi Keiran,
    Thanks so much for the Hamilton Venus tutorials and posts. They have been extremely helpful and using them I was able to write a library normalization script that utilizes different sizes of tips.

    Please consider writing more of these posts!

    1. Keiran says:

      Hi Christie,

      Thanks for reading and the kind words. I do intend to do some more Hamilton articles and maybe some videos on Udemy in the future once I wrap up my current batch of articles on building a Voron 3D printer. I’m very happy to see that people find these articles helpful, nothing like this site existed when I was learning so it was a lot of trial and error and I’m happy to be able to let others skip that step.

  21. kay says:

    Hi Keiran,
    In Hamilton Venus 4, do you know how to convert a String into a float point number?

    Thanks,

    Kay

    1. Keiran says:

      Hi Kay,

      You can use the string library, specifically the StrFVal command, which converts the digits within a string into the corresponding floating point value. It will only convert certain characters though so if you have something like a “x” in the middle of your numbers it will abort at that point. If you have the string “123456” then it will convert to the float 123456.0. If you have “123×456” it will only return the float 123.0.

      Hope that helps and thanks for reading!

Leave a Reply

Your email address will not be published. Required fields are marked *