## Aide de Tenmon

Tenmon est destiné principalement à la visualisation de photos et d'images astronomique. Il prend en charge les formats suivants :

- FITS 8, 16 bit entier et 32 bit point flottant
- XISF 8, 16 bit entier et 32 bit point flottant
- images JPEG, PNG, BMP, GIF, PBM, PGM, PPM et SVG
- images RAW CR2, CR3, NEF, DNG

### Fenêtre principale

La fenêtre principale affiche l'image actuellement chargée. Sur la gauche se trouve le panneau Informations de l'image qui affiche des détails sur l'image chargée. Le panneau Système de fichier affiche d'autres images dans le même répertoire que l'image chargée. En haut se trouve le menu principal et en dessous se trouve le panneau Réglage de la luminosité contenant diverses options pour l'étirement automatique des images linéaires.

Tous les panneaux de l'interface peuvent être déplacés et/ou fermés. Tout panneau fermé ou non visible peut être rouvert via le menu Fenêtres encrables en haut.

En bas, il y a une barre d'état qui affiche l'intensité ou la valeur du pixel rouge, vert, bleu sous le curseur de la souris, puis les coordonnées X et Y et, si l'image contient des métadonnées du World Coordinate System, elle affiche les coordonnées célestes.

### Ouvrir et enregistrer des images

Pour charger une image, sélectionnez Fichier->Ouvrir et choisissez le fichier. Une fois qu'un fichier est chargé, il devient visible dans le panneau d'image et le panneau du système de fichiers affiche les autres images dans le même répertoire.

L'image chargée peut être exportée dans un format différent avec Fichier->Enregistrer sous. Tous les formats JPEG, PNG FITS et XISF peuvent être sélectionnés. Dans le cas d'un enregistrement JPEG ou PNG, la fonction d'étirement de la luminosité est appliquée à l'image enregistrée. FITS et XISF sont enregistrés/convertis sans appliquer l'étirement. Pour ouvrir une image, vous pouvez également la faire glisser et la déposer dans la fenêtre principale.

### Voir

Le menu Voir propose des options pour contrôler la taille et l'échelle des images affichées :

- Zoom avant et Zoom arrière agrandissent et rétrécissent l'image. La molette de la souris peut également être utilisée pour zoomer librement.
- Meilleur ajustement, zoom automatiquement l'image pour l'adapter à la taille actuelle de la fenêtre.
- 100 %, zoom à l'échelle 1:1.
- Plein écran agrandit la fenêtre principale sur tout l'écran.
- Vignettes, affiche de petites vignettes pour toutes les images du répertoire actuel.

### Barre d'outils du réglage de la luminosité

Ces outils modifient la luminosité des images affichées.

À partir de la gauche, il y a une échelle de luminosité avec trois points réglables pour contrôler manuellement l'étirement.

- point noir - tous les pixels avec une valeur inférieure (plus sombre) que ce paramètre seront écrêtés en noir
- point médian - définit la valeur à étirer à 50 % d'intensité
- point blanc - tous les pixels avec une valeur supérieure (plus lumineuse) que celle-ci seront écrêtés en blanc

Après le curseur se trouvent 5 boutons pour la luminosité automatique :

