text: # Using GridSearchCV to automate the tuning process of the model. Different parameters will be tried and best
  # performance will be evaluated. The file returns the model with the best parameters and best score.
  
  import numpy as np
  import os
  import pandas as pd
  
  # From William Curkierski Kaggle Kernel 'Reading images'
  def read_header(infile):
      """Read image header (first 512 bytes)
      """
      h = dict()
      fid = open(infile, 'r+b')
      h['filename'] = b''.join(np.fromfile(fid, dtype = 'S1', count = 20))
      h['parent_filename'] = b''.join(np.fromfile(fid, dtype = 'S1', count = 20))
      h['comments1'] = b''.join(np.fromfile(fid, dtype = 'S1', count = 80))
      h['comments2'] = b''.join(np.fromfile(fid, dtype = 'S1', count = 80))
      h['energy_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['config_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['file_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['trans_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['scan_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['data_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['date_modified'] = b''.join(np.fromfile(fid, dtype = 'S1', count = 16))
      h['frequency'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['mat_velocity'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['num_pts'] = np.fromfile(fid, dtype = np.int32, count = 1)
      h['num_polarization_channels'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['spare00'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['adc_min_voltage'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['adc_max_voltage'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['band_width'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['spare01'] = np.fromfile(fid, dtype = np.int16, count = 5)
      h['polarization_type'] = np.fromfile(fid, dtype = np.int16, count = 4)
      h['record_header_size'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['word_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['word_precision'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['min_data_value'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['max_data_value'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['avg_data_value'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['data_scale_factor'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['data_units'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['surf_removal'] = np.fromfile(fid, dtype = np.uint16, count = 1)
      h['edge_weighting'] = np.fromfile(fid, dtype = np.uint16, count = 1)
      h['x_units'] = np.fromfile(fid, dtype = np.uint16, count = 1)
      h['y_units'] = np.fromfile(fid, dtype = np.uint16, count = 1)
      h['z_units'] = np.fromfile(fid, dtype = np.uint16, count = 1)
      h['t_units'] = np.fromfile(fid, dtype = np.uint16, count = 1)
      h['spare02'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['x_return_speed'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_return_speed'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_return_speed'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['scan_orientation'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['scan_direction'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['data_storage_order'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['scanner_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['x_inc'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_inc'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_inc'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['t_inc'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['num_x_pts'] = np.fromfile(fid, dtype = np.int32, count = 1)
      h['num_y_pts'] = np.fromfile(fid, dtype = np.int32, count = 1)
      h['num_z_pts'] = np.fromfile(fid, dtype = np.int32, count = 1)
      h['num_t_pts'] = np.fromfile(fid, dtype = np.int32, count = 1)
      h['x_speed'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_speed'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_speed'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['x_acc'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_acc'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_acc'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['x_motor_res'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_motor_res'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_motor_res'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['x_encoder_res'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_encoder_res'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_encoder_res'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['date_processed'] = b''.join(np.fromfile(fid, dtype = 'S1', count = 8))
      h['time_processed'] = b''.join(np.fromfile(fid, dtype = 'S1', count = 8))
      h['depth_recon'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['x_max_travel'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_max_travel'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['elevation_offset_angle'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['roll_offset_angle'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_max_travel'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['azimuth_offset_angle'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['adc_type'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['spare06'] = np.fromfile(fid, dtype = np.int16, count = 1)
      h['scanner_radius'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['x_offset'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['y_offset'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['z_offset'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['t_delay'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['range_gate_start'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['range_gate_end'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['ahis_software_version'] = np.fromfile(fid, dtype = np.float32, count = 1)
      h['spare_end'] = np.fromfile(fid, dtype = np.float32, count = 10)
      return h
  
  # From William Curkierski Kaggle Kernel 'Reading images'
  def read_data(infile):
      """Read any of the 4 types of image files, returns a numpy array of the image contents
      """
      extension = os.path.splitext(infile)[1]
      h = read_header(infile)
      nx = int(h['num_x_pts'])
      ny = int(h['num_y_pts'])
      nt = int(h['num_t_pts'])
      fid = open(infile, 'rb')
      fid.seek(512) #skip header
      if extension == '.aps' or extension == '.a3daps':
          if(h['word_type']==7): #float32
              data = np.fromfile(fid, dtype = np.float32, count = nx * ny * nt)
          elif(h['word_type']==4): #uint16
              data = np.fromfile(fid, dtype = np.uint16, count = nx * ny * nt)
          data = data * h['data_scale_factor'] #scaling factor
          data = data.reshape(nx, ny, nt, order='F').copy() #make N-d image
      elif extension == '.a3d':
          if(h['word_type']==7): #float32
              data = np.fromfile(fid, dtype = np.float32, count = nx * ny * nt)
          elif(h['word_type']==4): #uint16
              data = np.fromfile(fid, dtype = np.uint16, count = nx * ny * nt)
          data = data * h['data_scale_factor'] #scaling factor
          data = data.reshape(nx, nt, ny, order='F').copy() #make N-d image
      elif extension == '.ahi':
          data = np.fromfile(fid, dtype = np.float32, count = 2* nx * ny * nt)
          data = data.reshape(2, ny, nx, nt, order='F').copy()
          real = data[0,:,:,:].copy()
          imag = data[1,:,:,:].copy()
      fid.close()
      if extension != '.ahi':
          return data
      else:
          return real, imag
  
  z6samlist = os.listdir('/Users/TejasReddy9/Documents/PSA_Homeland/')
  z6paths = ['/Users/TejasReddy9/Documents/PSA_Homeland/' + z6sam for z6sam in z6samlist]
  del z6paths[0]
  
  arr_list = [read_data(z6path) for z6path in z6paths]
  x = np.stack(arr_list, axis=0)
  
  maximum = np.max(x)
  minimum = np.min(x)
  x = (x - minimum)/(maximum - minimum)
  
  z6sample30 = pd.read_csv('/Users/TejasReddy9/Documents/PSA_Homeland/zone6_sample30.csv')
  z6sample30.sort_values('Id', inplace=True)
  
  z6sample_90 = pd.read_csv('/Users/TejasReddy9/Documents/PSA_Homeland/zone6_sample90.csv')
  
  z6sample_120 = z6sample30.append(z6sample_90, ignore_index=True)
  z6sample_120.sort_values('Id', inplace=True)
  
  y = z6sample_120.iloc[:,2].values
  
  from sklearn.model_selection import train_test_split
  x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
  
  # Tuning the ANN
  from keras.models import Sequential
  from keras.layers import Dense, Flatten, Dropout
  
  # Evaluating the ANN
  from keras.wrappers.scikit_learn import KerasClassifier
  from sklearn.model_selection import GridSearchCV
  
  def build_classifier(optimizer):
      classifier = Sequential()
      classifier.add(Dense(25, input_shape=(512, 660, 16), activation='relu', kernel_initializer='uniform', name='dense1'))
      classifier.add(Dropout(rate=0.1, name='dropout1'))
      classifier.add(Flatten())
      classifier.add(Dense(50, activation='relu', kernel_initializer='uniform', name='dense2'))
      classifier.add(Dropout(rate=0.1, name='dropout2'))
      classifier.add(Dense(50, activation='relu', kernel_initializer='uniform', name='dense3'))
      classifier.add(Dropout(rate=0.1, name='dropout3'))
      classifier.add(Dense(50, activation='relu', kernel_initializer='uniform', name='dense4'))
      classifier.add(Dropout(rate=0.1, name='dropout4'))
      classifier.add(Dense(1, activation='sigmoid', kernel_initializer='uniform', name='dense5'))
      classifier.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])
      return classifier
  
  # Wrap the whole thing
  classifier = KerasClassifier(build_fn=build_classifier)
  
  parameters = {'batch_size': [25, 32],
                'nb_epoch': [50, 100],
                'optimizer': ['adam', 'rmsprop', ]}
  grid_search = GridSearchCV(estimator=classifier,
                             param_grid=parameters,
                             scoring='accuracy',
                             cv=10)
  grid_search = grid_search.fit(x_train, y_train)
  best_parameters = grid_search.best_params_
  best_accuracy = grid_search.best_score_
  
  print(best_parameters)
  print(best_accuracy)
  