📖 Overview

lickcalc is a web-based application for analysing licking microstructure in rodent behavioural experiments. It processes timestamp data from licking events and provides detailed statistical analysis including:

  • Session-level analysis: Overall licking patterns over time
  • Microstructural analysis: Burst patterns, intraburst frequency, and lick durations
  • Statistical modeling: Weibull distribution fitting for burst probability
  • Data export: Excel exports with customizable data selection

The application is based on the lickcalc function from the trompy module. More details about installing trompy and using lickcalc to code lick microstructure can be found in the section, Using lickcalc without the app

🚀 Getting Started

Choose your data file format from the dropdown:

  • Med Associates: For .txt files from Med-PC systems. Options for column and array based
  • CSV/TXT: For comma-separated or tab-separated files
  • DD Lab: For DD Lab specific format files
  • KM Lab: For KM Lab specific format files

Upload your data file by either:

  • Dragging and dropping the file onto the upload area
  • Clicking "Select Files" to browse for your file
💡 Tip: The app will automatically detect columns in your file and populate the onset dropdown.
⚠️ File Validation: After upload, watch for validation messages. Green indicates successful parsing, red indicates errors with specific details about what went wrong. If you change the file type dropdown, the file will be re-parsed automatically.

Select which columns contain your data:

  • Onset Array: Column containing lick onset timestamps (required)
  • Offset Array: Column containing lick offset timestamps (optional, for lick duration analysis)
⚠️ Note: If you only have onset data, select "None" for the offset array. This will disable lick duration analysis but all other features will work normally.

Once your data are loaded:

  • Adjust analysis parameters using the sliders
  • View real-time updates in the graphs and statistics
  • Export data to Excel for further analysis
  • Add results to the results table

Customize default analysis parameters by uploading a configuration file:

  • Create a YAML file with your preferred default values
  • Download custom_config_example.yaml to use as a template
  • Upload via the configuration section (top right)
  • Settings will apply immediately and persist until app is reloaded/refreshed
💡 Pro Tip: Create different config files for different experiment types or for your lab to ensure consistent analysis parameters across your team.

📁 Supported File Formats

Med Associates - column

Text files from Med-PC systems with column format:

0.123 0.456 0.655 0.870 ...
Download example file
Med Associates - array

Text files from Med-PC systems with array format:

A: 0 0.123 0.456 0.655 0.870 1.013 5 1.195 1.378 1.801 9.211 9.502 ...
Download example file
CSV/TXT

Comma or tab-separated files with columns:

onset,offset,other 0.123,0.199,data 0.456,0.540,data 0.655,0.722,data 0.870,0.956,data ...
Download example file
OHRBETS

OHRBETS format.

31 12567 41 12567 31 12678 41 12678 31 12789 41 12789 ...
Download example file
DD Lab

Custom DD Lab format with specific parsing rules.

Download example file
KM Lab

Custom KM Lab format with specific parsing rules.

Download example file

Examples of each file format can be viewed and downloaded here or from the Github repository. If you need a custom format for your data please contact j.mccutcheon@uit.no.

📊 Session Analysis

Session Overview Graph

The session graph shows the overall pattern of licking throughout your experimental session. You can choose between two visualization modes:

Standard Histogram
Shows licks per time bin, allowing you to see periods of high and low licking activity.
Cumulative Plot
Shows the cumulative number of licks over time, useful for seeing overall session progress.
Bin Size Control

Adjust the time bin size to change the temporal resolution of your analysis. Smaller bins show more detail but may be noisier.

Session Length

By default, the session length will be based on the length of the data. If you want a specific session length, you can set it here or by using a custom config file.

🔬 Microstructural Analysis

Burst Analysis

Burst Definition: A sequence of licks separated by intervals shorter than the interburst interval threshold.

Key Metrics:
  • Number of Bursts: Total burst count in session
  • Mean Licks per Burst: Average burst size
  • Weibull Parameters: α and β parameters from probability distribution fitting
⚠️ Weibull Analysis Requirements: Weibull distribution fitting requires a minimum number of bursts (default: 10, configurable in config file). If fewer bursts are detected, Weibull statistics will show "N/A" and the burst probability plot title will indicate insufficient data.
Intraburst Frequency

Definition: The frequency of licking within bursts, calculated from interlick intervals (ILIs) within bursts.

Typical Values:
  • Normal range: 6-8 Hz
  • Displayed as histogram of ILIs
