"""
    sumr(;binfile::AbstractString="", outdir::AbstractString=".", pseudocount::Number=1.0)
Extract the summary information of data matrix.
`binfile` is a Julia Binary file generated by `csv2bin` function.
`outdir` is specified the directory you want to save the result.
`pseudocount` is specified to avoid NaN by log10(0) and used when `Row_LogMeans.csv` <log10(mean+pseudocount) value of each Row> is generated.
Output Files
---------
- `Col_Means.csv` : Mean in each column.
- `Col_LogMeans.csv` : Mean of Log10(count+pseudocount) in each column.
- `Col_FTTMeans.csv` : Mean of sqrt(count) + sqrt(count+1) in ech column.
- `Col_Vars.csv` : Variance in each column.
- `Col_LogVars.csv` : Variance of Log10(count+pseudocount) in each column.
- `Col_FTTVars.csv` : Variance of sqrt(count) + sqrt(count+1) in ech column.
- `Col_SDs.csv` : Standard deviation in each column.
- `Col_LogSDs.csv` : Standard deviation of Log10(count+pseudocount) in each column.
- `Col_FTTSDs.csv` : Standard deviation of sqrt(count) + sqrt(count+1) in ech column.
- `Col_CV2s.csv` : Coefficient of Variation in each column.
- `Col_NoZeros.csv` : Number of zero-elements in each column.
- `Col_NoCounts.csv` : Sum of counts in each column.
- `Row_Means.csv` : Mean in each row.
- `Row_LogMeans.csv` : Mean of Log10(count+pseudocount) in each row.
- `Row_FTTMeans.csv` : Mean of sqrt(count) + sqrt(count+1) in ech row.
- `Row_Vars.csv` : Variance in each row.
- `Row_LogVars.csv` : Variance of Log10(count+pseudocount) in each row.
- `Row_FTTVars.csv` :  Variance of sqrt(count) + sqrt(count+1) in ech row.
- `Row_SDs.csv` : Standard deviation in each row.
- `Row_LogSDs.csv` : Standard deviation of Log10(count+pseudocount) in each row.
- `Row_FTTSDs.csv` : Standard deviation of sqrt(count) + sqrt(count+1) in ech row.
- `Row_CV2s.csv` : Coefficient of Variation in each row.
- `Row_NoZeros.csv` : Number of zero-elements in each row.
- `Row_NoCounts.csv` : Sum of counts in each row.
"""
function sumr(;binfile::AbstractString="", outdir::AbstractString=".", pseudocount::Number=1.0)
    # 1 / 2 : Column-wise statistics
    println("1 / 2 : Column-wise statistics are calculated...")
    Col_Means, Col_LogMeans, Col_FTTMeans, Col_Vars, Col_LogVars, Col_FTTVars, Col_SDs, Col_LogSDs, Col_FTTSDs, Col_CV2s, Col_NoZeros, Col_NoCounts = colstats(binfile, pseudocount)

    # 2 / 2 : Row-wise statistics
    println("2 / 2 : Row-wise statistics are calculated...")
    Row_Means, Row_LogMeans, Row_FTTMeans, Row_Vars, Row_LogVars, Row_FTTVars, Row_SDs, Row_LogSDs, Row_FTTSDs,  Row_CV2s, Row_NoZeros, Row_NoCounts = rowstats(binfile, pseudocount)

    # Save
    # Col-wise
    writecsv(joinpath(outdir, "Col_Means.csv"), Col_Means)
    writecsv(joinpath(outdir, "Col_LogMeans.csv"), Col_LogMeans)
    writecsv(joinpath(outdir, "Col_FTTMeans.csv"), Col_FTTMeans)
    writecsv(joinpath(outdir, "Col_Vars.csv"), Col_Vars)
    writecsv(joinpath(outdir, "Col_LogVars.csv"), Col_LogVars)
    writecsv(joinpath(outdir, "Col_FTTVars.csv"), Col_FTTVars)
    writecsv(joinpath(outdir, "Col_SDs.csv"), Col_SDs)
    writecsv(joinpath(outdir, "Col_LogSDs.csv"), Col_LogSDs)
    writecsv(joinpath(outdir, "Col_FTTSDs.csv"), Col_FTTSDs)
    writecsv(joinpath(outdir, "Col_CV2s.csv"), Col_CV2s)
    writecsv(joinpath(outdir, "Col_NoZeros.csv"), Col_NoZeros)
    writecsv(joinpath(outdir, "Col_NoCounts.csv"), Col_NoCounts)

    # Row-wise
    writecsv(joinpath(outdir, "Row_Means.csv"), Row_Means)
    writecsv(joinpath(outdir, "Row_LogMeans.csv"), Row_LogMeans)
    writecsv(joinpath(outdir, "Row_FTTMeans.csv"), Row_FTTMeans)
    writecsv(joinpath(outdir, "Row_Vars.csv"), Row_Vars)
    writecsv(joinpath(outdir, "Row_LogVars.csv"), Row_LogVars)
    writecsv(joinpath(outdir, "Row_FTTVars.csv"), Row_FTTVars)
    writecsv(joinpath(outdir, "Row_SDs.csv"), Row_SDs)
    writecsv(joinpath(outdir, "Row_LogSDs.csv"), Row_LogSDs)
    writecsv(joinpath(outdir, "Row_FTTSDs.csv"), Row_FTTSDs)
    writecsv(joinpath(outdir, "Row_CV2s.csv"), Row_CV2s)
    writecsv(joinpath(outdir, "Row_NoZeros.csv"), Row_NoZeros)
    writecsv(joinpath(outdir, "Row_NoCounts.csv"), Row_NoCounts)
