using Pkg
using CSV
using Statistics
using OnlinePCA
using Distributions
using DelimitedFiles
using Arpack
using HypergeometricFunctions
using Distances
using StatsBase




mat = CSV.read("/home/cbl06/Documents/Matrix.csv")
genes = mat[1]
cells = mat[1,:]
@time arr = convert(Matrix{Int32}, mat[2:2169])
arrlog = Float32.(log.(arr .+ 1))
X = arr
bool = var(X, dims = 2)[:] .!= 0
X = X[bool, :]
@time standardize(ZScoreTransform, Float32.(X), dims=2)
rmin = minimum(X, dims = 2)
rmax = maximum(X, dims = 2)
rangeMM = rmax - rmin
X = (X .- rmin) ./ rangeMM
StatsBase.standardize(UnitRangeTransform, [0.0 -0.5 0.5; 0.0 1.0 2.0], dims=2)
standardize(UnitRangeTransform, Array{Float64,2}(X), dims =1)
X = convert(Matrix{Float32}, X)
X = vcat(X, 1 .- X)
Acol = sum(X, dims = 1)
Arow = sum(X, dims = 2)
Acol_sqrt = convert(Matrix{Float32}, sqrt.(Acol))
Arow_sqrt = convert(Matrix{Float32}, sqrt.(Arow))
@time Z = X ./ Acol_sqrt ./ Arow_sqrt

U, S, V = (Arpack.svds(Z, nsv = 50))[1]
gene = (Z * V)[:, 1:end .!= 1]
cell = (size(Z)[2] * V)[:, 1:end .!= 1]
@time dist = Distances.pairwise(Euclidean(), cell, gene, dims = 1)


P = mapslices(x->sortperm(x; rev = false, alg = PartialQuickSort(200)), dist, dims = 1)
mapslices(sortperm, dist, dims = 2)

sil = sortperm(dist[:,1], rev = false)[1:200]
sortperm(eachcol(dist[:, 1:5]))
dist[sil,1]

sortperm(dist[:,32], rev = true, alg = PartialQuickSort(200))

function NormalizeData(X::AbstractArray; scale_factor::Int = 10000)::Array{Float32,2}
    return log1p.(scale_factor * (X ./ sum(X, dims = 1)))
end
@time NormalizeData(arr)
scale(arr, d::MvLogNormal)
StatsBase.standardize(ZScoreTransform, [0.0 -0.5 5.5; 0.0 1.0 2.0], dims=2)


JuliaSeurat.NormalizeData(arrlog)