Lick Duration Analysis

Requirements: Both onset and offset data must be available.

Lick Lengths
  • Histogram of individual lick durations
  • Typically range from 50-200ms
  • Longer licks may indicate suboptimal placement of sipper
Long Licks
  • Licks exceeding the long lick threshold
  • Count and maximum duration reported
  • Can be excluded from analysis if desired

⚙️ Parameters Explained

🕐 Interburst Interval (IBI)

Typical range: 0.25 - 1.0 seconds

Default: 0.5 seconds

The minimum gap between licks that defines the end of one burst and the beginning of another. Shorter intervals = more bursts with fewer licks each.

📊 Minimum Licks per Burst

Typical range: 1 - 5 licks

Default: 3 licks

The minimum number of licks required to classify a sequence as a burst. Sequences with fewer licks are excluded from burst analysis.

⏱️ Long Lick Threshold

Typical range: 0.1 - 1.0 seconds

Default: 0.3 seconds

Licks longer than this duration are classified as "long licks" and indicate suboptimal sipper placement.

Remove Long Licks: Optional checkbox to exclude long licks from all analyses. When enabled, licks exceeding the threshold are filtered out. Requires offset data.

🔧 Configuration Files
Customizing Default Settings

You can customize default analysis parameters by uploading a custom configuration file:

Available Settings:
  • Microstructure parameters: Inter-burst interval, min licks per burst, long lick threshold, min bursts for Weibull analysis
  • Session settings: Default length, length unit, figure type, bin size
  • Output settings: Default animal ID
💡 Creating a Config File:
  1. Use YAML format (key: value pairs)
  2. Download custom_config_example.yaml to use as a template
  3. Upload via the config upload section in the app
⚠️ Note: Configuration changes apply immediately after upload and persist for the session. Invalid config files will be rejected with an error message.

💾 Data Export

Excel Export Options

Export your analysis results to Excel format with customizable data selection:

Available Data Types:
  • Session Histogram Data: Time bins and lick counts
  • Intraburst Frequency Data: ILI distributions
  • Lick Lengths Data: Duration histograms (requires offset data)
  • Burst Histogram Data: Burst size distributions
  • Burst Probability Data: Weibull fitting data
  • Burst Details Data: Individual burst information (start/end times, lick counts, etc.)
Export Features:
  • Multiple Excel sheets per export
  • Summary sheet with all key statistics
  • Animal ID and timestamp tracking
  • Source filename preservation
💡 Pro Tip: Use the Animal ID field to organize your data exports. This makes it easier to track multiple subjects in your analysis pipeline.

📋 Results Management

🔍 Epoch/Division Analysis
Analyzing Session Subdivisions

The app supports dividing your session into temporal or burst-based epochs for detailed analysis:

Analysis Epoch Options:
  • Whole Session: Analyze entire session (default)
  • Divide by 2/3/4: Split session into equal parts
  • First n Bursts: Analyze only the first N bursts
  • Between times: Analyze a specific time window (see below)
Division Methods:
  • By Time: Split session into equal time intervals
  • By Burst Number: Split based on burst count (e.g., first vs. last half of bursts)
Use Cases:
  • Compare early vs. late session behavior
  • Track learning or satiation effects over time
  • Analyze acquisition phase (first N bursts only)
  • Assess stability of licking patterns
💡 Example: Select "Divide by 2" and "By Time" to compare the first and second halves of your session. Each division will be added as a separate row in the results table.
⚠️ Important: When using divisions, each segment is analyzed independently. Statistics like Weibull parameters require a minimum number of bursts (default: 10) and will show "N/A" if insufficient data exists in a segment.
⏱️ Between Times Analysis
Analyzing Specific Time Windows

The "Between times" option allows you to analyze licking behavior within a custom time range, providing flexibility for targeted analyses:

How to Use:
  1. Select "Between times" from the Analysis Epoch dropdown
  2. Enter your desired Start time (when to begin analysis)
  3. Enter your desired Stop time (when to end analysis)
  4. Select the time Unit (seconds, minutes, or hours)
  5. Click "Add Current Results to Table"
💡 Unit Conversion: You can switch between seconds (s), minutes (min), and hours (hr) at any time. The values will automatically convert to maintain the same time duration.
Common Use Cases:
  • Baseline Period: Analyze initial behavior (e.g., 0-300s)
  • Post-Treatment: Focus on a specific window after intervention
  • Steady State: Skip initial adaptation period (e.g., 300-3600s)
  • Comparison Windows: Analyze multiple specific periods separately
  • Exclude Artifacts: Remove problematic time segments from analysis
