#!/usr/bin/python3
# -*- coding: utf-8 -*-
#-------------------------------------------
# logiciel de calcul d'une mosaïque de quatre matrices carrées
#
# Historique 
#---------------------------------------------------------
# rev.#    Date    # Commentaires
# 0.1 # 01/02/2021 # Premier jet
# 0.2 # 05/02/2021 # Précisions sur le mode d'emploi
# 0.3 # 10/02/2021 # Passage des paramètres durée, No (Parking) et nom de la cible à calxx.py
# 0.4 # 10/02/2021 # Le nom de la cible est (underscore) "_" si indéterminé
# 0.5 # 11/02/2021 # lancement différé avec 'at' lignes 331-334 - première matrice immédiatement, les autres à la même heure les jours suivants
# 0.6 # 12/02/2021 # Le lancement des scripts ne fonctionne pas en interne. 
# 0.7 # 12/02/2021 # Le lancement des scipts est effectué séparemment dans application mosaic_run.py
# 0.8 # 14/02/2021 # Appel à cal28.py qui signale l'acquisision via le drapeau du Préampli 2
# 0.9 # 18/02/2021 # On termine la matrice 4 par un retour au parking
#
#
import os
import time
import sys
import threading
import datetime
import pytz
import subprocess
import datetime
from datetime import timedelta

Version = 0.9
VERSION_CAL = "28"

def conv_sexa(HMS):
    if HMS[0] == '-':
        HMS_pos = HMS[1:]
        negatif = True
    else :
        HMS_pos = HMS
        negatif = False
    ctrl = (len(HMS_pos) == 7) or (len(HMS_pos) == 8)
    if ctrl:
        if (len(HMS_pos) == 8) :
            ctrl = (HMS_pos[2] == ':') and (HMS_pos[5] == ':')
            heures = int(HMS_pos[0:2])
            minutes = int(HMS_pos[3:5])
            secondes = int(HMS_pos[6:8])
        else :
            ctrl = (HMS_pos[1] == ':') and (HMS_pos[4] == ':')
            heures = int(HMS_pos[0:1])
            minutes = int(HMS_pos[2:4])
            secondes = int(HMS_pos[5:7])
    if ctrl :
        if (negatif == False) :
            return (heures + (minutes / 60) + (secondes / 3600))
        else :
            return (-heures	- (minutes / 60) - (secondes / 3600))
    else :
        return (99.9)

# Traitement des paramètres

# print(len(sys.argv), ' arguments : ',sys.argv)
if (len(sys.argv) < 3):
   print ("Mosaic calcule une mosaïque carrée de 4 matrices carrées.")
   print
   print ("Nombre de paramètres insufisants, il faut au moins 'Ascension Droite' et 'Déclinaison'.")
   print ("format : mosaic.py <Ascension Droite> <Déclinaison> [<pas>] [<nb de pas en AD et Dec>]")
   print ("l'Ascension Droite est exprimée en heures décimales")
   print ("La Déclinaison est exprimée en degrés décimaux")
   print ("La valeur du pas est exprimée en degrés décimaux, et est identique pour les deux axes")  
   print ("Notez bien que la mosaïque doit avoir une dimension double des matrices carrées, donc 38 pour 19x19")
   print ("ou 22 pour 11x11 ou 14 pour 7x7 par exemple.") 
   exit(2)
try:
   AD = float(sys.argv[1])
except:
   AD = conv_sexa(sys.argv[1])
   if AD > 24 :
	   print (AD,"impossible de convertir l'ascension droite : utiliser un format HH:MM:SS ou flottant")
	   exit(3)
try:
   Dec = float(sys.argv[2])
except:
   Dec = conv_sexa(sys.argv[2])
   if Dec > 90 :
	   print ("impossible de convertir la déclinaison : utiliser un format HH:MM:SS ou flottant")
	   exit(4)
if (len(sys.argv) >= 4):
   try:
      Pas = float(sys.argv[3])
   except:
      Pas = 0.1    # Pas de 0.1° pris par défaut
else:
   Pas = 0.1       # Pas de 0.1° pris en absence de paramètre
Pas_AD = Pas / 15.0
if (len(sys.argv) >= 5):
   try: 
      Nb_AD = int(sys.argv[4])
   except:
      Nb_AD = 38 # 38 pas pris par défaut
else: 
   Nb_AD = 38    # 38 pas pris en absence d'argument ( 19 + 19 ) x 2
