npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

microplate

v2.7.1

Published

A module for parsing, reading & writing microtiter plate layouts in XSLX format.

Downloads

23

Readme

Microplate

The microplate package is built for parsing microtiter plate information from Excel sheets, validating the contents of plate layouts, and saving plate layouts into Excel or CSV files.

Layout formats

A spreadsheet with one or more plate layouts will be formatted like this:

plate-1  1       2		  3		...
A	     item-1  item-2
B                         item-3
C
D
.
.
.

plate-2  1      2		  3		...
A
B
.
.

Alternatively, the spreadsheet can be in tabular format, which also allows for providing multiple columns of data:

PLATE    POSITION   NAME    SCORE ...
plate-1   A1        item-1      5
plate-1   A2        item-2     15
plate-1   B3        item-3     10
.        .
.        .
.        .

The plate layout parser will return a list of all layouts it detects.

Installation

You can install this package with NPM:

npm install microplate

Usage

The examples in this section contain ECMAScript 2016 (ES7) code. Use equivalent ECMAScript 5 code where necessary.

Sheets

A sheet object is created from either an Excel sheet, converted CSV file, or other 2D-array sources. They are the intermediary format between files and plate layouts. For different ways to load sheets from Excel files, read Working with Excel files.

Parsing and validating plate layouts

Plate layouts are processed in three stages:

  1. Reading a workbook and selecting a sheet
  2. Parsing the sheet into a layout
  3. Validating the layout's contents

Parsing step

In this example we are parsing a grid-based sheet we've built from an array:

import {Sheet, PlateLayout} from 'microplate';

let sheet = new Sheet([
	['platename', 1, 2, 3],
	['A', 'item1', 'item2', 'item3'],
	['B', 'item1', 'item2', 'item3'],
	[]
])

let layouts = PlateLayout.parse(sheet, {
	default: 'name',
	converters: {
		name: 'string'
	}
});

PlateLayout.parse() always returns an array, because both grid and tabular formats support multiple plates. The converters option is a dictionary for enforcing types on values. default is only used with grid layouts.

Possible converters are:

name | description ------ | -------------------------------------------- number | numeric value string | string value number[] | array of numbers (comma separated list) string[] | array of strings (comma separated list) string(position) | well position

A list-based plate layout is processed like so:

let sheet = new Sheet([
	['plate', 'position', 'name', 'score value'],
	['platename', 'A1', 'item1', 5],
	['platename', 'A2', 'item2', 9],
	['platename', 'A3', 'item3', 11],
	['platename', 'B1', 'item1', 7],
	['platename', 'B2', 'item2', 9],
	['platename', 'B3', 'item3', 15],
	[]
])

let layouts = PlateLayout.parse(sheet, {
    aliases: {
    	'score': ['score value']
    }
    required: ['name', 'score'],
    converters: {
    	name: 'string',
    	score: 'number'
    }
});

The validation here makes use of aliases and required option values, for header name aliases and required columns respectively. The full .parse() function syntax:

PlateLayout.parse(sheet: Sheet, {
	default?: string,
	aliases?: {[name:string]: string[]},
	converters?: {[name:string]: string},
	required?: string[]
}): PlateLayout[]

Validation step

To validate each position in a plate layout, use PlateLayout.prototype.validate().

// dummy lookup function
function lookupItemByName(name) {
	return Promise.resolve({name: name}) 
}

try {
	let validatedLayout = layouts[0].validate({
		name: lookupItemByName
	});
} except(e) {
	// errors grouped by well position.
}	

The full .validate() function syntax:

PlateLayout.prototype.validate(
	validators: {[name:string]: (any) => Promise}, 
	parallel: boolean): Promise<PlateLayout>

Parsing and validating tables

In addition to plate layouts, the package contains a Table class. A table works just like a plate layout, with the difference that there are no well positions, but rows.

let sheet = new Sheet([
	['id', 'name'],
	[1, 'foo'],
	[2, 'bar']
])

let table = Table.parse(sheet);

try { // validation
    table = await table.validate({id: lookupByIdFunction});
} except (e) { 
	console.log('validation errors:', e)
}

for(let row of table) {
	console.log(row);
}

If parallel is false, the validator functions in Table functions will receive two arguments. The second argument will be an array with all previously processed rows. This is useful when importing a table where validation depends on values in previous rows.

You can create a Sheet from a Table like so:

let sheet = new Table([
	{id: 2, name: 'bar'},
	{id: 3, name: 'baz'}
]).toSheet();

Working with Excel files

The microplate package has some features that aid with import and export to Excel using xlsx. These examples here are for command-line use.

import fs from 'fs';
import {Workbook} from 'microplate';

let file = fs.readFileSync('./example.xlsx');
let workbook = Workbook.fromFile(file);

console.log(workbook.sheetNames()); // ['Sheet 1', 'Sheet 2']

let sheet1 = workbook.sheet('Sheet 1');
console.log(sheet1.name); // 'Sheet 1'

for(let sheet of workbook) { /* iterates through all sheets in a workbook */ }

let workbook2 = new Workbook({foo: new Sheet()}); // initialize a new Workbook.

You can also load a workbook from an <input/> in the browser. First, add a file input to your page:

<input type="file" accept=".xlsx" />

Now you can load files like so:

let input = document.querySelector('input[type=file]');

input.addEventListener('change', function () {
	if(this.files.length) {
		let fileReader = new FileReader();
		fileReader.onload = (e) => {	
			let workbook = Workbook.fromFile(e.target.result);
			console.log(workbook);
		});

		fileReader.readAsBinaryString(this.files[0]);
	}
});

To save a workbook in the browser, use e.g. filesaver.js :

import {saveAs} from 'filesaver.js';
let wb = new Workbook({foo: new Sheet()}); // initialize a new Workbook.
saveAs(wb.toBlob(), 'foo.xlsx');    

For more information, read Using files from web applications on MDN.