"""
# HISTORY
"""
"""
#### CONTENT

* The universe isn't behaving. Or at least, that's the view of many of the world's leading scientists: the universe behaves as if there is far more matter than we can observe. And that's important, because it means either that vital scientific theories are wrong, or that there are whole new types of stuff that we haven't yet discovered.

* The aim is to measure the shapes of galaxies to reconstruct the gravitational lensing signal in the presence of noise and a known Point Spread Function. The signal is a very small change in the galaxies’ ellipticity, an exactly circular galaxy image would be changed into an ; however real galaxies are not circular.

* The galaxy images are convolved or smoothed with a kernel that would act to turn a single point into a blurry image. Part of the challenge is to attempt to remove or account for that blurring effect.
"""
"""
# PACKAGES AND LIBRARIES
"""
#GENERAL
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import random
#PATH PROCESS
import os
import os.path
from pathlib import Path
import glob
#IMAGE PROCESS
from PIL import Image
from keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import cv2
from keras.applications.vgg16 import preprocess_input, decode_predictions
from keras.preprocessing import image
import skimage
from skimage.feature import hessian_matrix, hessian_matrix_eigvals
from scipy.ndimage.filters import convolve
from skimage import data, io, filters
#SCALER & TRANSFORMATION
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from keras.utils.np_utils import to_categorical
from sklearn.model_selection import train_test_split
from keras import regularizers
from sklearn.preprocessing import LabelEncoder
#ACCURACY CONTROL
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report, roc_auc_score, roc_curve
from sklearn.model_selection import GridSearchCV, cross_val_score
from sklearn.metrics import mean_squared_error, r2_score
#OPTIMIZER
from keras.optimizers import RMSprop,Adam,Optimizer,Optimizer, SGD
#MODEL LAYERS
from tensorflow.keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D, BatchNormalization,MaxPooling2D,BatchNormalization,\
                        Permute, TimeDistributed, Bidirectional,GRU, SimpleRNN, LSTM, GlobalAveragePooling2D, SeparableConv2D, ZeroPadding2D, \
Convolution2D, Reshape, GaussianNoise
from keras import models
from keras import layers
import tensorflow as tf
from keras.applications import VGG16,VGG19,inception_v3
from keras import backend as K
from keras.utils import plot_model
from keras.models import load_model
from keras.regularizers import l1,l2,L1L2
#SKLEARN CLASSIFIER
from xgboost import XGBClassifier, XGBRegressor
from lightgbm import LGBMClassifier, LGBMRegressor
from catboost import CatBoostClassifier, CatBoostRegressor
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor
from sklearn.ensemble import BaggingRegressor
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
from sklearn.neural_network import MLPClassifier, MLPRegressor
from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor
from sklearn.linear_model import LinearRegression
from sklearn.cross_decomposition import PLSRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import RidgeCV
from sklearn.linear_model import Lasso
from sklearn.linear_model import LassoCV
from sklearn.linear_model import ElasticNet
from sklearn.linear_model import ElasticNetCV
#IGNORING WARNINGS
from warnings import filterwarnings
filterwarnings("ignore",category=DeprecationWarning)
filterwarnings("ignore", category=FutureWarning) 
filterwarnings("ignore", category=UserWarning)
"""
# PATH
"""
Galaxy_Train_Path = Path("../input/mapping-dark-matter-image-set/DARK MATTER/galaxy/training")
Star_Train_Path = Path("../input/mapping-dark-matter-image-set/DARK MATTER/star/training")
Galaxy_IMG_Path = list(Galaxy_Train_Path.glob(r"*.png"))
Star_IMG_Path = list(Star_Train_Path.glob(r"*.png"))
"""
# TO SERIES
"""
Galaxy_IMG_Series = pd.Series(Galaxy_IMG_Path,name="PNG").astype(str)
Star_IMG_Series = pd.Series(Star_IMG_Path,name="PNG").astype(str)
print(Galaxy_IMG_Series.head(-1))
print(Star_IMG_Series.head(-1))
"""
# VISUALIZATION
"""
plt.style.use("classic")
Example_Galaxy_IMG = Galaxy_IMG_Series[45]
Example_Star_IMG = Star_IMG_Series[45]
Reading_Galaxy_IMG = cv2.imread(Example_Galaxy_IMG)
Reading_Galaxy_IMG = cv2.cvtColor(Reading_Galaxy_IMG,cv2.COLOR_BGR2RGB)
Reading_Star_IMG = cv2.imread(Example_Star_IMG)
Reading_Star_IMG = cv2.cvtColor(Reading_Star_IMG,cv2.COLOR_BGR2RGB)
figure = plt.figure(figsize=(12,12))
print("GALAXY")
plt.xlabel(Reading_Galaxy_IMG.shape)
plt.ylabel(Reading_Galaxy_IMG.size)
plt.imshow(Reading_Galaxy_IMG)
figure = plt.figure(figsize=(12,12))
print("STAR")
plt.xlabel(Reading_Star_IMG.shape)
plt.ylabel(Reading_Star_IMG.size)
plt.imshow(Reading_Star_IMG)
figure = plt.figure(figsize=(12,12))

