blink1073 / tifffile

Deprecated: Read and write image data from and to TIFF files.
Other
61 stars 41 forks source link

Couple of issues with ScanImage files #37

Open ecobost opened 6 years ago

ecobost commented 6 years ago

Hi, Thanks for the updates and the change logs. I've found a couple of minor issues when reading ScanImage tiff files:

  1. When the file has no ROI data, calling file.scanimage_metadata fails because the roidata returned from read_scanimage_metadata is None and dict.update(None) (here: https://github.com/blink1073/tifffile/blob/master/tifffile/tifffile.py#L2606) throws a TypeError: 'NoneType' object is not iterable. Changing that line to result.update(roidata if roidata is not None else {}) avoids the error but the JSON reader (here https://github.com/blink1073/tifffile/blob/master/tifffile/tifffile.py#L6795) still throws a warning:
    /data/tifffile/tifffile/tifffile.py:6344: UserWarning: invalid JSON 'b'''
    warnings.warn("invalid JSON '%s'" % data)
  2. Older versions of ScanImage (<= 5.1) are not correctly detected by is_scanimage (here https://github.com/blink1073/tifffile/blob/master/tifffile/tifffile.py#L3720). Changing the property to this:
    @property
    def is_scanimage(self):
        """Page contains ScanImage metadata."""
        info = self.description + '\n' + self.software
        return bool(re.search(r'SI.?\.VERSION_MAJOR', info))

    solves it but throws a warning when reading the metadata:

    
    In [15]: t = tifffile.TiffFile('/data/scanreader/data/scan_5_1_001.tif')

In [16]: t.is_scanimage Out[16]: True

In [17]: t.scanimage_metadata /data/tifffile/tifffile/tifffile.py:2614: UserWarning: scanimage_description_metadata failed: could not convert string to float: 'zeros(1,0)' warnings.warn("scanimage_description_metadata failed: %s" % e) Out[17]: {}

I think it is better if it says that it is a ScanImage file even if it cannot read the metadata.

Here's the output for `t.__str__(2)` in case you want to take a look at it; essentially all info is in the ImageDescription tag.

TiffFile 'scan_5_1_001.tif' 811.94 MiB LittleEndian SCANIMAGE 6000 Pages

TiffPageSeries 0 6000x256x256 int16 IYX Generic 6000 Pages

TiffPage 0 @104 256x256 INT16 MINISBLACK MEMMAPPABLE SCANIMAGE

TiffTag 256 ImageWidth 1H @306 256 TiffTag 257 ImageLength 1H @306 256 TiffTag 258 BitsPerSample 1H @306 16 TiffTag 259 Compression 1H @306 NONE TiffTag 262 PhotometricInterpretation 1H @306 MINISBLACK TiffTag 270 ImageDescription 10476s @320 "frameNumbers = 177001\nacquisitionNumbers = 1\nframeNumb TiffTag 273 StripOffsets 16I @10796 (10928, 19120, 27312, 35504, 43696, 51888, 60080, 68272, 76464 TiffTag 274 Orientation 1H @10868 TOPLEFT TiffTag 277 SamplesPerPixel 1H @10868 1 TiffTag 278 RowsPerStrip 1H @10868 16 TiffTag 279 StripByteCounts 16I @10860 (8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192 TiffTag 282 XResolution 2I @304 (1207959552, 16777216) TiffTag 283 YResolution 2I @312 (1207959552, 16777216) TiffTag 284 PlanarConfiguration 1H @328 CONTIG TiffTag 296 ResolutionUnit 1H @328 INCH TiffTag 339 SampleFormat 1H @328 INT

IMAGEDESCRIPTION frameNumbers = 177001 acquisitionNumbers = 1 frameNumberAcquisition = 177001 frameTimestamps_sec = 5343.276217350 acqTriggerTimestamps_sec = -0.000091800 nextFileMarkerTimestamps_sec = -1.000000000 endOfAcquisition = 0 endOfAcquisitionMode = 0 dcOverVoltage = 0 epoch = [2016 9 19 15 18 52.929] auxTrigger0 = [] auxTrigger1 = [] auxTrigger2 = [] auxTrigger3 = [] I2CData = {} scanimage.SI.TIFF_FORMAT_VERSION = 1 scanimage.SI.VERSION_MAJOR = '5.1' scanimage.SI.VERSION_MINOR = '0' scanimage.SI.acqsPerLoop = 1 scanimage.SI.active = false scanimage.SI.extTrigEnable = false scanimage.SI.focusDuration = Inf scanimage.SI.hBeams.active = false scanimage.SI.hBeams.directMode = false scanimage.SI.hBeams.enablePowerBox = false scanimage.SI.hBeams.flybackBlanking = true scanimage.SI.hBeams.interlaceDecimation = 1 scanimage.SI.hBeams.interlaceOffset = 0 scanimage.SI.hBeams.lengthConstants = 195 scanimage.SI.hBeams.powerBoxEndFrame = Inf scanimage.SI.hBeams.powerBoxStartFrame = 1 scanimage.SI.hBeams.powerBoxes.rect = [0.25 0.25 0.5 0.5] scanimage.SI.hBeams.powerBoxes.powers = NaN scanimage.SI.hBeams.powerBoxes.name = '' scanimage.SI.hBeams.powerBoxes.oddLines = true scanimage.SI.hBeams.powerBoxes.evenLines = true scanimage.SI.hBeams.powerLimits = 50 scanimage.SI.hBeams.powerUnits = 'percent' scanimage.SI.hBeams.powers = 38 scanimage.SI.hBeams.pzAdjust = true scanimage.SI.hBeams.stackEndPower = NaN scanimage.SI.hBeams.stackStartPower = NaN scanimage.SI.hBeams.stackUseStartPower = true scanimage.SI.hBeams.stackUserOverrideLz = 1 scanimage.SI.hChannels.active = false scanimage.SI.hChannels.channelAdcResolution = {16 16 16 16} scanimage.SI.hChannels.channelAvailableInputRanges = {[-1 1] [-0.5 0.5] [-0.25 0.25]} scanimage.SI.hChannels.channelDisplay = [1;2] scanimage.SI.hChannels.channelDisplayFunction = {'displayStripe' 'displayStripe' 'displayStripe' 'displayStripe'} scanimage.SI.hChannels.channelInputRange = {[-1 1] [-1 1] [-1 1] [-1 1]} scanimage.SI.hChannels.channelLUT = {[0 32767] [0 6878] [0 100] [0 100]} scanimage.SI.hChannels.channelMergeColor = {'green';'red';'red';'red'} scanimage.SI.hChannels.channelName = {'Channel 1' 'Channel 2' 'Channel 3' 'Channel 4'} scanimage.SI.hChannels.channelOffset = [-1554 -1388 -72 -272] scanimage.SI.hChannels.channelSave = [1;2] scanimage.SI.hChannels.channelSubtractOffset = [true true true true] scanimage.SI.hChannels.channelType = {'stripe' 'stripe' 'stripe' 'stripe'} scanimage.SI.hChannels.channels = {} scanimage.SI.hChannels.channelsActive = [1;2] scanimage.SI.hChannels.channelsAvailable = 4 scanimage.SI.hChannels.loggingEnable = 1 scanimage.SI.hChannels.logicalChannelInputRange = {} scanimage.SI.hChannels.logicalChannelOffset = zeros(1,0) scanimage.SI.hChannels.logicalChannelSubtractOffset = zeros(1,0) scanimage.SI.hConfigurationSaver.active = false scanimage.SI.hConfigurationSaver.cfgFilename = 'C:\Users\scanimage\Documents\SI settings\piezo.cfg' scanimage.SI.hConfigurationSaver.cfgLoadingInProgress = false scanimage.SI.hConfigurationSaver.fastCfgAutoStartTf = [false;false;false;false;false;false] scanimage.SI.hConfigurationSaver.fastCfgAutoStartType = {[];[];[];[];[];[]} scanimage.SI.hConfigurationSaver.fastCfgCfgFilenames = {'';'';'';'';'';''} scanimage.SI.hConfigurationSaver.usrCfgFileVarName = 'scanimage_components_ConfigurationSaver__configFileName' scanimage.SI.hConfigurationSaver.usrFilename = 'C:\Users\scanimage\Documents\SI settings\standard.usr' scanimage.SI.hConfigurationSaver.usrLoadingInProgress = false scanimage.SI.hCycleManager.active = false scanimage.SI.hCycleManager.cycleIdxDone = 0 scanimage.SI.hCycleManager.cycleIdxTotal = 1 scanimage.SI.hCycleManager.cycleIterIdxDone = 0 scanimage.SI.hCycleManager.cycleIterIdxTotal = 0 scanimage.SI.hCycleManager.enabled = false scanimage.SI.hDisplay.active = false scanimage.SI.hDisplay.channelsMergeEnable = false scanimage.SI.hDisplay.channelsMergeFocusOnly = false scanimage.SI.hDisplay.displayFrameBatchFactor = 3 scanimage.SI.hDisplay.displayFrameBatchFactorLock = false scanimage.SI.hDisplay.displayFrameBatchSelectAll = true scanimage.SI.hDisplay.displayFrameBatchSelectLast = false scanimage.SI.hDisplay.displayFrameBatchSelection = [1 2 3] scanimage.SI.hDisplay.displayRollingAverageFactor = 1 scanimage.SI.hDisplay.displayRollingAverageFactorLock = false scanimage.SI.hDisplay.displayTiling = true scanimage.SI.hDisplay.displayVolumeLock = 1 scanimage.SI.hDisplay.renderer = 'auto' scanimage.SI.hFastZ.acquisitionDelay = 0.007 scanimage.SI.hFastZ.active = false scanimage.SI.hFastZ.discardFlybackFrames = false scanimage.SI.hFastZ.enable = 1 scanimage.SI.hFastZ.extFrameClockTerminal = '/PXI1Slot4/PXI_Trig1' scanimage.SI.hFastZ.fillFraction = [] scanimage.SI.hFastZ.homePosition = [] scanimage.SI.hFastZ.numDiscardFlybackFrames = 0 scanimage.SI.hFastZ.numFramesPerVolume = 3 scanimage.SI.hFastZ.numVolumes = 60500 scanimage.SI.hFastZ.period = [] scanimage.SI.hFastZ.positionAbsolute = 0.0204846 scanimage.SI.hFastZ.positionTarget = 0 scanimage.SI.hFastZ.secondMotor = true scanimage.SI.hFastZ.settlingTime = 0.014 scanimage.SI.hFastZ.useArbitraryZs = 1 scanimage.SI.hFastZ.userZs = [-5 10 25] scanimage.SI.hFastZ.volumePeriodAdjustment = -0.0006 scanimage.SI.hFastZ.waveformType = 'step' scanimage.SI.hMotors.active = false scanimage.SI.hMotors.motorDimensionConfiguration = 'xyz-z' scanimage.SI.hMotors.motorFastMotionThreshold = 100 scanimage.SI.hMotors.motorMoveTimeout = 5 scanimage.SI.hMotors.motorPosition = [-1025 -495.5 -202.8 0] scanimage.SI.hMotors.motorSecondMotorZEnable = false scanimage.SI.hMotors.userDefinedPositions = <nonscalar struct/object> scanimage.SI.hPmts.active = false scanimage.SI.hPmts.bandwidths = [NaN NaN NaN NaN] scanimage.SI.hPmts.gains = [0 0 0 0] scanimage.SI.hPmts.names = {'Thor 1' 'Thor 2' 'Thor 3' 'Thor 4'} scanimage.SI.hPmts.offsets = [NaN NaN NaN NaN] scanimage.SI.hPmts.powersOn = [false false false false] scanimage.SI.hPmts.tripped = [0 0 0 0] scanimage.SI.hRoiManager.active = true scanimage.SI.hRoiManager.forceSquarePixelation = true scanimage.SI.hRoiManager.forceSquarePixels = true scanimage.SI.hRoiManager.linePeriod = 6.31264e-05 scanimage.SI.hRoiManager.linesPerFrame = 256 scanimage.SI.hRoiManager.pixelsPerLine = 256 scanimage.SI.hRoiManager.scanAngleMultiplierFast = 1 scanimage.SI.hRoiManager.scanAngleMultiplierSlow = 1 scanimage.SI.hRoiManager.scanAngleShiftFast = 0 scanimage.SI.hRoiManager.scanAngleShiftSlow = 0 scanimage.SI.hRoiManager.scanFramePeriod = 0.030175 scanimage.SI.hRoiManager.scanFrameRate = 33.14 scanimage.SI.hRoiManager.scanRotation = 0 scanimage.SI.hRoiManager.scanVolumeRate = 11.0467 scanimage.SI.hRoiManager.scanZoomFactor = 1.8 scanimage.SI.hScan2D.active = false scanimage.SI.hScan2D.beamClockDelay = 2 scanimage.SI.hScan2D.beamClockExtend = 0 scanimage.SI.hScan2D.bidirectional = true scanimage.SI.hScan2D.channelOffsets = [-1554 -1388 -72 -272] scanimage.SI.hScan2D.channels = {} scanimage.SI.hScan2D.channelsAdcResolution = 16 scanimage.SI.hScan2D.channelsAutoReadOffsets = true scanimage.SI.hScan2D.channelsAvailable = 4 scanimage.SI.hScan2D.channelsAvailableInputRanges = {[-1 1] [-0.5 0.5] [-0.25 0.25]} scanimage.SI.hScan2D.channelsDataType = 'int16' scanimage.SI.hScan2D.channelsFilter = 'Bessel' scanimage.SI.hScan2D.channelsInputRanges = {[-1 1] [-1 1] [-1 1] [-1 1]} scanimage.SI.hScan2D.channelsSubtractOffsets = [true true true true] scanimage.SI.hScan2D.fillFractionSpatial = 0.9 scanimage.SI.hScan2D.fillFractionTemporal = 0.712867 scanimage.SI.hScan2D.flybackTimePerFrame = 0.00189379 scanimage.SI.hScan2D.flytoTimePerScanfield = 0.00189379 scanimage.SI.hScan2D.keepResonantScannerOn = false scanimage.SI.hScan2D.linePhase = 3.45833e-06 scanimage.SI.hScan2D.linePhaseMode = 'Nearest Neighbor' scanimage.SI.hScan2D.logAverageFactor = 1 scanimage.SI.hScan2D.logFramesPerFile = 3000 scanimage.SI.hScan2D.logFramesPerFileLock = false scanimage.SI.hScan2D.maxSampleRate = 1.2e+08 scanimage.SI.hScan2D.name = 'ResScanner' scanimage.SI.hScan2D.pixelBinFactor = NaN scanimage.SI.hScan2D.resonantLimitedFovMode = true scanimage.SI.hScan2D.sampleRate = 1.2e+08 scanimage.SI.hScan2D.scanPixelTimeMaxMinRatio = 2.29412 scanimage.SI.hScan2D.scanPixelTimeMean = 1.77018e-07 scanimage.SI.hScan2D.scannerFrequency = 7920.62 scanimage.SI.hScan2D.scannerToRefTransform = [1 0 0;0 1 0;0 0 1] scanimage.SI.hScan2D.scannerType = 'Resonant' scanimage.SI.hScan2D.settleTimeFraction = 0 scanimage.SI.hScan2D.simulated = false scanimage.SI.hScan2D.trigAcqEdge = 'rising' scanimage.SI.hScan2D.trigAcqInTerm = '' scanimage.SI.hScan2D.trigNextEdge = 'rising' scanimage.SI.hScan2D.trigNextInTerm = '' scanimage.SI.hScan2D.trigNextStopEnable = true scanimage.SI.hScan2D.trigStopEdge = 'rising' scanimage.SI.hScan2D.trigStopInTerm = '' scanimage.SI.hScan2D.useNonlinearResonantFov2VoltsCurve = false scanimage.SI.hShutters.active = false scanimage.SI.hStackManager.active = false scanimage.SI.hStackManager.framesPerSlice = 1 scanimage.SI.hStackManager.numSlices = 3 scanimage.SI.hStackManager.slicesPerAcq = 3 scanimage.SI.hStackManager.stackReturnHome = true scanimage.SI.hStackManager.stackSlicesDone = 0 scanimage.SI.hStackManager.stackStartCentered = false scanimage.SI.hStackManager.stackZEndPos = NaN scanimage.SI.hStackManager.stackZStartPos = NaN scanimage.SI.hStackManager.stackZStepSize = 8 scanimage.SI.hStackManager.stageDependentZs = false scanimage.SI.hStackManager.zs = [-5 10 25] scanimage.SI.hUserFunctions.active = false scanimage.SI.hUserFunctions.userFunctionsCfg = <nonscalar struct/object> scanimage.SI.hUserFunctions.userFunctionsOverride = <nonscalar struct/object> scanimage.SI.hUserFunctions.userFunctionsUsr = <nonscalar struct/object> scanimage.SI.hWSConnector.active = false scanimage.SI.hWSConnector.enable = false scanimage.SI.imagingSystem = 'ResScanner' scanimage.SI.loopAcqInterval = 10

STRIPOFFSETS (10928, 19120, 27312, 35504, 43696, 51888, 60080, 68272, 76464, 84656, 92848, 101040, 109232, 117424, 125616, 133808)

STRIPBYTECOUNTS (8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192)



Cheers,

Erick