syntax = "proto3";

package biopb.ome;

option java_package = "biopb.ome";
option java_multiple_files = true;

import "biopb/ome/bindata.proto";
import "biopb/ome/light_source_setting.proto";
import "biopb/ome/detector_setting.proto";
import "biopb/ome/lightpath.proto";

// The Plane object holds microscope stage and image timing data
// for a given channel/z-section/timepoint.
//
message Plane {

    // This optional element is a hash of the plane's image data. 
    bytes hash_sha1 = 1;

    // The Z-section this plane is for. [units:none]
    // This is numbered from 0.
    optional uint32 the_z = 2;

    // The T-section this plane is for. [units:none]
    // This is numbered from 0.
    optional uint32 the_t = 3;

    // The C-section this plane is for. [units:none]
    // This is numbered from 0.
    optional uint32 the_c = 4;

    // Time since the beginning of the experiment.
    // Units are set by DeltaTUnit.
    optional float delta_t = 5;

    // The units of the DeltaT - default:seconds[s]
    string delt_t_unit = 6;

    // The length of the exposure.
    // Units are set by ExposureTimeUnit.
    optional float exposure_time = 7;

    // The units of the ExposureTime - default:seconds[s]
    string exposure_time_unit = 8;

    // The X position of the stage. Units are set by PositionXUnit.
    optional float postion_x = 9;

    // The Y position of the stage. Units are set by PositionYUnit.
    optional float postion_y = 10;
    
    // The Z position of the stage. Units are set by PositionZUnit.
    optional float postion_z = 11;

    // The units of the stage position - default:[reference frame]
    // Note: OME-XML allows different units for X-Y-Z 
    string position_unit = 12;

    repeated string annotation_ids = 15;
}


// There must be one per channel in the Image, even for a single-plane image.
// And information about how each of them was acquired is stored in the various
// optional *Ref elements.  Each Logical Channel is composed of one or more
// ChannelComponents.  For example, an entire spectrum in an FTIR experiment may
// be stored in a single Logical Channel with each discrete wavenumber of the
// spectrum constituting a ChannelComponent of the FTIR Logical Channel.  An RGB
// image where the Red, Green and Blue components do not reflect discrete probes
// but are instead the output of a color camera would be treated similarly - one
// Logical channel with three ChannelComponents in this case. The total number
// of ChannelComponents for a set of pixels must equal SizeC. The
// IlluminationType attribute is a string enumeration which may be set to
// 'Transmitted', 'Epifluorescence', 'Oblique', or 'NonLinear'. The user
// interface logic for labeling a given channel for the user should use the
// first existing attribute in the following sequence: Name -> Fluor ->
// EmissionWavelength -> ChannelComponent/Index.
message Channel {
    
    string name = 2;

    LightSourceSetting light_source_setting = 3;

    DetectorSetting detector_setting = 4;

    string FilterSet_id = 5;

    repeated string annotation_ids = 6;

    LightPath light_path = 7;

    // The number of samples the detector takes to form each pixel value. [units:none]
    // Note: This is not the same as "Frame Averaging" - see Integration in DetectorSettings
    optional uint32 samples_per_pixel = 8;

    // The method of illumination used to capture the channel.
    // NOTE: OME-XML uses enum
    string illumination_type = 9;

    // The optional PinholeSize attribute allows specifying adjustable pin hole
    // diameters for confocal microscopes. Units are set by PinholeSizeUnit.
    optional float pinhole_size = 10;

    // The units of the pin hole diameter for confocal microscopes -
    // default:microns[µm].
    string pinhole_size_unit = 11;

    // AcquisitionMode describes the type of microscopy performed for each
    // NOTE: OME-XML uses enum
    string acquisition_model = 12;

    // ContrastMethod describes the technique used to achieve contrast for each channel
    // NOTE: OME-XML uses enum
    string contrast_method = 13;

    // Wavelength of excitation for a particular channel. Units are set by
    // ExcitationWavelengthUnit.
    optional float excitation_wavelength = 14;

    // The units of the wavelength of excitation - default:nanometres[nm].
    string exitation_wavelength_unit = 15;

    // Wavelength of emission for a particular channel. Units are set by
    // EmissionWavelengthUnit.
    optional float emission_wavelength = 16;

    // The units of the wavelength of emission - default:nanometres[nm].
    string emission_wavelength_unit = 17;

    // The Fluor attribute is used for fluorescence images.
    // This is the name of the fluorophore used to produce this channel [plain text string]    
    string fluor = 18;

    // The NDfilter attribute is used to specify the combined effect of any neutral density filters used.
    // The amount of light the filter transmits at a maximum [units:none]
    // A fraction, as a value from 0.0 to 1.0.
    // 
    // NOTE: This was formerly described as "units optical density expressed as a PercentFraction".
    // This was how the field had been described in the schema from the beginning but all
    // the use of it has been in the opposite direction, i.e. as a amount transmitted,
    // not the amount blocked. This change has been made to make the model reflect this usage.
    optional float nd_filter = 19;

    // The PockelCellSetting used for this channel. This is the amount the
    // polarization of the beam is rotated by. [units:none]
    optional int32 pockle_cell_setting = 20;

    // A color (RGBA) used to render this channel 
    // If unset, the color should be solid white
    optional uint32 color = 21;

}