_,threshold_Galaxy = cv2.threshold(Reading_Galaxy_IMG,200,255,cv2.THRESH_BINARY_INV)

print("GALAXY")
plt.xlabel(threshold_Galaxy.shape)
plt.ylabel(threshold_Galaxy.size)
plt.imshow(threshold_Galaxy)
figure = plt.figure(figsize=(12,12))

_,threshold_Star = cv2.threshold(Reading_Star_IMG,200,255,cv2.THRESH_BINARY_INV)

print("STAR")
plt.xlabel(threshold_Star.shape)
plt.ylabel(threshold_Star.size)
plt.imshow(threshold_Star)
figure,axis = plt.subplots(nrows=5,ncols=5,figsize=(12,12))

print("GALAXY")
for indexing,ax in enumerate(axis.flat):
    IMG_Reading = cv2.imread(Galaxy_IMG_Series[indexing])
    ax.set_xlabel(IMG_Reading.shape)
    ax.set_ylabel(IMG_Reading.size)
    ax.imshow(IMG_Reading)
plt.tight_layout()
plt.show()
figure,axis = plt.subplots(nrows=5,ncols=5,figsize=(12,12))

print("STAR")
for indexing,ax in enumerate(axis.flat):
    IMG_Reading = cv2.imread(Star_IMG_Series[indexing])
    ax.set_xlabel(IMG_Reading.shape)
    ax.set_ylabel(IMG_Reading.size)
    ax.imshow(IMG_Reading)
plt.tight_layout()
plt.show()
figure,axis = plt.subplots(nrows=5,ncols=5,figsize=(12,12))

print("GALAXY")
for indexing,ax in enumerate(axis.flat):
    IMG_Reading = cv2.imread(Galaxy_IMG_Series[indexing])
    _,threshold_Galaxy = cv2.threshold(IMG_Reading,200,255,cv2.THRESH_BINARY_INV)
    ax.set_xlabel(threshold_Galaxy.shape)
    ax.set_ylabel(threshold_Galaxy.size)
    ax.imshow(threshold_Galaxy)
plt.tight_layout()
plt.show()
figure,axis = plt.subplots(nrows=5,ncols=5,figsize=(12,12))

print("STAR")
for indexing,ax in enumerate(axis.flat):
    IMG_Reading = cv2.imread(Star_IMG_Series[indexing])
    _,threshold_Star = cv2.threshold(IMG_Reading,200,255,cv2.THRESH_BINARY_INV)
    ax.set_xlabel(threshold_Star.shape)
    ax.set_ylabel(threshold_Star.size)
    ax.imshow(threshold_Star)
plt.tight_layout()
plt.show()
figure = plt.figure(figsize=(12,12))