⚠️ Note: Only licks occurring within the specified time window are included in the analysis. The Stop time must be greater than the Start time.
Example Workflow:

To compare early vs. late session behavior using specific time windows:

  1. Load your data file
  2. Select "Between times" and enter 0 to 5 minutes for early session
  3. Click "Add Current Results to Table"
  4. Change times to 25 to 30 minutes for late session
  5. Click "Add Current Results to Table" again
  6. Both analyses will appear as separate rows for comparison
Results Summary Table

Collect and compare results from multiple analyses in an interactive table:

Table Features:
  • Add Results: Add current analysis to comparison table
  • Edit Cells: Modify Animal IDs and other editable fields
  • Delete Rows: Remove unwanted entries
  • Export Options: Export individual rows or full table
  • Clear All: Remove all entries at once
Automatic Statistics:

When you have multiple entries, the table automatically calculates:

  • Sum: Sum of values across all rows
  • Mean: Average (mean) value across all rows
  • SD: Standard deviation
  • N: Sample size for each measure
  • SE: Standard error of the mean
💡 Workflow: Load each subject's data file, adjust parameters as needed, select your analysis epoch, then click "Add Current Results to Table". Repeat for all subjects, then export the full table for statistical analysis.
📦 Batch Processing
Processing Multiple Files at Once

The batch processing feature allows you to analyze multiple data files simultaneously using the same parameters, dramatically speeding up your workflow for large datasets.

How to Use Batch Processing:
  1. Set Parameters: Configure all analysis parameters (interburst interval, min burst size, etc.) in the main interface
  2. Choose Analysis Epoch: Select your desired epoch (whole session, divisions, first n bursts, or between times)
  3. Open Batch Modal: Click the "Batch Process Files" button at the top of the interface
  4. Upload Files: Drag and drop or click to select multiple data files (any supported format)
  5. Configure Export:
    • Check "Export per-file Excel" to get individual Excel files for each data file
    • Check "Include all sheets" to force export of all data sheets (histograms, bursts, etc.)
  6. Start Processing: Click "Start Batch Processing"
  7. Monitor Progress: Watch the progress indicator and status messages
  8. Download Results: When complete, download the ZIP file containing all results
Key Features:
  • Unified Parameters: All files processed with the same settings
  • Epoch Awareness: Respects your chosen analysis epoch (divisions, between times, etc.)
  • Auto Offset Detection: Automatically identifies offset columns when available
  • Progress Tracking: Visual feedback during processing
  • Results Table: All results automatically added to the comparison table
  • ZIP Export: Optional individual Excel files packaged in a convenient ZIP
  • Full Data Sheets: Per-file Excel exports include all data sheets (same as single-file export)
💡 Best Practice: Test your analysis on a single representative file first. Once you're satisfied with the parameters, use batch processing for the remaining files.
Export Options Explained:
Standard Batch Processing
Results are added to the comparison table only. No individual files created. Use this for quick data collection when you plan to export the full table later.
With Per-File Excel Export
Each data file gets its own Excel workbook (matching single-file export format) plus results in the comparison table. All Excel files are packaged in a ZIP. Use this when you need both individual detailed exports and a combined summary.
⚠️ Important Notes:
  • Batch processing uses automatic offset detection. The app will search for appropriate offset columns based on naming patterns and validation rules.
  • If a file cannot be processed (e.g., invalid format, missing data), an error will be reported but processing will continue for remaining files.
  • When using "Between times" with batch processing, the same time window is applied to all files.
  • Large batch jobs may take several minutes depending on file size and number of files.
Example Workflow:

Processing 20 experimental sessions with time-based divisions:

  1. Load one representative file and optimize your parameters
  2. Select "Divide by 4" and "By Time" to split each session into quarters
  3. Open the Batch Processing modal
  4. Upload all 20 data files
  5. Check "Export per-file Excel" for detailed per-subject records
  6. Click "Start Batch Processing"
  7. Wait for completion (progress bar will show X/20 files processed)
  8. Download the ZIP file containing 20 Excel workbooks
  9. Export the complete results table for statistical analysis (now containing 80 rows: 4 divisions × 20 subjects)