// The Pixels element should contain a list of BinData, each containing a single
// plane of pixels. These Pixels elements, when read in document order, must
// produce a 5-D pixel array of the size specified in this element, and in the
// dimension order specified by 'DimensionOrder'.
//
// All of the values in the Pixels object when present should match the same
// value stored in any associated TIFF format (e.g. SizeX should be the same).
// Where there is a mismatch our readers will take the value from the TIFF
// structure as overriding the value in the OME-XML. This is simply a pragmatic
// decision as it increases the likelihood of reading data from a slightly
// incorrect file.
//
message Pixels {

    // If specified, the length should match size_z
    repeated Channel channels = 1;

    // If specified, the length should match bindata.
    repeated Plane planes = 2;

    // Pixel values
    // Note: We only support BinData, not TiffData as in OME-XML
    // Note: use an empty list to indicate metadata-only
    repeated BinData bindata = 3;

    // A string describing the dimension order of the pixel data, e.g. "XYZCT"
    // The string must be a permutaion of these 5 letters even if some of the
    // dimension doesn't exist in the data.
    // NOTE: OME-XML uses enum
    string dimension_order = 4;

    // The variable type used to represent each pixel in the image.
    enum PixelType {
        // PT_ prefix to avoid c++ enum name collision
        PT_UNSPECIFIED = 0;
        PT_INT8 = 1;
        PT_INT16 = 2;
        PT_INT32 = 3;
        PT_UINT8 = 4;
        PT_UINT16 = 5;
        PT_UINT32 = 6;
        PT_FLOAT = 7;
        PT_DOUBLE = 8;
        PT_COMPLEX = 9;
        PT_DOUBLE_COMPLEX = 10;
        PT_BIT = 11;
    }
    PixelType pixel_type = 5;

    // The number of bits within the type storing each pixel that are significant.
    // e.g. you can store 12 bit data within a 16 bit type.
    // This does not reduce the storage requirements but can be a useful indicator
    // when processing or viewing the image data.
    //
    // Default (0) is all bits
    optional uint32 significant_bits = 6;

    // How the channels are arranged within the data block:
    // true if channels are stored RGBRGBRGB...;
    // false if channels are stored RRR...GGG...BBB...
    optional bool interleaved = 7;

    // This is true if the pixels data was written in BigEndian order.
    // If this value is present it should match the value used in BinData
    // or TiffData. If it does not a reader should honour the value used
    // in the BinData or TiffData. This values is useful for MetadataOnly
    // files and is to allow for future storage solutions.
    optional bool big_endian = 8;

    // Dimensional size of pixel data array [units:none]
    uint32 size_x = 9;

    uint32 size_y = 10;

    uint32 size_z = 11;

    uint32 size_c = 12;

    uint32 size_t = 13;

    // Physical size of a pixel. 
    optional float physical_size_x = 14;

    optional float physical_size_y = 15;

    optional float physical_size_z = 16;

    // physical size unit, default "µm"
    // Note: OME-XML allows different units for X-Y-Z
    string physical_size_unit = 17;

    // TimeIncrement is used for time series that have a global timing
    // specification instead of per-timepoint timing info. For example in a
    // video stream. Units are set by TimeIncrementUnit.
    optional float time_increment = 18;

    // time unit, default "s"
    string time_increment_unit = 21;

}
