WeatherRegime <- function(data, EOFS = TRUE, neofs = 30, lon = NULL, lat = NULL, ncenters = NULL, method = "kmeans",
                          nstart = 30, listindex = NULL) {
  if (EOFS != 1) {
    stop("Currently clusters must be calculated from fields")
  }
  sdate <- which(names(dim(data)) == "sdate")
  ftime <- which(names(dim(data)) == "ftime")
  nftimes <- dim(data)[ftime]
  nsdates <- dim(data)[sdate]
  lon2 <- which(names(dim(data)) == "lon")
  lat2 <- which(names(dim(data)) == "lat")
  dims <- c(1 : length(dim(data)))[-c(sdate, ftime, lon2, lat2)]
  data <- aperm(data, c(sdate, ftime, lat2, lon2, dims))
  nlon <- dim(data)[lon2]
  nlat <- dim(data)[lat2]
  if (is.null(ncenters)) {
    stop("nclusters must be specified")
  }
  if (EOFS  == TRUE) {
    data <- melt(data, varnames = c("Year", "Day", "Lat", "Lon"))
    data <- acast(data, Year + Day ~ Lat ~ Lon)
    #data <- princomp(data[,subs], cor = FALSE)$scores
    dataPC <- EOF(data, lat = lat, lon = lon, neofs = neofs)
    threshold <- 90
    minPC <- head(as.numeric(which(cumsum(dataPC$var) > threshold)), 1)
  } 
  if (method == "kmeans") {
    result <- kmeans(dataPC$PC[, 1 : minPC], centers = ncenters, 
                     iter.max = 100, nstart = nstart, trace = FALSE)
    reconstructed <- array(0, c(ncenters, nlat, nlon))
    for (i in 1 : ncenters) {
      field <- apply(dataPC$EOF[1 : minPC, , ], MARGIN = c(2,3), function(x) x * result$center[i,])
      reconstructed[i , ,] <- apply(field, MARGIN = c(2,3), sum)
    }
    reconstructed <- aperm(reconstructed, c(1,3,2))
    names(dim(reconstructed)) <- c("cluster", "lon", "lat")
    cluster_timeseries <- list(lengths = c(), values = c())
    for (i in 1 : nsdates) {
      occurences <- rle(result$cluster[((i * nftimes) + 1 - nftimes) : (i * nftimes)])
      cluster_timeseries <- list(lengths = c(cluster_timeseries$lengths, occurences$lengths),
                                 values = c(cluster_timeseries$values, occurences$values))
    }
  } else {
    result <- hclust(dist(dataPC$PC[, 1 : minPC]), method = method)
    clusterCut <- cutree(result, ncenters)
    data <- aperm(data, c(3, 2, 1))
    result <- Composite(data, clusterCut)
  }
  if (method == "kmeans") {
    return(list(field = reconstructed, EOF = dataPC$EOF, center = result$center, cluster = result$cluster,
           cluster_lengths = cluster_timeseries$lengths, cluster_values = cluster_timeseries$values))
  } else {
    return(list(field = result, cluster = clusterCut))
  }
}


