Skip to the content.

logicleTransform

Unit Test codecov View logicleTransform.m on File Exchange

MATLAB class to apply the logicle transformation to a matrix and provide axes labels.


Installation

This call can be installed by any of the following methods:

MATLAB IDE users. (Click to expand) Download the latest logicleTransform.m.mltbx file from the releases page of this GitHub repository. Install this from MATLAB by double-clicking on toolbox the file.
For those with no MATLAB IDE (perhaps running MATLAB kernel in Jupyter Notebook). (Click to expand) Once you've downloaded the downloadGitHubRelease tool, you can install the logicleTransform.m toolbox file using the following at the MATLAB command line:
downloadGitHubRelease ( 'harleyday/logicleTransform.m', 'install', true );
For developers wishing to edit the code. (Click to expand) These instructions will place the source code in your working directory so that you can edit it as you wish.
For linux users
Go to your working directory for your MATLAB project, and extract the @logicleTransform directory from the latest release archive. This can be done using a curl one-liner:
cd path/to/working/directory
curl -L https://github.com/harleyday/logicleTransform.m/archive/v1.5.tar.gz | tar -xzf - --strip-components=1 logicleTransform.m-1.5/@logicleTransform/
For windows users
Download and extract the zip archive. The folder @logicleTransform should be placed into your working directory.

Usage

To apply the logicle transform, the parameters of the transformation must first be set. There are four parameters:

These parameters are specified when creating a new logicleTransform object:

obj = logicleTransform(T,W,M,A);
obj = logicleTransform(T,W,M,A,n_bins); % linear interpolation of transform with n_bins evaluated points

The optional n_bins parameter specifies the number of bins to be included in the fast logicle transform algorithm. When this parameter is specified, the fast logicle transform is used.

The object stores internal variables for later calculations based on data. In this way, the object guides the calculation of many data points efficiently.

The .transform() method calculates the transformed value of each element in turn, and returns a matrix of the same dimention as the input.

transformed_data = obj.transform(data);

The .inverse() method performes the inverse operation.

data = obj.inverse(transformed_data);

The variable data can be a matrix of any number of dimensions.

Axes ticks and labels can be set by acessing the Tick and TickLabel properties of the logicleTransform object.


Example 1

obj = logicleTransform(10000,2,4,0);
x = linspace(obj.inverse(0),obj.T,1000);
y = obj.transform(x);
plot(x,y);
ax = gca;
ax.YTick = obj.Tick;
ax.YTickLabel = obj.TickLabel;

alt text

Example 2

MATLAB object arrays may be used to operate on each column of a matrix using different transform parameters. This is particularly useful for data intended for scatter plotting where each axis requires a different transformation (as is generally the case when using a logicle transform). Create a row-vector of logicleTransform objects where each column corresponds to an exis of your plot. Then provide your data with the same number of columns, and each column will be processed according to the corresponding logicleTransform parameters.

rng default; % for reproducability
obj = [logicleTransform(1000,2,4,0),logicleTransform(10000,1,4.5,0.4,2^6)];
x = randn(1000,2)*50 + 10;
y = obj.transform(x);
scatter(y(:,1),y(:,2),'.');
ax = gca;
ax.XTick = obj(1).Tick;
ax.XTickLabel = obj(1).TickLabel;
ax.YTick = obj(2).Tick;
ax.YTickLabel = obj(2).TickLabel;

alt text


Run tests

You can run unit testing of this MATLAB class using the following static method. (Click to expand)
result = logicleTransform.test;
If the class is working, this will yield the following:
Checking logicleTransform.m toolbox performance using the packaged test suite.
Running logicleTransformTest
.......... ..
Done logicleTransformTest
__________

  12×6 table

                                                                              Name                                                                              Passed    Failed    Incomplete    Duration       Details   
    ________________________________________________________________________________________________________________________________________________________    ______    ______    __________    _________    ____________

    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testClass(type=logicleTransform)'                     }    true      false       false        0.094782    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testSize'                                             }    true      false       false       0.0085903    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testRejectWrongInputSize'                             }    true      false       false        0.019347    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformation1d'                                 }    true      false       false         0.06245    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformation2d'                                 }    true      false       false        0.071034    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformationNd'                                 }    true      false       false        0.011476    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testClass(type=logicleTransform)'}    true      false       false        0.043506    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testSize'                        }    true      false       false       0.0008899    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testRejectWrongInputSize'        }    true      false       false        0.011629    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformation1d'            }    true      false       false        0.014922    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformation2d'            }    true      false       false        0.045648    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformationNd'            }    true      false       false       0.0061737    {1×1 struct}

  Tests passed with no errors. Enjoy!
  User manual can be found at the GitHub Pages site.
