Table of Contents

Obsidian as a Lab Notebook

In a previous post, I discussed why you would want to use Obsidian as an electronic lab notebook (ELN). Just to quickly recap: Obsidian is flexible, (pretty) open, and free to use. In this post, I will guide you through the practical steps of setting up Obsidian for effective use as an ELN. First, I will explain broadly how everything sticks together, followed by a more in-depth exploration of the configuration details at the end of the post.

How I use my Obsidian Lab Notebook

I keep separate note types for daily notes, experiments, meetings, talks, literature, stocks and samples, teaching, and ideas. Finally there are a few special pages. Each type of note has its own folder. I use the powerful Templater plugin to define templates for each note category.

Let's take daily notes as an example. Every day, a new note is automatically generated with the current date, and it's linked to the notes from the previous and next days for easy navigation. This note also includes a section for random thoughts. Plus, with the help of the Dataview plugin, I can add a table showing all the ongoing experiments with links for quick access.

Similarly, when I create a new experimental note, it's given a name automatically1). The note starts with some basic information that I need to fill in, such as a title, start date, checkboxes to mark if the experiment is finished or useful. Then, there's a space for adding tags to make finding experiments later easier. After that, I have a section to describe the experiment's background and purpose, ideally with links to previous or related experiments. Finally, there's a space to jot down notes about what happened during the experiment. To make note-taking even more convenient, I use a couple of extra plugins: Excalidraw for quick drawings and sketches (of a setup, or what you see in a microscope) and numerals for simple calculations right in the notebook. During experiments, you can paste in pictures you take, or just experimental data although obviously you may want to keep an eye on the file sizes.

You can make a customized template for each type of note, automating most of the formatting and naming processes. This way, you're left with the “straightforward” task of just filling the notes up with your science.

While this system works great, the real test is finding the notes you've already written. The simplest way to do this is by searching your database, where you can look for tags, keywords, or anything else that comes to mind. If you're unsure what to search for, the special pages I mentioned earlier come in handy. These pages contain tables, created using the Dataview plugin, containing all notes of each category. The tables show relevant properties, making it easy to sort and find the notes as you need.

Finally, stuff like scribbling down ideas and literature notes is also surprisingly convenient using obsidian, check out this guide for instance. This is not really part of a lab notebook I think, but it can be easily be done in obsidian as well.

Syncing and Backup

Of course, an electronic lab journal is pretty useless without it being possible to sync between devices, and it outright stupid to use one without some form of backup and/or syncing between devices. You probably want to be able to look at your lab notebook on your phone/tablet/laptop/whatever other device. And In case of a computer crash you don't want to lose all your experiments. For this you can use the payed built-in syncing system of Obsidian, but personally, I use Syncthing which also just works™. But in general any file syncing system (Dropbox, Google Drive, whatever) will probably work. Just make sure that you don't sync the folder containing Obsidian settings, this will lead to weird issues. And please, please, take a backup of this folder regularly in case something weird happens.

Actual usage

With this system in place, the structure and formatting of my lab journal requires minimal thought. And this is good, because I am easily distracted by such things. Everything is more-or-less automatically generated, so I have to focus on the science-y bits. Every morning, when I open Obsidian for the first time, a new daily note is generated if it does not exist yet. I can also make a quick to-do list for today. I can also make daily notes for days in the future, to plan a later to-do.

Starting new experiment is also very easy; when I start a new experiment, I just create a new experiment file, the name is auto-generated. If I collect data, I just use the auto-generated name: no chance of labeling something twice with te same name! I can past pictures of what is happening as well as experimental data or analysis. Easy peasy! All other categories of notes are similarly easy to generate, use, and order.

Final remarks

This is how I've configured Obsidian to serve as my electronic lab notebook. The strength of Obsidian lies in its flexibility—you can create your own categories, folder structure, tags, intricate templates, and virtually anything you desire. It allows for a high degree of customization, enabling you to craft sophisticated systems if that's what you like. After investing a bit of effort upfront, Obsidian operates almost seamlessly for me. I encourage you to give it a try, experiment with it, and change things to fit your working style. Below, I provide a bit more detail about my setup for those interested, but you should definitely adapt stuff to your needs. Don't be afraid to break things!