end

# Column-wise statistics
function colstats(binfile::AbstractString, pseudocount::Number)
    N, M = nm([binfile])
    N = N[]
    M = M[]
    tmpN = zeros(UInt32, 1)
    tmpM = zeros(UInt32, 1)
    x = zeros(UInt32, M)
    m = zeros(M)
    lm = zeros(M)
    fttm = zeros(M)
    v = zeros(M)
    lv = zeros(M)
    fttv = zeros(M)
    sd = zeros(M)
    lsd = zeros(M)
    fttsd = zeros(M)
    c = zeros(M)
    nz = zeros(M)
    nc = zeros(M)
    # Mean Calculator
    progress = Progress(N)
    open(binfile) do file
        stream = ZstdDecompressorStream(file)
        read!(stream, tmpN)
        read!(stream, tmpM)
        for n = 1:N
            # Data Import
            read!(stream, x)
            # Update
            m = m .+ (x .- m) / n
            lm = lm .+ (log10.(x .+ pseudocount) .- lm) / n
            fttm = fttm .+ (sqrt.(x) .+ sqrt.(x .+ 1) .- lm) / n
            # Non-zero counts
            nc = nc .+ x
            tmpx = x
            for mm = 1:M
                if tmpx[mm] != 0
                    tmpx[mm] = 1
                end
            end
            nz = nz .+ tmpx
            # Progress Bar
            next!(progress)
        end
        close(stream)
    end
    # Sum of squared deviation Calculator
    progress = Progress(N)
    open(binfile) do file
        stream = ZstdDecompressorStream(file)
        read!(stream, tmpN)
        read!(stream, tmpM)
        for n = 1:N
            # Data Import
            read!(stream, x)
            # Update
            tmpv = x .- m
            tmplv = log10.(x .+ pseudocount) .- lm
            tmpfttv = sqrt.(x) .+ sqrt.(x .+ 1) .- fttm
            v = v .+ tmpv .* tmpv
            lv = lv .+ tmplv .* tmplv
            fttv = fttv .+ tmpfttv .* tmpfttv
            # Progress Bar
            next!(progress)
        end
        close(stream)
    end
    # Variance
    v = v ./ N
    lv = lv ./ N
    fttv = fttv ./ N
    # Var → SD
    sd = sqrt.(v)
    lsd = sqrt.(lv)
    fttsd = sqrt.(fttv)
    # CV2
    c = v ./ m .* m
    return m, lm, fttm, v, lv, fttv, sd, lsd, fttsd, c, nz, nc
end

# Row-wise statistics
function rowstats(binfile::AbstractString, pseudocount::Number)
    N, M = nm([binfile])
    N = N[]
    M = M[]
    tmpN = zeros(UInt32, 1)
    tmpM = zeros(UInt32, 1)
    x = zeros(UInt32, M)
    m = zeros(N)
    lm = zeros(N)
    fttm = zeros(N)
    v = zeros(N)
    lv = zeros(N)
    fttv = zeros(N)
    sd = zeros(N)
    lsd = zeros(N)
    fttsd = zeros(N)
    c = zeros(N)
    nz = zeros(UInt32, N)
    nc = zeros(UInt32, N)
    progress = Progress(N)
    open(binfile) do file
        stream = ZstdDecompressorStream(file)
        read!(stream, tmpN)
        read!(stream, tmpM)
        for n = 1:N
            # Data Import
            read!(stream, x)
            # Update
            m[n] = mean(x)
            lm[n] = mean(log10.(x .+ pseudocount))
            fttm[n] = mean(sqrt.(x) .+ sqrt.(x .+ 1))
            v[n] = var(x)
            lv[n] = var(log10.(x .+ pseudocount))
            fttv[n] = var(sqrt.(x) .+ sqrt.(x .+ 1))
            sd[n] = var(x)^(1/2)
            lsd[n] = var(log10.(x .+ pseudocount))^(1/2)
            fttsd[n] = var(sqrt.(x) .+ sqrt.(x .+ 1))^(1/2)
            c[n] = v[n] ./ (m[n] .* m[n])
            for mm = 1:M
                if x[mm] != 0
                    nz[n] = nz[n] + 1
                end
            end
            nc[n] = sum.(x)[1]
            # Progress Bar
            next!(progress)
        end
        close(stream)
    end
    return m, lm, fttm, v, lv, fttv, sd, lsd, fttsd, c, nz, nc
end