If there is a bug somewhere, this test suite might detect it and return something like:
Checking logicleTransform.m toolbox performance using the packaged test suite.
Running logicleTransformTest

================================================================================
Error occurred while setting up or tearing down logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high].
As a result, all logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high] tests failed and did not run to completion.
    ---------
    Error ID:
    ---------
    'logicleTransform:ParameterError'
    --------------
    Error Details:
    --------------
    Error using logicleTransform (line 35)
    We require T > 0
    
    Error in logicleTransformTest/testLogicTranformConstructor (line 29)
                testCase.obj1d = logicleTransform(inputs_1{:});
================================================================================

================================================================================
Error occurred while setting up or tearing down logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low].
As a result, all logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low] tests failed and did not run to completion.
    ---------
    Error ID:
    ---------
    'logicleTransform:ParameterError'
    --------------
    Error Details:
    --------------
    Error using logicleTransform (line 35)
    We require T > 0
    
    Error in logicleTransformTest/testLogicTranformConstructor (line 29)
                testCase.obj1d = logicleTransform(inputs_1{:});
================================================================================

Done logicleTransformTest
__________

Failure Summary:

     Name                                                                                                                                                  Failed  Incomplete  Reason(s)
    =====================================================================================================================================================================================
     logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testClass(type=logicleTransform)                         X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testSize                                                 X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testRejectWrongInputSize                                 X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformation1d                                     X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformation2d                                     X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformationNd                                     X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testClass(type=logicleTransform)    X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testSize                            X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testRejectWrongInputSize            X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformation1d                X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformation2d                X         X       Errored.
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformationNd                X         X       Errored.
  12×6 table

                                                                              Name                                                                              Passed    Failed    Incomplete    Duration       Details   
    ________________________________________________________________________________________________________________________________________________________    ______    ______    __________    _________    ____________

    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testClass(type=logicleTransform)'                     }    false     true        true        0.0020224    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testSize'                                             }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testRejectWrongInputSize'                             }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformation1d'                                 }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformation2d'                                 }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters,inputs_2=transform_parameters,torance=high]/testTransformationNd'                                 }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testClass(type=logicleTransform)'}    false     true        true        0.0008519    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testSize'                        }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testRejectWrongInputSize'        }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformation1d'            }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformation2d'            }    false     true        true                0    {1×1 struct}
    {'logicleTransformTest[inputs_1=transform_parameters_and_n_bins,inputs_2=transform_parameters_and_n_bins,torance=low]/testTransformationNd'            }    false     true        true                0    {1×1 struct}

Logicle Transform class contains errors. Please register this issue at the GitHub repository issues page.
  Thank you for your time, and sorry for the inconvenience.

USEFUL TIP

Using class folders as documented here is a useful way to keep this (and other classes you may have written) separated in your filesystem to prevent confusion. In this case, download this repository, and place it in a folder called @logicleTransform in your working directory. This can be achieved using the command above.


Algorithms were developed by:
Moore WA, Parks DR. Update for the Logicle Data Scale Including Operational Code Implementations. Cytometry Part A : the journal of the International Society for Analytical Cytology. 2012;81(4):273-277. doi:10.1002/cyto.a.22030. Note that Moore and Parks’ code is no longer hosted at the link provided in the supplmentary material of this paper. It was moved to this GitHub repository.

An implementation in R (which actually uses the compiled C/C++ code by the above authors) is available from Bioconductor, in the “flowCore” package. To install this package in R, use the commands:

if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")

BiocManager::install("flowCore")