licelfile-js
v1.0.0
Published
JavaScript library for parsing and processing Licel format data files (lidar measurement data)
Maintainers
Readme
licelfile-js
A JavaScript/TypeScript library for parsing and processing Licel format data files — lidar measurement data from Licel transient recorders.
Features
- Parsing: Parse Licel binary files to extract metadata and measurement profiles
- Data conversion: Convert raw little-endian int32 binary data into float64 values with proper per-channel scaling
- Safe round-trip: Save → load produces identical data; scaling is handled transparently
- Zip support: Load packs from and save packs to zip archives
- Profile selection: Filter profiles by photon type and wavelength across single files or entire packs
Installation
npm install licelfile-jsUsage
Load a Licel file
import { loadLicelFile } from 'licelfile-js';
const lf = loadLicelFile('path/to/file.licel');
console.log(lf.measurementSite, lf.nDatasets);Load from a Buffer
import { loadLicelFileFromBuffer } from 'licelfile-js';
const buf = fs.readFileSync('path/to/file.licel');
const lf = loadLicelFileFromBuffer(buf);Save a file
import { saveLicelFile } from 'licelfile-js';
saveLicelFile(lf, 'output.dat');Save to Buffer
import { writeLicelFileToBuffer } from 'licelfile-js';
const buf = writeLicelFileToBuffer(lf, 'output.dat');Load a pack by glob mask
import { newLicelPack } from 'licelfile-js';
const pack = newLicelPack('data/*.licel');Load a pack from zip
import { newLicelPackFromZip } from 'licelfile-js';
const pack = newLicelPackFromZip('archive.zip');Save a pack to zip
import { savePackToZip } from 'licelfile-js';
savePackToZip(pack, 'output.zip');Select profiles
import { selectProfile, selectProfiles } from 'licelfile-js';
// From a single file — match any polarization
const profile = selectProfile(lf, true, 532, '');
// From a single file — match specific polarization
const profile = selectProfile(lf, false, 355, 'o');
// Across all files in a pack — match any polarization
const profiles = selectProfiles(pack, false, 355, '');
// Across all files in a pack — match specific polarization
const profiles = selectProfiles(pack, true, 1064, 's');Filter files in a pack
import { filterPack } from 'licelfile-js';
// Keep only files from a specific site
const filtered = filterPack(pack, (lf) => lf.measurementSite === 'Observatory');
// Keep only files within a time range
const filtered = filterPack(pack, (lf) => {
return lf.measurementStartTime >= startOfDay &&
lf.measurementStopTime <= endOfDay;
});Filter profiles within a pack
import { filterProfilesInPack } from 'licelfile-js';
// Keep only analog profiles, drop files with none
const analogPack = filterProfilesInPack(pack, (pr) => !pr.photon);Collect matching profiles into a flat list
import { filterProfilesList } from 'licelfile-js';
// Get all analog profiles as a flat list
const analogProfiles = filterProfilesList(pack, (pr) => !pr.photon);
for (const pr of analogProfiles) {
console.log(pr.wavelength, pr.polarization);
}Glue analog and photon channels
import { glue } from 'licelfile-js';
// Glue 355nm analog+photon, compute ratio in [500; 2000]m
const glued = glue(lf, 355, 500, 2000, '');
// glued.deviceID === "BG"API
Types
LicelFile — a single measurement with metadata and profiles.
| Field | Type | Description |
|-------|------|-------------|
| measurementSite | string | Measurement location |
| measurementStartTime | Date | Start time |
| measurementStopTime | Date | Stop time |
| altitudeAboveSeaLevel | number | Lidar altitude |
| longitude | number | Longitude |
| latitude | number | Latitude |
| zenith | number | Zenith angle |
| laser1NShots | number | Laser 1 shot count |
| laser1Freq | number | Laser 1 frequency |
| laser2NShots | number | Laser 2 shot count |
| laser2Freq | number | Laser 2 frequency |
| nDatasets | number | Number of profiles |
| laser3NShots | number | Laser 3 shot count |
| laser3Freq | number | Laser 3 frequency |
| fileLoaded | boolean | Whether the file was loaded |
| profiles | LicelProfile[] | Measurement profiles |
LicelProfile — a single measurement channel.
| Field | Type | Description |
|-------|------|-------------|
| active | boolean | Channel active |
| photon | boolean | Photon counting mode |
| laserType | number | Laser type |
| nDataPoints | number | Number of data points |
| reserved | [number, number, number] | Reserved values |
| highVoltage | number | High voltage |
| binWidth | number | Bin width (meters) |
| wavelength | number | Wavelength (nm) |
| polarization | string | Polarization |
| binShift | number | Bin shift |
| decBinShift | number | Dec bin shift |
| adcBits | number | ADC bits |
| nShots | number | Number of shots |
| discrLevel | number | Discrimination level |
| deviceID | string | Device ID ("BC", "BT", "BG") |
| nCrate | number | Crate number |
| data | Float64Array | Scaled data points |
LicelPack — collection of LicelFile instances.
| Field | Type | Description |
|-------|------|-------------|
| startTime | Date | Earliest measurement start |
| stopTime | Date | Latest measurement stop |
| data | Map<string, LicelFile> | Files keyed by filename |
| zipCompressionLevel | number | Deflate level for zip (0–9) |
Functions
| Function | Description |
|----------|-------------|
| loadLicelFile(fname) | Load a Licel file from disk |
| loadLicelFileFromBuffer(buf) | Load a Licel file from a Buffer |
| saveLicelFile(lf, fname) | Save a LicelFile to disk |
| writeLicelFileToBuffer(lf, fname) | Serialize a LicelFile to a Buffer |
| newLicelPack(mask) | Load files matching a glob mask |
| newLicelPackFromZip(zipPath) | Load files from a zip archive |
| Function | Signature |
|----------|-----------|
| selectProfile | (lf, isPhoton, wavelength, polarization) => LicelProfile \| undefined |
| glue | (lf, wvl, h1, h2, polarization) => LicelProfile |
| setMaxDistOnFile | (lf, alt) => void |
| filterPack | (pack, cond) => LicelPack |
| filterProfilesInPack | (pack, cond) => LicelPack |
| packToProfilesList | (pack) => LicelProfile[] |
| filterProfilesList | (pack, cond) => LicelProfile[] |
| selectProfiles | (pack, isPhoton, wavelength, polarization) => LicelProfile[] |
| gluePack | (pack, wvl, h1, h2, polarization) => void |
| setMaxDistOnPack | (pack, alt) => void |
| savePack | (pack) => void |
| savePackToZip | (pack, zipPath) => void |
License
LGPL-3.0