- Luminosité automatique, applique automatiquement les points noirs et moyens pour rendre l'image avec une luminosité optimale.
- Réinitialiser, réinitialise les trois valeurs pour le point noir, moyen et blanc par défaut.
- Inverser, inverse les couleurs pour afficher l'image en négatif.
- Super pixel CFA , moyenne 2x2 pixels en un (adapté aux images d'une caméra couleur).
- Appliquer la luminosité automatique au chargement, applique la luminosité automatique pour chaque image lors du chargement.

### Marquer les images

Les images peuvent être marquées dans le menu Sélectionner. Pour afficher une liste des seules images marquées, utilisez Sélectionner->Afficher marqué. Cette boîte de dialogue peut être utile pour effacer les marques des images. Les images marquées affichent un caractère * dans la barre de titre de la fenêtre principale. Les images marquées peuvent être copiées ou déplacées vers un répertoire sélectionné avec Fichier->Copier/Déplacer les fichiers marqués. Après la copie ou le déplacement, la liste des fichiers marqués est effacée. La liste des fichiers marqués sera mémorisée après avoir quitté le programme.

Une autre façon de marquer des images est dans la vue de la base de données où vous pouvez sélectionner des lignes, puis sélectionner l'action marquer ou décocher dans le menu contextuel. Les fichiers marqués seront affichés en texte gras. La troisième façon de marquer les fichiers est de voir les vignettes où vous pouvez appuyer sur Maj et cliquer avec le bouton gauche de la souris et faire glisser sur les vignettes pour les marquer. Maintenir Ctrl décochera les fichiers.

### Système de fichier et arborescence

Le panneau du système de fichiers contient la liste des images du répertoire ouvert. Vous pouvez sélectionner un fichier dans cette liste et il sera affiché. Il est également possible d'utiliser les touches fléchées pour revenir en arrière (gauche et haut) et avancer (droite et bas) entre les images.

L'arborescence des fichiers montre la structure du système de fichiers. Vous pouvez cliquer avec le bouton droit de la souris pour afficher un menu contextuel permettant d'effectuer diverses actions du menu Fichier. Il y a aussi les actions suivantes

- Définir comme répertoire racine afficher uniquement ce répertoire et ses sous-répertoires
- Réinitialiser la racine afficher tout le système de fichiers
- Monter afficher le répertoire qui est un niveau au-dessus du répertoire racine actuel

### Base de donnée de fichiers FITS/XISF

Tenmon peut analyser un répertoire de fichiers FITS/XISF et indexer les métadonnées des en-têtes FITS dans sa base de données interne. Cela permet de rechercher et de trier des images en fonction de ces métadonnées.

Pour remplir la base de données, sélectionnez un répertoire de fichiers FITS/XISF avec Fichier->Indexer le répertoire. Une fois le répertoire parcouru, les métadonnées analysées à partir des images seront stockées dans la base de données. Pour actualiser la base de données, exécutez Fichier-> Ré-indexer les fichiers. Cela mettra à jour toutes les métadonnées modifiées et supprimera tout enregistrement de fichiers supprimés. Pour indexer de nouveaux fichiers, exécutez simplement à nouveau Fichier->Indexer le répertoire.

La base de données est visualisée via un panneau qui n'est pas visible dans la mise en page par défaut. Pour ajouter le panneau de base de données à la vue, basculez Fenêtres encrables->Base de données FITS/XISF. Une fois visible, le panneau de la base de données affiche la base de données sous forme de tableau avec une colonne pour chaque propriété. Sous le tableau se trouve un bouton pour sélectionner les colonnes/propriétés à afficher.

Au bas du panneau de la base de données se trouvent également trois boîtes de liste déroulante et des entrées de texte utilisées pour le filtrage. Sélectionnez la propriété à filtrer dans une liste déroulante et dans la zone de texte adjacente, entrez un texte à rechercher pour cette propriété. Ces trois boîtes contiennent la liste de toutes les propriétés qui sont trouvées pendant l'indexation, sauf les trois premières. La première définit la recherche dans le nom du fichier. Les deux suivantes "RA pos" et "DEC pos" permettent de filtrer les images indexées qui contiennent un point avec les coordonnées RA/DEC entrée. Le format attendu est trois nombres séparés par un espace. Dans le cas de "DEC pos", il accepte également le signe +-. L'omission d'un ou deux derniers chiffres est également valable. Quelques exemples "02 12 32" "-12 43 12" "+45 32" "13". Le fait de définir à la fois "RA pos" et "DEC pos" peut renvoyer des images qui ne contiennent pas le point saisi, car la recherche est faite sur les coordonnées RA/DEC minimum et maximum que les images contiennent. "RA range" et "DEC range" filtrent les images dont les coordonnées centrale se trouvent dans la plage saisie. En appuyant sur la touche Enter ou en cliquant sur le bouton Filtre, les enregistrements de la base de données seront filtrés en fonction des paramètres de recherche.

Caractères génériques :

- % (pourcentage) est un caractère générique représentant zéro ou plusieurs caractères.
- _ (trait de soulignement) est un caractère générique pour exactement un caractère quelconque.
- En l'absence de caractères génériques, le texte exacte doit correspondre.

Cet exemple filtre les fichiers où : "Bias" figure dans le nom de fichier, la propriété OBJECT est "M_42" (où le trait de soulignement peut être n'importe quel caractère) et la propriété DATE commence par "2022".

### Traitement par lot

Ce module permet d'écrire des scripts en JavaScript qui traitent des fichiers images. La fenêtre de traitement par lots se compose de trois parties principales. En haut se trouve la liste des fichiers et répertoires d'entrée. Vous pouvez ajouter des répertoires ou des fichiers individuels à cette liste. Les répertoires sont analysés de manière récursive pour trouver tous les fichiers, même les fichiers non image. Cette liste de fichiers est ensuite transmise au script dans un tableau nommé files. Dans le script, vous pouvez ensuite parcourir les fichiers comme ici.

    for(file of files)
    {
        if(file.suffix() == "fits")
        {
            core.log(file.fileName());
            file.convert(file.relativeFilePath(), "XISF");
        }
    }

#### core

Il existe un objet global appelé core qui possède ces méthodes.

- log(message) afficher le message dans la fenêtre du journal.
- mark(file) marquer le fichier de la même manière que dans l'interface graphique. Prend un objet de type File comme argument.
- unmark(file) décoche le fichier de la même manière que dans l'interface graphique. Prend un objet de type File comme argument.
- isMarked(file) vérifie si le fichier a été marqué. Prend un objet de type File comme argument.
- setMaxThread(maxthread) définir le nombre maximal de threads simultanés lors de l'exécution d'une tâche asynchrone.
- sync() attendre que toutes les tâches asynchrones soient terminées.
- getString(label = "", text = "") affiche la boîte de dialogue pour obtenir un text de l'utilisateur. La valeur text passée dans le premier argument est utilisée comme label de description. Le texte du deuxième argument est la valeur par défaut dans la zone de texte. Les deux paramètres sont facultatifs, donc l'appel à getString() est valide. Lorsque vous appuyez sur Annuler, il renvoie Undefined
- getInt(label = "", value = 0) affiche une boîte de dialogue avec une zone de saisie pour récupérer une valeur entière. Le texte passé dans le premier argument est utilisé comme label de description. Le deuxième paramètre est la valeur par défaut dans la zone de saisie. Les deux paramètres sont facultatifs. Lorsque vous appuyez sur Annuler, il renvoie Undefined.
- getFloat(label = "", value = 0, decimals = 3) affiche une boîte de dialogue avec une zone de saisie pour récupérer une valeur décimale. Le texte passé dans le premier argument est utilisé comme label de description. Le deuxième paramètre est la valeur par défaut dans la zone de saisie. Les trois paramètres sont facultatifs. Lorsque vous appuyez sur Annuler, il renvoie Undefined.
- getItem(items) affiche une boîte de dialogue de sélection qui permet de sélectionner un élément dans un tableau d'éléments. Lorsque vous appuyez sur Annuler, il renvoie Undefined.
- setStartingSolution(solution) with this you can set starting point and image scale. It accepth object with attributes "ra", "dec", "pixscale". Same object as returned by File.solve() method. You can also call it without paramer in which case it will clear any previously set values.
- getSolverProfile() return solver profile as Object.

      var profile = core.getSolverProfile();
      core.log(JSON.stringify(profile));

- setSolverProfile(index) set solver profile by index. Valid values are from 1 to 8 as in GUI.
- setSolverProfile(profile) set solver profile. Parameter is same as object returned by getSolverProfile() method
- question(question, buttons, title = "") show dialog with question. First argument question is string. Second argument buttons is array of following strings. "ok", "yes", "no", "yesall", "noall", "abort", "retry", "ignore", "cancel", "discard", "apply", "reset" Third argument title is optional string that show in title bar. It return button that was clicked as a string.

      var button = core.question("Apply to all files?", ["yes", "no"]);

- plot(graph) this method show graph defined by JS object.

      var chart = {
          "title": "Chart title", // Title that will show on top of chart
          "legend":
          {
              "visible": true,// default is true
              "align": "left" // allowed values are "top", "right", "bottom", "left". default is "top"
          },
          "series":[ // array of data series
              {
                  "title": "HFR",
                  "type": "bar", // type of the serie. Can be one of "line", "points", "linePoints", "bar"
                  "y":[2.5,3.1,2.6,2.2] // array of values
              },
              {
                  "title": "Ecc",
                  "y":[0.37, 0.4, 0.35, 0.25],
                  "color": "red" // color of serie. It can be name of color like "green" or RGB hex value "#ccddff"
              },
              {
                  "title": "Stars",
                  "type": "points", // type of serie. can be "line", "points", "linePoints" and "bar". Default is "line"
                  "shape": "star", // shape of markers. valid only for points
                  "x":[1, 2.5, 3.5, 6],// line, points and linePoints can also have "x" values. Otherwise it assume sequence 0,1,2 ...
                  "y":[523,412,487,510],
                  "y2": true, // if set to true this serie will use secondary Y axis
                  "bestFit": true, // show best fit line
                  "color": "#0000ff"
              }
          ]
      };

      core.plot(chart);

#### File

Dans le tableau files, il y a des instances d'objets de type File qui ont ces méthodes.

- fileName() renvoie le nom du fichier, à l'exclusion du chemin.
- absoluteFilePath() renvoie un chemin absolu incluant le nom du fichier.
- absolutePath() renvoie un chemin absolu sans le nom du fichier
- relativeFilePath() renvoie le chemin relatif incluant le nom du fichier par rapport au répertoire qui était dans la liste des répertoires à analyser. Par exemple, vous ajoutez C:/images comme répertoire d'entrée. Dans ce répertoire, il y a le fichier C:/images/lights/red/M42_001.fits, alors cette méthode renverra lights/red/M42_001.fits
- relativePath() renvoie le même chemin que la méthode précédente, mais sans le nom de fichier. lights/red
- baseName() renvoie le nom du fichier jusqu'au premier point. Par exemple, pour some.file.name.fits, il renverra some
- completeBaseName() renvoie le nom du fichier jusqu'au dernier point. Par exemple, pour some.file.name.fits, il renverra some.file.name
- suffix() renvoie la chaîne après le dernier point du nom de fichier. Par exemple fits
- size() renvoie la taille du fichier en octets.
- fitsKeywords() renvoie un tableau de chaînes avec chaque mot-clé présent dans l'en-tête. SIMPLE,BITPIX,NAXIS,NAXIS1,NAXIS2,EXTEND,COMMENT
- fitsValue(key) renvoie la valeur pour le mot-clé. En cas d'occurrences multiples, la dernière est renvoyée.
- fitsValues(key) renvoie un tableau de valeurs pour le mot clé.
- fitsRecords() renvoie un tableau d'objets avec des propriétés key, value et comment
- modifyFITSRecords(FITSRecordModify) modifier l'en-tête FITS en ajoutant, supprimant ou mettant à jour l'enregistrement FITS. Renvoie true en cas de succès. Reportez-vous à FITSRecordModify
- isMarked() renvoie true si le fichier est marqué.
- copy(newpath) Copie le fichier vers un nouvel emplacement. Il renvoie une instance du nouvel objet File qui représente ce fichier copié. Ce chemin peut être relatif ou absolu. Dans le cas où le paramètre newpath est un chemin relatif, le "Répertoire de sortie" des fenêtres de l'interface graphique est utilisé comme répertoire de base. Le paramètre newpath peut être un chemin absolu. Le fichier est ensuite copié vers ce chemin. En cas d'échec de la copie, il renvoie null.
- move(newpath) déplacer le fichier vers un nouvel emplacement. Il renvoie false si le déplacement a échoué. Cela peut se produire si la destination n'est pas accessible en écriture mais aussi si le fichier de destination existe déjà. Cette fonction n'écrase pas le fichier existant. Ce chemin peut être relatif ou absolu. Dans le cas où le paramètre newpath est un chemin relatif, le "répertoire de sortie" des fenêtres de l'interface graphique est utilisé comme répertoire de base. Le paramètre newpath peut être un chemin absolu. Le fichier est ensuite déplacé vers ce chemin.
- convert(outpath, format, params) Convertir un fichier image à partir de n'importe quel format que le programme peut ouvrir en FITS, XISF, JPEG, PNG, BMP. Les paramètres sont : outputpath chemin où l'image convertie sera enregistrée. Il remplace automatiquement le suffixe en fonction du format. format l'un des éléments suivants : "FITS", "XISF", "JPG", "PNG", "TIFF" ou "BMP". params objet avec les attributs "compressionType" et "compressionLevel". Les valeurs valides pour compressionType sont "gzip" ou "rice" lors de la conversion en FITS. Lors de la conversion en XISF, compressionType peut être "zlib", "lz4", "lz4hc", "zstd", "zlib+sh", "lz4+sh", "lz4hc+sh", "zstd+sh". Il est recommandé d'utiliser les variantes de compression "+sh". Le format XISF accepte également les "compressionLevel" dans la plage 0-100, où zéro est la compression la plus rapide et 100 la plus lente. Si vous omettez cet attribut ou le définissez sur -1, le niveau de compression par défaut sera utilisé. Il renvoie une nouvelle instance de File qui pointe vers le fichier converti.

      file.convert("converted_file.xisf", "xisf", {"compressionType": "zstd+sh", "compressionLevel": 70});
      file.convert("converted_file.fits", "fits", {"compressionType": "rice"});
      file.convert("converted_file.jpg", "png");

- convertAsync(outpath, format, params) même méthode que la précédente, mais effectue la conversion dans un thread séparé de manière asynchrone et en parallèle. Avant d'appeler une méthode sur un objet renvoyé par cette méthode, vous devez appeler `core.sync();` pour s'assurer que la conversion est effectuée et que le fichier de destination existe.

      let compression = {"compressionType": "zstd+sh"};
      let convertedFiles = [];
      for(file of files)
      {
          if(file.suffix() == "fits")
              convertedFiles.push(file.convertAsync("xisf/" + file.fileName(), "XISF", compression));
      }
      core.sync(); // ensure that files exist
      for(file of convertedFiles)// now we can iterate over the files
      {
          core.log(file.fileName() + " " + file.size()); // let print compressed file sizes
      }

- stats() calculer les statistiques d'images de base et les renvoyer sous forme d'objet avec des attributs "mean", "stddev", "median", "min", "max" et "mad".

      let s = file.stats();
      core.log("Median value is " + s.median);

- solve(updateHeader) this method will run plate solving on this image and will return solution in form of object with these attributes "ra" and "dec" which are center coordinates of image "fieldWidth" and "fieldHeight" which is FOV of image in arcseconds, "orientation" is degrees east of north, "pixscale" scale of image in arcseconds per pixel, "parity" true false value if the image was flipped in vertical direction, "raError" and "decError" deviation from starting point. When updateHeader is set to true it update FITS header for file with this solution. Default value is false.
- extractStars(hfr) extract stars will run extraction of stars. When parameter hfr is set to true it will fit HFR on every star. It return array of objects representing extracted stars. Each object in array will have these attributes "x" and "y" pixel coordinates of center of star, "mag" relative magnitude of star, "flux" total flux, "peak" peak value of star, "HFR" half flux radius of star, "a" and "b" semi major and minor axis of star, "theta" angle of orientation of the star, "ra" and "dec" coordinates of star, "numPixels" number of pixel occupied by the star in image.

#### FITSRecordModify

Cette classe est utilisée pour définir l'en-tête FITS des opérations de modification dans les fichiers FITS et XISF. Elle peut supprimer, mettre à jour et ajouter des enregistrements. L'ordre des opérations est également le suivant : suppression, puis mise à jour et enfin ajout. Les noms des mots-clés peuvent comporter jusqu'à 8 caractères et ne peuvent contenir que des lettres majuscules, les chiffres de 0 à 9, le trait d'union et le caractère de soulignement.

    let modify = new FITSRecordModify();
    modify.updateKeyword("OBJECT", "M42");
    modify.updateKeyword("MYTILE", "PART1", "adding custom keyword so WBPP can group it");
    modify.removeKeyword("OBJECT");
    // Peu importe qu'il soit spécifié comme dernier. Cela supprimera d'abord
    // l'enregistrement OBJECT existant, puis ajoutera à nouveau OBJECT=M42
    for(file in files)
    {
        file.modifyFITSRecords(modify);
    }

- new FITSRecordModify() créer une nouvelle instance de l'objet.
- removeKeyword(key); spécifier la suppression de l'enregistrement avec key comme mot-clé.
- updateKeyword(key, value, comment = "") spécifiez la mise à jour du mot-clé existant avec la valeur et le commentaire. Le commentaire est un paramètre facultatif. Si l'enregistrement avec le mot-clé n'existe pas, il en ajoutera un nouveau. À moins que vous ne souhaitiez avoir plusieurs enregistrements avec le même mot-clé (par exemple HISTORY), utilisez toujours cette méthode et non addKeyword.
- addKeyword(key, value, comment = "") spécifier l'ajout d'un nouveau mot-clé

PS: Le Kanji de icône (tenmon) signifie astronomie en japonais