Advanced Batch Mode

Enable the toggle Advanced mode: select columns per file in the Batch modal to unlock per‑file controls and more flexible processing:

  • Per‑file onset/offset multi‑selects: Choose one or more onset columns for each file. Offsets are optional; if none are selected, analysis runs on onset times only. Each chosen onset column yields its own row(s) based on the selected epoch (whole session, divisions, first n bursts, between times, or trial‑based).
  • Automatic offset pairing: For each onset column, selected offsets are validated automatically (length difference ≤ 1, offset never before onset, and never after the next onset). Invalid pairs are skipped.
  • Global selections: Use the Global selections card at the top to pick onset/offset columns once, then click Apply to all files. Only columns that exist in a given file are applied; missing ones are ignored.
  • Trial‑based in batch: If the main epoch dropdown is set to Trial-based, the app auto‑detects trials using your minimum ITI and outputs one row per trial for each onset column. If no trials are detected, the whole session is treated as a single trial.
  • Per‑file Excel export: When enabled, each file also gets a session‑level Excel workbook (same structure as single‑file export) packaged into a ZIP. Per‑epoch/per‑onset sheets are planned for a future update.
💡 Tips: Keep column names consistent across files to make global apply most effective. If offsets differ slightly (e.g., one extra terminal lick), the app trims arrays to align automatically. You can mix supported file types; just set the correct File type before starting batch.
⚠️ Troubleshooting: If you see fewer rows than expected, confirm the selected onset columns contain data and that any chosen offsets pass validation. Trial‑based rows appear only when Trial-based is selected before launching the batch process.

📄 Advanced Use

Installing locally

Reasons to install locally include working offline, avoiding server outages, and enabling modification or customization. Follow these steps to install using Anaconda or Mamba:

  1. Clone the repository using git:
git clone https://github.com/uit-no/lickcalc.git
cd lickcalc
  1. Create and activate the environment:
conda env create -f environment.yml
conda activate lickcalc
  1. Run the app:
python app.py
  1. Open a browser and go to localhost:8050
Using underpinning functions

The application is based on a utility included in the package trompy. It can be installed via pip and is hosted on Github at https://www.github.com/mccutcheonlab/trompy. The function lickcalc calls a class, Lickcalc, and is documented fully in the parent package. trompy also includes the file parsers and some helper functions Some example code using the function follows:

from pathlib import Path import trompy DATAFOLDER = Path("../data") list_of_files = [ "med_test2.med", "med_test3.med" ] results_dict = {} for file in list_of_files: results_dict[file] = {} onset, offset = trompy.medfilereader(DATAFOLDER / file, varsToExtract=["b", "c"], remove_var_header=True ) lickdata = trompy.lickcalc(onset, offset=offset, #some variables ) results_dict[file]["total_licks"] = lickdata["total"] results_dict[file]["burst_number"] = lickdata["bNum"] results_dict[file]["licks_per_burst"] = lickdata["bMean"]

🔧 Troubleshooting

Problem: File won't upload or process
Solutions:
  • Check file format matches selected type
  • Ensure file is not corrupted
  • Verify file contains numeric timestamp data
  • Try a smaller test file first

Problem: Graphs are empty or not updating
Solutions:
  • Ensure onset array is selected correctly
  • Check that your data contains valid timestamps
  • Try adjusting parameter sliders
  • Refresh the browser page

Problem: Long licks showing "N/A" or not calculated
Solutions:
  • Ensure you have both onset and offset data
  • Select proper offset array (not "None")
  • Check that onset and offset arrays have matching lengths
  • Verify offset timestamps are after onset timestamps

Problem: Excel export fails or empty
Solutions:
  • Ensure data is loaded and analyzed first
  • Select at least one data type for export
  • Enter a valid Animal ID
  • Check browser download settings

Problem: Weibull parameters (α, β, r²) display "N/A"
Cause: Insufficient number of bursts for statistical fitting
Solutions:
  • Check if you have at least 10 bursts (default minimum threshold)
  • Decrease the interburst interval to identify more bursts
  • Decrease minimum licks per burst threshold
  • Ensure your time window captures enough bursting behavior
  • Adjust the minimum burst threshold in your config file if appropriate for your experiment

Problem: Re-uploading the same file doesn't update the analysis
Cause: Browser caching of file uploads
Solutions:
  • Change the file type dropdown before re-uploading (this triggers re-parsing)
  • Upload a different file, then upload the original file again
  • Refresh the browser page and upload again

Problem: Custom configuration file rejected
Solutions:
  • Ensure file is valid YAML format (check indentation with spaces, not tabs)
  • Use the provided custom_config_example.yaml as a template
  • Verify all parameter values are within valid ranges
  • Check for typos in parameter names
  • Ensure numeric values don't have quotes around them

📄 Theoretical and Practical Considerations

Historical background

Microstructural analysis was first described in Davis and Smith (1992) and has since then been used understand diverse phenomena. In-depth reviews on many of these, and microstructural parameters used to study them, are available (Johnson, 2018; Naneix et al., 2020; Smith, 2001). Briefly, although much of the foundational work on drinking microstruture was on licking for nutritive solutions (e.g., sucrose solutions), microstructural analysis can also be used to study intake of water (McKay & Daniels, 2013; Santollo et al., 2021), ethanol (Patwell et al., 2021), and other tastants such as non-caloric artificial sweeteners, sodium, and quinine (Lin et al., 2012; Spector & St. John, 1998; Verharen et al., 2019). Lick microstructure has been used to shed light on, for example, how licking is affected by neuropeptides (McKay & Daniels, 2013), enzymes in the mouth (Chometton et al., 2022), ovarian hormones (Santollo et al., 2021), nutrient restriction (Naneix et al., 2020), response to alcohol (Patwell et al., 2021), and diet (Johnson, 2012). The number of lick bouts over a session are thought to reflect postingestive feedback from the consumed fluid, wheras the number of licks in a bout are thought to reflect palatability of the solution.

Interpreting microstructure data

Lick microstructure can provide a great deal of interesting information about why an animal is drinking. Often, changes in microstructure are accompanied by changes in total intake, but this is not always the case: sometimes, equal intake will be achieved by quite different licking patterns that indicate changes in orosensory and postingestive feedback (Johnson et al., 2010; Volcko et al., 2020). Analyzing lick microstructure is therefore highly valuable in understanding how a manipulation affects appetite; if X causes an animal to feel more satiated after drinking, that may lead to a different interpretation than if X were to reduce the palatability of the solution.

Hardware considerations

Traditionally, researchers have used contact lickometers to detect individual licks. These generally pass a small amount of current through the animal and contacts with a (metal) spout cause completion of the circuit and lick detection. Recently, capacitive touch is more commonly used or deflections of a piezo or optic fibre. Several open-source lickometer designs are now available (e.g., Frie & Khokhar, 2024; Monfared et al., 2024; Petersen et al., 2024; Raymond et al., 2018; Silva et al., 2024).

Practical considerations: extended contacts

One problem that can arise are extended contacts with the spout, generally due to a fluid bridge forming between the animal's tongue and the spout. This can lead to very long "licks" that are in fact not individual licks but rather extended contacts. These can be prevented by ensuring that the sipper is recessed some distance from the wall of the chamber. To be sure that extended contacts do not affect the analysis, we recommend recording the offset time of each lick in addition to the onset time. In lickcalc, it is then possible to check for extended contacts and either adjust the behavioural setup (e.g., by moving the bottle back) or filter out extended contacts.

Setting up hardware to capture offsets

The instructions below refer to Med Associates hardware but the general principles can likely be transferred to other systems. First, in Med it is critical to adjust the jumper on the card so that the inputs from the lickometers are set to 'Level' mode rather than 'Toggle'. We then use state sets to track whether the tongue is in contact or not with the spout at all times but only write changes to this value to our data arrays. Example code can be downloaded from here and adapted as needed.

📚 Glossary

Burst
A sequence of licks separated by intervals shorter than the interburst interval threshold
Interlick Interval (ILI)
Time between consecutive lick onsets
Intraburst Frequency
Rate of licking within bursts, typically 6-8 Hz in rodents
Interburst Interval (IBI)
Minimum gap between licks that defines burst boundaries
Long Lick
Lick duration exceeding the long lick threshold, may indicate suboptimal sipper placement
Onset
Timestamp when tongue contact begins (required data)
Offset
Timestamp when tongue contact ends (optional, enables lick duration analysis)
Weibull Distribution
Statistical model used to fit burst size probability distributions (see Davis, 1998)
Microstructure
Fine-grained temporal patterns of licking behavior within and between bursts
Session
Complete behavioral recording period, analyzed for overall licking patterns