_,threshold_Galaxy = cv2.threshold(Reading_Galaxy_IMG,200,255,cv2.THRESH_BINARY_INV)
Canny_Galaxy = cv2.Canny(threshold_Galaxy,10,100)
contours_Galaxy,_ = cv2.findContours(Canny_Galaxy,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

for cnt_Galaxy in contours_Galaxy:
    x,y,w,h = cv2.boundingRect(cnt_Galaxy)
    cv2.rectangle(Reading_Galaxy_IMG,(x,y),(x+w,y+h),(255,0,0),1)

print("GALAXY")
plt.xlabel(Reading_Galaxy_IMG.shape)
plt.ylabel(Reading_Galaxy_IMG.size)
plt.imshow(Reading_Galaxy_IMG)
figure = plt.figure(figsize=(12,12))

_,threshold_Star_E = cv2.threshold(Reading_Star_IMG,200,255,cv2.THRESH_BINARY_INV)
Canny_Star_E = cv2.Canny(threshold_Star_E,10,100)
contours_Star_E,_ = cv2.findContours(Canny_Star_E,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

for cnt_Star_E in contours_Star_E:
    x_s,y_s,w_s,h_s = cv2.boundingRect(cnt_Star_E)
    cv2.rectangle(Reading_Star_IMG,(x_s,y_s),(x_s+w_s,y_s+h_s),(255,0,0),1)

print("STAR")
plt.xlabel(Reading_Star_IMG.shape)
plt.ylabel(Reading_Star_IMG.size)
plt.imshow(Reading_Star_IMG)
figure,axis = plt.subplots(nrows=5,ncols=5,figsize=(12,12))

print("GALAXY")
for indexing,ax in enumerate(axis.flat):
    IMG_Reading = cv2.imread(Galaxy_IMG_Series[indexing])
    _,threshold_Galaxy = cv2.threshold(IMG_Reading,200,255,cv2.THRESH_BINARY_INV)
    Canny_Galaxy = cv2.Canny(threshold_Galaxy,10,100)
    contours_Galaxy,_ = cv2.findContours(Canny_Galaxy,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

    for cnt_Galaxy in contours_Galaxy:
        x,y,w,h = cv2.boundingRect(cnt_Galaxy)
        cv2.rectangle(IMG_Reading,(x,y),(x+w,y+h),(255,0,0),1)
        
    ax.set_xlabel(IMG_Reading.shape)
    ax.set_ylabel(IMG_Reading.size)
    ax.imshow(IMG_Reading)
plt.tight_layout()
plt.show()
figure,axis = plt.subplots(nrows=5,ncols=5,figsize=(12,12))

print("STAR")
for indexing,ax in enumerate(axis.flat):
    IMG_Reading = cv2.imread(Star_IMG_Series[indexing])
    _,threshold_Star = cv2.threshold(IMG_Reading,200,255,cv2.THRESH_BINARY_INV)
    Canny_Star = cv2.Canny(threshold_Star,10,100)
    contours_Star,_ = cv2.findContours(Canny_Star,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

    for cnt_Star in contours_Star:
        x,y,w,h = cv2.boundingRect(cnt_Star)
        cv2.rectangle(IMG_Reading,(x,y),(x+w,y+h),(255,0,0),1)
        
    ax.set_xlabel(IMG_Reading.shape)
    ax.set_ylabel(IMG_Reading.size)
    ax.imshow(IMG_Reading)
plt.tight_layout()
plt.show()
"""
# DATA PROCESS
"""
Galaxy_Train = Galaxy_IMG_Series[:10000]
Galaxy_Test = Galaxy_IMG_Series[10000:20000]
Galaxy_Test = Galaxy_Test.reset_index()
Star_Train = Star_IMG_Series[:10000]
Star_Test = Star_IMG_Series[10000:20000]
Star_Test = Star_Test.reset_index()
print(Galaxy_Train.head(-1))
print(Galaxy_Test.head(-1))
print(Star_Train.head(-1))
print(Star_Test.head(-1))
Transformation_Galaxy_Train = []

for Galaxy_IMG in Galaxy_Train:
    
    IMG_G = cv2.imread(Galaxy_IMG)
    IMG_G = IMG_G / 255.
    Transformation_Galaxy_Train.append(IMG_G)
Transformation_Galaxy_Test = []

for Galaxy_IMG_Test in Galaxy_Test["PNG"]:
    
    IMG_G_Test = cv2.imread(Galaxy_IMG_Test)
    IMG_G_Test = IMG_G_Test / 255.
    Transformation_Galaxy_Test.append(IMG_G_Test)
Transformation_Star_Train = []

for Star_IMG in Star_Train:
    
    IMG_S = cv2.imread(Star_IMG)
    IMG_S = IMG_S / 255.
    Transformation_Star_Train.append(IMG_S)
Transformation_Star_Test = []

for Star_IMG_Test in Star_Test["PNG"]:
    
    IMG_S_Test = cv2.imread(Star_IMG_Test)
    IMG_S_Test = IMG_S_Test / 255.
    Transformation_Star_Test.append(IMG_S_Test)
print(Transformation_Galaxy_Train[4].shape)
print(Transformation_Galaxy_Test[4].shape)
print(Transformation_Star_Train[4].shape)
print(Transformation_Star_Test[4].shape)
X_Train_Galaxy = np.asarray(Transformation_Galaxy_Train)
X_Test_Galaxy = np.asarray(Transformation_Galaxy_Test)
X_Train_Star = np.asarray(Transformation_Star_Train)
X_Test_Star = np.asarray(Transformation_Star_Test)
print(X_Train_Galaxy.shape)
print(X_Test_Galaxy.shape)
print(X_Train_Star.shape)
print(X_Test_Star.shape)
"""
# AUTO-ENCODER FOR GALAXY
"""
Encoder_G = Sequential()
#
Encoder_G.add(Flatten(input_shape=(48,48,3)))
#
Encoder_G.add(Dense(1000,activation="relu"))
Encoder_G.add(Dense(900,activation="relu"))
Encoder_G.add(Dense(800,activation="relu"))
Encoder_G.add(Dense(700,activation="relu"))
Encoder_G.add(Dense(600,activation="relu"))
Encoder_G.add(Dense(500,activation="relu"))
Encoder_G.add(Dense(400,activation="relu"))
Encoder_G.add(Dense(300,activation="relu"))
Encoder_G.add(Dense(200,activation="relu"))
Encoder_G.add(Dense(100,activation="relu"))
Encoder_G.add(Dense(50,activation="relu"))
Encoder_G.add(Dense(25,activation="relu"))
Encoder_G.add(Dense(15,activation="relu"))
#
Encoder_G.add(Dense(7,activation="relu"))
Decoder_G = Sequential()
#
Decoder_G.add(Dense(15,activation="relu",input_shape=[7]))
#
Decoder_G.add(Dense(25,activation="relu"))
Decoder_G.add(Dense(50,activation="relu"))
Decoder_G.add(Dense(100,activation="relu"))
Decoder_G.add(Dense(200,activation="relu"))
Decoder_G.add(Dense(300,activation="relu"))
Decoder_G.add(Dense(400,activation="relu"))
Decoder_G.add(Dense(500,activation="relu"))
Decoder_G.add(Dense(600,activation="relu"))
Decoder_G.add(Dense(700,activation="relu"))
Decoder_G.add(Dense(800,activation="relu"))
Decoder_G.add(Dense(900,activation="relu"))
Decoder_G.add(Dense(1000,activation="relu"))
#
Decoder_G.add(Dense(48*48*3,activation="sigmoid"))
#
Decoder_G.add(Reshape([48,48,3]))
Auto_Encoder_Galaxy = Sequential([Encoder_G,Decoder_G])
print(Auto_Encoder_Galaxy.summary())
print(Auto_Encoder_Galaxy.layers)
Auto_Encoder_Galaxy.compile(loss="binary_crossentropy",optimizer="rmsprop",metrics=["accuracy"])
AE_G_Model = Auto_Encoder_Galaxy.fit(X_Train_Galaxy,X_Train_Galaxy,epochs=5,batch_size=20)
Prediction_Galaxy_IMG = Auto_Encoder_Galaxy.predict(X_Test_Galaxy[:20])
prediction_img_number = 2
print("NORMAL")
plt.imshow(X_Test_Galaxy[prediction_img_number])
plt.show()
print("AUTO-ENCODER OUTPUT")
plt.imshow(Prediction_Galaxy_IMG[prediction_img_number])
prediction_img_number = 10
print("NORMAL")
plt.imshow(X_Test_Galaxy[prediction_img_number])
plt.show()
print("AUTO-ENCODER OUTPUT")
plt.imshow(Prediction_Galaxy_IMG[prediction_img_number])
figure,axis = plt.subplots(nrows=5,ncols=4,figsize=(10,10))

for Pr_Image,ax in enumerate(axis.flat):
    ax.imshow(Prediction_Galaxy_IMG[Pr_Image])
TEST_IMG = X_Test_Galaxy[1]
AUTOENCODER_OUTPUT = Prediction_Galaxy_IMG[1]

IMGs_List_Predict = [TEST_IMG,AUTOENCODER_OUTPUT]

figure,axis = plt.subplots(nrows=1,ncols=2,figsize=(10,10))

for i, ax in enumerate(axis.flat):
    ax.imshow(IMGs_List_Predict[i])
plt.tight_layout()
plt.show()
TEST_IMG = X_Test_Galaxy[1]
AUTOENCODER_OUTPUT = Prediction_Galaxy_IMG[10]

IMGs_List_Predict = [TEST_IMG,AUTOENCODER_OUTPUT]

figure,axis = plt.subplots(nrows=1,ncols=2,figsize=(10,10))

for i, ax in enumerate(axis.flat):
    ax.imshow(IMGs_List_Predict[i])
plt.tight_layout()
plt.show()
"""
# AUTO-ENCODER FOR STAR
"""
Encoder_S = Sequential()
#
Encoder_S.add(Flatten(input_shape=(48,48,3)))
#
Encoder_S.add(Dense(400,activation="relu"))
Encoder_S.add(Dense(300,activation="relu"))
Encoder_S.add(Dense(200,activation="relu"))
Encoder_S.add(Dense(100,activation="relu"))
Encoder_S.add(Dense(50,activation="relu"))
Encoder_S.add(Dense(25,activation="relu"))
Encoder_S.add(Dense(15,activation="relu"))
#
Encoder_S.add(Dense(7,activation="relu"))
Decoder_S = Sequential()
#
Decoder_S.add(Dense(15,activation="relu",input_shape=[7]))
#
Decoder_S.add(Dense(25,activation="relu"))
Decoder_S.add(Dense(50,activation="relu"))
Decoder_S.add(Dense(100,activation="relu"))
Decoder_S.add(Dense(200,activation="relu"))
Decoder_S.add(Dense(300,activation="relu"))
Decoder_S.add(Dense(400,activation="relu"))
#
Decoder_S.add(Dense(48*48*3,activation="sigmoid"))
#
Decoder_S.add(Reshape([48,48,3]))
Auto_Encoder_Star = Sequential([Encoder_S,Decoder_S])
print(Auto_Encoder_Star.summary())
print(Auto_Encoder_Star)
Auto_Encoder_Star.compile(loss="binary_crossentropy",optimizer="rmsprop",metrics=["accuracy"])
AE_S_Model = Auto_Encoder_Star.fit(X_Train_Star,X_Train_Star,epochs=5,batch_size=20)
Prediction_Star_IMG = Auto_Encoder_Galaxy.predict(X_Test_Star[:20])
prediction_img_number = 11
print("NORMAL")
plt.imshow(X_Test_Star[prediction_img_number])
plt.show()
print("AUTO-ENCODER OUTPUT")
plt.imshow(Prediction_Star_IMG[prediction_img_number])
prediction_img_number = 1
print("NORMAL")
plt.imshow(X_Test_Star[prediction_img_number])
plt.show()
print("AUTO-ENCODER OUTPUT")
plt.imshow(Prediction_Star_IMG[prediction_img_number])
figure,axis = plt.subplots(nrows=5,ncols=4,figsize=(10,10))

for Pr_Image,ax in enumerate(axis.flat):
    ax.imshow(Prediction_Star_IMG[Pr_Image])
TEST_IMG = X_Test_Star[1]
AUTOENCODER_OUTPUT = Prediction_Star_IMG[1]

IMGs_List_Predict = [TEST_IMG,AUTOENCODER_OUTPUT]

figure,axis = plt.subplots(nrows=1,ncols=2,figsize=(10,10))

for i, ax in enumerate(axis.flat):
    ax.imshow(IMGs_List_Predict[i])
plt.tight_layout()
plt.show()
TEST_IMG = X_Test_Star[19]
AUTOENCODER_OUTPUT = Prediction_Star_IMG[19]

IMGs_List_Predict = [TEST_IMG,AUTOENCODER_OUTPUT]

figure,axis = plt.subplots(nrows=1,ncols=2,figsize=(10,10))

for i, ax in enumerate(axis.flat):
    ax.imshow(IMGs_List_Predict[i])
plt.tight_layout()
plt.show()
plt.savefig("output")
print(Prediction_Star_IMG[1].dtype)