if (len(sys.argv) >= 6):
   try: 
      Duree = int(sys.argv[5])
   except:
      Duree = 1 # 1 minute par observation pris par défaut
else: 
    Duree = 1    # 1 minute en absence d'argument
if (len(sys.argv) >= 7):
   try: 
      Parking = sys.argv[6]
   except:
      Parking = "N" # Pas de retour au parking pris par défaut
else: 
   Parking = "N"    #  Pas de retour au parking pris par défaut

# Par défaut le nom de la cible est un "tiret bas"
   Nom_Cible = "_"
if (len(sys.argv) >= 8):
   Nom_Cible = sys.argv[7]

Nb_Dec = Nb_AD
AD_min = AD - (Pas_AD * ((Nb_AD)) / 2) 
AD_max = AD + (Pas_AD * ((Nb_AD)) / 2)
Dec_min = Dec - (Pas * ((Nb_Dec)) / 2)
Dec_max = Dec + (Pas * ((Nb_Dec)) / 2)
# 
# Résumé des paramètres choisis
#------------------------------
print("Paramètres de base de la mosaïque")
print("=================================")
print(" ")
print("Nombre de pas en AD/Dec : ", Nb_AD)
print(" ")
print("Ascension Droite :        ", AD)
pad = str('{:.5F}'.format(Pas_AD))
print("Pas en Ascension Droite :  " , pad)
admin = str('{:.5F}'.format(AD_min))
print("Ascension Droite mini. :  " , admin)
admax = str('{:.5F}'.format(AD_max))
print("Ascension Droite maxi. :  " , admax)
print("Déclinaison :             ", Dec)
print("Pas en Déclinaison :      ", Pas)
decmin = str('{:.5F}'.format(Dec_min))
print("Déclinaison minimale :    " , decmin)
decmax = str('{:.5F}'.format(Dec_max))
print("Déclinaison maximale :    " , decmax)
print("Durée de chaque observation : ", Duree)
print(" ")
print(" ")
#
# La cible visée est au centre de la mosaïque
# moins N/2 points en AD et plus N/2 points en DEC 
# Chaque matrice sera calculée avec le quart des points de la mosaïque
# de part et d'autre du centre des matrices
# la matrice #1 est décalée d'une demi matrice en AD et DEC
# Les autres sont décalées d'une demi mosaïque en +/- AD et DEC
#
Nb_AD = Nb_AD / 2
Nb_Dec = Nb_Dec / 2
# le centre de l'AD est décalé d'un quart de mosaïque
# Nb_AD et Nb_Dec sont déjà divisés par 2
# AD en négatif - Dec en positif 
AD1 = AD - (Pas_AD * Nb_AD / 2 )
Dec1 = Dec + (Pas * Nb_Dec / 2)
AD_min = AD1 - (Pas_AD * ((Nb_AD) / 2)) 
AD_max = AD1 + (Pas_AD * ((Nb_AD) / 2))
Dec_min = Dec1 - (Pas * ((Nb_Dec) / 2))
Dec_max = Dec1 + (Pas * ((Nb_Dec) / 2))
ad1 = str('{:.5F}'.format(AD1))
dec1 = str('{:.5F}'.format(Dec1))
print(" ")
print(" ")
print("Paramètres calculés matrice #1")
print("------------------------------")
#print(" ")
print("Ascension Droite        = ", ad1)
print("Déclinaison             = ", dec1)
print("Pas en Déclinaison :      ", Pas)
print("Nombre de pas en AD/Dec : ", int(Nb_AD))
print
admin = str('{:.5F}'.format(AD_min))
print("Ascension Droite mini. :" , admin)
admax = str('{:.5F}'.format(AD_max))
print("Ascension Droite maxi. :" , admax)
decmin = str('{:.5F}'.format(Dec_min))
print("Déclinaison minimale   :" , decmin)
decmax = str('{:.5F}'.format(Dec_max))
print("Déclinaison maximale   :" , decmax)
print
# Fichier batch matrice #0
sortie = "matrice_0.sh"
sortie0 = open(sortie,'w')
sortie = "/usr/bin/python3 cal"+ VERSION_CAL + ".py" + " "+ ad1 + " " + dec1 + " " + str(0.1) + " " + str(1) + " " + str(1) + " " + str("N") +" "+ Nom_Cible + "\n"
sortie0.write(sortie)
# Fichier batch matrice #1
sortie = "matrice_1.sh"
sortie1 = open(sortie,'w')
sortie = "# mosaic.py version " + str(Version) + "\n"
sortie1.write(sortie)
sortie = "# matrice_1 radec " + str(int(Nb_AD)) + " x " + str(int(Nb_Dec)) + "\n"
sortie1.write(sortie)
sortie = "# pas = " + str(Pas) + "\n"
sortie1.write(sortie)
sortie = "# Nombre de pas = " + str(int(Nb_AD))+ "\n"
sortie1.write(sortie)
sortie = "/usr/bin/python3 cal"+ VERSION_CAL + ".py" + " "+ ad1 + " " + dec1 + " " + str(Pas) + " " + str(int(Nb_AD)) + " " + str(Duree) + " " + Parking +" "+ Nom_Cible + "\n"
sortie1.write(sortie)
#
AD2 = AD1 + (Pas_AD * Nb_AD )
Dec2 = Dec1
AD_min = AD2 - (Pas_AD * ((Nb_AD) / 2)) 
AD_max = AD2 + (Pas_AD * ((Nb_AD) / 2))
Dec_min = Dec2 - (Pas * ((Nb_Dec) / 2))
Dec_max = Dec2 + (Pas * ((Nb_Dec) / 2))
ad2 = str('{:.5F}'.format(AD2))
dec2 = str('{:.5F}'.format(Dec2))
print(" ")
print("Paramètres calculés matrice #2")
print("------------------------------")
#print(" ")
print("Ascension Droite        = ", ad2)
print("Déclinaison             = ", dec2)
print("Pas en Déclinaison :      ", Pas)
print("Nombre de pas en AD/Dec : ", int(Nb_AD))
admin = str('{:.5F}'.format(AD_min))
print("Ascension Droite mini. :" , admin)
admax = str('{:.5F}'.format(AD_max))
print("Ascension Droite maxi. :" , admax)
decmin = str('{:.5F}'.format(Dec_min))
print("Déclinaison minimale   :" , decmin)
decmax = str('{:.5F}'.format(Dec_max))
print("Déclinaison maximale   :" , decmax)
print
# Fichier batch matrice #2
sortie = "matrice_2.sh"
sortie2 = open(sortie,'w')
sortie = "# mosaic.py version " + str(Version) + "\n"
sortie2.write(sortie)
sortie = "# matrice_2 radec " + str(int(Nb_AD)) + " x " + str(int(Nb_Dec)) + "\n"
sortie2.write(sortie)
sortie = "# pas = " + str(Pas) + "\n"
sortie2.write(sortie)
sortie = "# Nombre de pas = " + str(int(Nb_AD))+ "\n"
sortie2.write(sortie)
sortie = "/usr/bin/python3 cal"+ VERSION_CAL + ".py" + " "+ ad2 + " " + dec2 + " " + str(Pas) + " " + str(int(Nb_AD)) + " " + str(Duree) + " " + Parking +" "+ Nom_Cible +"\n"
sortie2.write(sortie)
#
# La cible de la matrice #3 est identique en AD et décalée de -N/2 points en déclinaison
# Nb_Dec est déjà divisé par 2
AD3 = AD2
Dec3 = Dec2 - (Pas * Nb_Dec)
AD_min = AD3 - (Pas_AD * ((Nb_AD) / 2)) 
AD_max = AD3 + (Pas_AD * ((Nb_AD) / 2))
Dec_min = Dec3 - (Pas * ((Nb_Dec) / 2))
Dec_max = Dec3 + (Pas * ((Nb_Dec) / 2))
ad3 = str('{:.5F}'.format(AD3))
dec3 = str('{:.5F}'.format(Dec3))
print(" ")
print("Paramètres calculés matrice #3")
print("------------------------------")
print("Ascension Droite        = ", ad3)
print("Déclinaison             = ", dec3)
print("Pas en Déclinaison :      ", Pas)
print("Nombre de pas en AD/Dec : ", int(Nb_AD))
print
print
admin = str('{:.5F}'.format(AD_min))
print("Ascension Droite mini. :" , admin)
admax = str('{:.5F}'.format(AD_max))
print("Ascension Droite maxi. :" , admax)
decmin = str('{:.5F}'.format(Dec_min))
print("Déclinaison minimale   :" , decmin)
decmax = str('{:.5F}'.format(Dec_max))
print("Déclinaison maximale   :" , decmax)
print(" ")
# Fichier batch matrice #3
sortie = "matrice_3.sh"
sortie3 = open(sortie,'w')
sortie = "# mosaic.py version " + str(Version) + "\n"
sortie3.write(sortie)
sortie = "# matrice_3 radec " + str(int(Nb_AD)) + " x " + str(int(Nb_Dec)) + "\n"
sortie3.write(sortie)
sortie = "# pas = " + str(Pas) + "\n"
sortie3.write(sortie)
sortie = "# Nombre de pas = " + str(int(Nb_AD))+ "\n"
sortie3.write(sortie)
sortie = "/usr/bin/python3 cal"+ VERSION_CAL + ".py" + " "+ ad3 + " " + dec3 + " " + str(Pas) + " " + str(int(Nb_AD)) + " " + str(Duree)  + " " + Parking +" " + Nom_Cible +"\n"
sortie3.write(sortie)
#
# La cible de la matrice #4 est identique en Déclinaison à #1
# et décalée de -N/2 en Ascension Droite
# Nb_AD est déja divisé par 2
#
#AD4 = AD3 - (Pas_AD * Nb_AD)
AD4 = AD1
#Dec4 = Dec3
Dec4 = Dec1 - (Pas * Nb_Dec)
AD_min = AD4 - (Pas_AD * ((Nb_AD) / 2)) 
AD_max = AD4 + (Pas_AD * ((Nb_AD) / 2))
Dec_min = Dec4 - (Pas * ((Nb_Dec) / 2))
Dec_max = Dec4 + (Pas * ((Nb_Dec) / 2))
ad4 = str('{:.5F}'.format(AD4))
dec4 = str('{:.5F}'.format(Dec4))
print(" ")
print("Paramètres calculés matrice #4")
print("------------------------------")
print("Ascension Droite        = ", ad4)
print("Déclinaison             = ", dec4)
print("Pas en Déclinaison :      ", Pas)
print("Nombre de pas en AD/Dec : ", int(Nb_AD))
admin = str('{:.5F}'.format(AD_min))
print("Ascension Droite mini. :" , admin)
admax = str('{:.5F}'.format(AD_max))
print("Ascension Droite maxi. :" , admax)
decmin = str('{:.5F}'.format(Dec_min))
print("Déclinaison minimale   :" , decmin)
decmax = str('{:.5F}'.format(Dec_max))
print("Déclinaison maximale   :" , decmax)
print(" ")
# Fichier batch matrice #4
sortie = "matrice_4.sh"
sortie4 = open(sortie,'w')
sortie = "# mosaic.py version " + str(Version) + "\n"
sortie4.write(sortie)
sortie = "# matrice_4 radec " + str(int(Nb_AD)) + " x " + str(int(Nb_Dec)) + "\n"
sortie4.write(sortie)
sortie = "# pas = " + str(Pas) + "\n"
sortie4.write(sortie)
sortie = "# Nombre de pas = " + str(int(Nb_AD))+ "\n"
sortie4.write(sortie)
sortie = "/usr/bin/python3 cal"+ VERSION_CAL + ".py" + " "+ ad4 + " " + dec4 + " " + str(Pas) + " " + str(int(Nb_AD)) + " " + str(Duree)  + " Y " + Nom_Cible +"\n"
sortie4.write(sortie)
#
# Fichier batch matrice #5 pour retour au parking
sortie = "matrice_5.sh"
sortie0 = open(sortie,'w')
sortie = "/usr/bin/python3 cal"+ VERSION_CAL + ".py" + " "+ ad1 + " " + dec1 + " " + str(0.1) + " " + str(1) + " " + str(1) + " Y "+ Nom_Cible + "\n"
sortie0.write(sortie)
delai = 10
# Permissions d'exécution des fichiers batch
time.sleep(delai)
subprocess.call(["chmod", "a+x", "matrice_0.sh"])
time.sleep(delai)
subprocess.call(["chmod", "a+x", "matrice_1.sh"])
time.sleep(delai)
subprocess.call(["chmod", "a+x", "matrice_2.sh"])
time.sleep(delai)
subprocess.call(["chmod", "a+x", "matrice_3.sh"])
time.sleep(delai)
subprocess.call(["chmod", "a+x", "matrice_4.sh"])
time.sleep(delai)
subprocess.call(["chmod", "a+x", "matrice_5.sh"])
# Lancements des scripts séparé dans mosaic_run.py
#
#