My Obsidian setup in more detail

Plugins

Folder structure

Templates

Daily notes
dailynote.md
---
date : <% tp.file.title %>
creationDate: <% tp.file.creation_date("YYYYMMDD") %>
---
<%*
let dateString = tp.file.title;
const year = parseInt(dateString.slice(0, 4), 10);
const month = parseInt(dateString.slice(4, 6), 10) - 1; // Months are 0-based in Date object
const day = parseInt(dateString.slice(6, 8), 10);
const dateToday = new Date(year, month, day);

const dateTomorrow = new Date(dateToday);
dateTomorrow.setDate(dateToday.getDate() + 2);

const dateYesterday = new Date(dateToday);
dateYesterday.setDate(dateToday.getDate() - 0);

// Convert the new date back to the YYYYMMDD format
const TomorrowString = dateTomorrow.toISOString().slice(0, 10).replace(/-/g, '');
const YesterdayString = dateYesterday.toISOString().slice(0, 10).replace(/-/g, '');
%>
<< [[<% YesterdayString %>]] | [[<% TomorrowString %>]] >>

## To do today:

- [ ] Blah

## Running experiments

```dataview
TABLE Title, StartDate as "Start date"
FROM ("experiments")
WHERE Completed != true
```

## Random notes
Experiments
experiment.md
---
StartDate: <% tp.date.now("YYYYMMDD") %>
EndDate: ""
Title: ChangeMe
Useful: false
Paper-worthy: false
Completed: false
---
<%* 
let d = tp.date.now("YYYYMMDD");
let label = "PJMS";
let index = 1;
let extension = ".md"
console.log("start:");
let name = d + "_" + label + ('00' + index).slice(-2);

function renameFile(newName) {
  possibleLoc = "experiments/" + newName + extension
  console.log("possibleLoc is: " + possibleLoc)
  return tp.file.exists(possibleLoc)
    .then((exists) => {
      if (exists) {
        console.log("possibleLoc rejected")
        index = index + 1;
        newName = d + "_" + label + ('00' + index).slice(-2);
        // Update the name variable with the new name here
        name = newName;
        return renameFile(newName);
      } else {
	    console.log("Will now rename:", name);
        return tp.file.rename(newName);
      }
    });
}

renameFile(name)
  .then(() => {
    console.log("Successfully renamed:", name);
  })
  .catch((error) => {
    console.error("Error:", error);
  });
%>

| Category       | Tags                   |
| -------------- | ----------------------- |
| ExperimentType |  #Experiment/placeholder |
| Project        | #Project/placeholder    |
| Device(s)      | #Device/placeholder    |

---
## Goal & background


## Procedure


## Results
Stock
stock.md
---
CreationDate : <% tp.date.now("YYYYMMDD") %>
UseBy: "Optional"
Compound: "ChangeMe"
CAS: "Optional"
Concentration: "ChangeMe"
Solvent: "ChangeMe" 
Location: "Optional"
Finished: false
---
<%* 
let d = tp.date.now("YYYYMMDD");
let label = "CHANGEME";
let index = 1;
let extension = ".md"
console.log("start:");
let name = d + "_" + label + ('00' + index).slice(-2);

function renameFile(newName) {
  possibleLoc = "stocks-samples/" + newName + extension
  console.log("possibleLoc is: " + possibleLoc)
  return tp.file.exists(possibleLoc)
    .then((exists) => {
      if (exists) {
        console.log("possibleLoc rejected")
        index = index + 1;
        newName = d + "_" + label + ('00' + index).slice(-2);
        // Update the name variable with the new name here
        name = newName;
        return renameFile(newName);
      } else {
	    console.log("Will now rename:", name);
        return tp.file.rename(newName);
      }
    });
}

renameFile(name)
  .then(() => {
    console.log("Successfully renamed:", name);
  })
  .catch((error) => {
    console.error("Error:", error);
  });
%>
All experiments
allexp.md
```dataview
TABLE Title, StartDate as "Start date", Completed, Useful
FROM ("experiments")
SORT StartDate DESCENDING
```
1)
In my case simply the date + my initials and a running number for that day, so for instance 20231023_PJMS01, but anything you can imagine will work, obviously