Introduction

JP Gros est en stage L3 Math-Info pour 10 semaines dans l'équipe technique du JMMC (IPAG).

Il va travailler sur le logiciel OIFitsExplorer pour ajouter de nouvelles interfaces (exports pdf en ligne de commande, scripts Jython).

Taches

Exports PDF

Besoin: il faut améliorer l'interface en ligne de commande (shell) pour exporter un document PDF sans utiliser l'interface graphique.

Points à traiter:

  • interface ligne de commande: ajouter les options d'export: nom du fichier en sortie, mode d'export (multi-page, single-page) ...
  • utiliser en input un fichier OIFitsExplorer (extension oixp) qui décrit les données et les plots pour charger les données et la configuration des plots
  • exporter tous les plots définis dans 1 seul PDF (multi-page ou single-page = vue globale)

En bonus, il faudrait aussi exporter certains plots en images PNG ...

Rapport de stage (notes)

Dépendance des modules:

Diagram_JMMC_modules.png

04/05: première réunion.

05/06: explication du fonctionnement de OiFitsExplorer et Aspro2

06/05: test exportation en PDF ligne de commande : résultat ok (faire attention à l'environement notamment pour l affichage graphique) Creation classe TestExportPDF permettant de tester l exportation, cette classe permet de créer un fichier (fichier definit en dur dans le code)

07/05:fin de l'élaboration de n charts sur une meme page PDF. + tests pour enregister cette page a partir de l affichage graphique : OK questionnement sur la facon de mettre en place :

Rapport des tests de faisabilité / étude technique

Test 1: TestExportPDF

  • objectif: tester de produire un pdf VIDE à partir de la ligne de commande (test-pdf.sh)
  • status: OK (en mode shell 'pur' tty1)
  • description: TestExportPDF.main() (mode headless) crée un PlotChartPanel (vide sans données) et utilise PDFUtils.savePDF(...) pour écrire le fichier pdf
  • scénario: lancer le script test-pdf.sh:
cd /home/grosje/dev/oiTools/oiexplorer
JAVA_HOME=/home/grosje/apps/jdk1.8.0_45
/home/grosje/apps/netbeans-8.0/java/maven/bin/mvn "-Dexec.args=-classpath %classpath pdf.TestExportPDF" -Dexec.executable=/home/grosje/apps/jdk1.8.0_45/bin/java -Dexec.classpathScope=test -Dfile.encoding=UTF-8 org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
  • impacts: aucun (api existante); TestExportPDF
  • commentaires: ce test est important car le composant PlotChartPanel utilise l'API Swing (mouse listener, JPanel ...) et JFreeChart(java2d) et continue de bien fonctionner sans GUI (X11...)

Test 2: Export PDF multi-page (MainPanel.PDF_MULTI_PAGE = true)

  • objectif: tester de produire un PDF de plusieurs pages a partir de plusieurs plots
  • status: OK en mode graphique uniquement pour le moment
  • description: nouvelle action (export all) => 1 plot par page
  • scénario:
    • charger le fichier Test_PDF_3pages.oixp (data)
    • selectionner la VIEW_0 (PlotView)
    • cliquer sur l'action 'Export all plots to PDF'
    • donner un nom au fichier pdf
    • ouvrir le pdf et vérifier que cela correspond bien à tous les plots ouverts
  • impacts: MainPanel OIFitsExplorerExportAllPDFAction
  • commentaires: permet d exporter tous ses plots sur le meme fichier PDF

Test 3: Export PDF single-page (MainPanel.PDF_MULTI_PAGE = false)

  • objectif: tester de produire un PDF d'une seule page a partir de plusieurs plots (GridLayout)
  • status: OK en mode graphique uniquement pour le moment
  • description: action (export plot) => tous les plots dans une page
  • scénario:
    • charger le fichier Test_PDF_3pages.oixp (data)
    • selectionner une VIEW_x (PlotView)
    • cliquer sur l'action 'Export all plots to PDF'
    • donner un nom au fichier pdf
    • ouvrir le pdf et vérifier que cela correspond bien à tous les plots ouverts
  • impacts: PDFExportable.prepareChart() => JFreeChart[] + PDFUtils pour gerer tous les plots.
  • commentaires: permet d exporter tous ses plots sur la meme page d un fichier PDF

Test 4: Nouvelle Vue GlobalView avec export PDF (via PDFExportable)

  • objectif: regrouper plusieurs plots à l'écran => vision synthétique des données => interet pour le scientifique
  • status: OK en mode graphique uniquement pour le moment
  • description: action (export plot) => tous les plots dans une GlobalView => dans une page
  • scénario:
    • charger le fichier Test_PDF_3pages.oixp (data)
    • selectionner la Global_View
    • cliquer sur l'action 'Export plot to PDF'
    • donner un nom au fichier pdf
    • ouvrir le pdf et vérifier que cela correspond bien à tous les plots ouverts
  • impacts: Creation de GlobalView qui implemente PDFExportable pour l'export en PDF
  • commentaires: beaucoup de questions fonctionnelles se posent:
    • garder/enlever la possibilite de pouvoir zoomer dans les plots affichés ?
    • empecher le fait de pouvoir ajouter des plots d'etoiles differentes = probleme possible de consistance ?
    • regrouper les plots partageant un meme axe ensemble (en colonne ou en ligne; par exemple: axe wavelength ...) ?
    • enlever le 'lien' entre la GlobalView et les PlotView car les plots sont partagés ?
    • pouvoir agencer facilement les plots dans la vue globale (ordre, position, taille ...)
    • Créer des nouveaux presets (modèle de vue) pour ces vues globales ? = généralisation des presets (pour l'instant ils ne concernent qu'un plot) => possibilité d'enregistrer ces vues / presets à approfondir

Test 5: TestExportPDF complet (laurent)

  • objectif: tester de produire un pdf COMPLET (avec des données) à partir de la ligne de commande (test-pdf.sh)
  • status: OK (en mode shell 'pur' tty1)
  • impacts: aucun (api existante); TestExportPDF
  • commentaires:
    • ajout du chargement d'un fichier de données et alimentation des plots (evenements) puis export pdf
    • attention: probleme de synchronisation (multi-threads + traitements asynchrones): à corriger par la suite

Test 6: Utilisation en ligne de commande dans App (Jmcs)

  • objectif: creer le lien entre l'exportation PDF et les parametres en ligne de commande
  • status: OK pour l'affichage help, reste a recuperer l'implementation faite dans TestExportPDF
  • description ./OIFitsExplorer [-pdf nomFichier] [-png NomFichier] [-mode true/false (PDF_MULTIPAGE)] [-anciens_arguments]
  • scénario
    • éxécuter la ligne de commande avec les arguments pour indiquer le format d'exportation ainsi que le nom du fichier et le mode (multi page ou non)
    • Verifier que le fichier PDF correspond bien aux critères demandés.
  • impacts : OIFitsExplorer (App) @Override defineCustomCommandLineArgumentsAndHelp()
  • commentaires : Derniere etape des tests avant de pouvoir valider la faisabilité technique.

Test 7: Utilisation de l'interface Drawable au lieu de la classe JFreeChart dans PDFExportable

  • objectif: pouvoir exporter autre chose que des plots (bloc de texte, autres dessins, diagrammes ...) et aussi appliquer l'approche WYSIWYG çàd exporter la vue globale telle qu'elle est à l'écran
  • status: KO car le pdf produit contient alors des images pixellisées çàd non vectorielles + problemes de proportions car Swing paint() utilise la taille du JPanel en pixels et non en points (72dpi)
  • description export => export charts + tout autre composant implementant Drawable
  • scénario : éxécuter le programme de la meme maniere que precedemment, l amelioration offre une plus grande possibilite d'export.
  • impacts : PDFUtils (prepareChart), PDFExportable, GlobalView.draw(g2d) utilise JComponent.paint(g2d)
  • commentaires : Test qui est utile car on veut pouvoir mettre autre chose que des charts dans notre PDF (ou PNG) plus tard. Ce test s'est releve non operationnel c est une amelioration qu il faudra revoir dans l avenir.

Test 8 : Générisation du code

  • Objectif : Factoriiser le code et changer le nom de certaines qui etaient obsoletes.
  • Status : OK en mode shell et graphique
  • Description : Pour l'utilisateur l'execution ne change pas
  • Scénarion : Idem
  • Impacts : PDFutils => (Writer + PDFWriter,ImageWriter) PDFOptions => (DocumentOptions + PDFOptions,ImageOptions)
  • Commentaires : Tache qui nous permettra par la suite de pouvoir modifier le code beaucoup plus facilement (par exemple ajoute de format exportable)

Diagramme des dépendances apres générisation : * exportDiagram.png:
exportDiagram.png

Bilan de l'étude:

2 solutions pour faire des PDFs en ligne de commande:

  • approche printer (pdf)
  • approche Global View (WYSIWYG à revoir)

avantages / inconvénients:

  • conserver tous les plots en un seul PDF / beaucoup de pages a imprimer
  • vue rapide sur tous les plots en une seule page / taille reduite si nombre de plots trop eleves: ajuster la mise en page dans ce cas (taille minimum au plot et plusieurs pages çad 8 plots par page max ...)

Plan d'action:

  • Enrichir l'API Jmcs pour les arguments et gérer le mode SHELL => processShellCommandLine() callback

en sortie: App._customArgumentValues=

  • open = 'fichier à ouvrir'
  • pdf = 'fichier pdf à ecrire'
  • png = 'fichier png à ecrire'
  • mode = ...
tous optionnels

Implementation

  • Solution définitive : main()
    • OIFitsExplorer.defineCustomCommandLineArgumentsAndHelp(): définir les arguments (pdf, png, jpg, mode, dims): OK
    • OIFitsExplorer.processShellCommandLine(): OK
      • verifier les valeurs des arguments: pdf, png, jpg, mode, dims (string) *tester toutes les valeurs possibles parmi -open TEST_PDF_3pages.oixp -pdf toto.pdf (ex -pdf : bug , -open -pdf : devrait marcher, -open TEST_PDF_3pages.oixp / : bug...)
      • reutiliser App.openCommandLineFile(): revoir sequence démarrage (services / actions / GUI)
      • instancier le data model çàd les vues = creer les PlotChartPanel à partir des Plots présents dans le fichier OIXP: Non pas besoin de recoder cela: on reutilise MainPanel() + event notifiers ... OK
      • PIEGE (laurent): gerer le probleme de synchronisation (evenements asynchrones) = nouvel event READY (executé à la fin) : OK Ajout de readyEventListener un OIFitsCollectionManagerEventListener pour déterminer quand tous les evennements ont terminé, pour cela, on utilise listener.onProcess(event) (dans EventNotifier) qui permet de determiner le type d event en cours, si c est un READY event, on lance alors doExport() qui va exporter le fichier PDF
      • export plots:
        • PDF: en fonction du mode:
        • PNG: A FAIRE :OK * creer un PNGUtils dans le meme esprit que PDFUtils: g2d = image.createGraphics() => drawble.draw(g2d) puis faire savePNG(image) : OK * objectif: pouvoir enregistrer des plots en format PNG (voire en format image dans l'avenir) * status: OK mais uniquemment en utilisant TestExportPDF car il faut gerer l argument PNG en ligne de commande * description
  • scénario : entrer -open nomFichier [-png] [NomPremierFichierImage]
  • impacts : creation de PNGUtils, prevoir des modifications dans la gestion des arguments MainPanel modifié afin de préparer l'exportation en fonction des options donées par l'utilisateur.
ExportPDFAction 'refactored' en OIFitsExplorerExportAction afin d'exporter la view selectionnée en fichier selon le format (PDF, PNG, JPG). et OIFitsExplorerAllAction afin d'exporter tous les charts en un seul fichier selon le format (PDF, PNG, JPG). Ajout de ExportUtils, qui utilise des export listeners et des exporting events. OIFitsExplorer modifié afin d'initialiser l'exportation en fonction des arguments avec processShellCommandLine() dans ExportUtils et implémenter la définition des arguments en ligne de commande : format de fichier (PDF, PNG, JPG) mode argument (single, multi, default) et dims argument (width,height). LoadOIDataCollectionAction modifié pour fire le ready event aux listener.

  • Bugs ou améliorations a effectuer : Gérer la global view quand aucun fichier n'est chargé et afficher une page blanche (ghost view) au lieu de laisser un graphique vide.
Enlever le fait de pouvoir modifier un chart de la global vie en changeant d etoile ? Ou indiquer quelle vie est active (par exemple surligner l'onglet concerné). * pour chaque vue => creer un fichier PNG : OK

Implémentation dimensions exportable en shell mode

  • objectif: Pouvoir exporter des miniatures pour les utiliser sur des sites internet par exemple.
  • status: OK d'après les jeux de tests
  • description ./OIFitsExplorer [-dim width(int),height(int)] [anciens arguments]
  • scénario : Executer le programme en ligne de commande comme précédemment, seul l'argument décris au dessus change l'execution du programme.
  • impacts : creation classe DocumentParameters contenant deux doubles (width et height) et un enum DocumentMode ImageExportUtils ExportPDFAction OIFitsExplorer
ExportUtils
  • commentaires : Dimensionnement disponible uniquement pour els fichiers images.

Test mode exportation :

* objectif: Laisser le choix à l'utilisateur s'il souhaite exporter seulement la globalview(single mode) ou les plots (default mode) ou tout à la fois (multi mode)
  • status: OK en shell mode et graphique
  • description ./OIFitsExplorer [ -mode single/multi/default ]
  • scénario : éxécuter le programme en renseignant le mode comme indiqué dans la description
  • impacts : MainPanel (prepareExport), PDFExportable (DocumentMode)
  • commentaires : Modification qui apporte des possibilités supplémentaires.

Test a effectuer :

  • Appel de JFrame trop tot, utiliser le debugger pour voir d ou vient le probleme.
  • Jython: regarder jython.org, installer l'outil et voir les tutorials:
    • premier essais: calculer des colonnes à partir de formules python: VIS2=VIS^2 : sqrt(vis2)/vis2_err

Tests sur les arguments

  • Tests en ligne de commande:
    • -pdf, -png, -jpg : OK
    • -mode single : OK
    • -mode multi : OK
    • -mode default ou [DEFAULT MODE] : OK
    • -dims [int,int] : OK
    • Jeux de tests "catchés" : -dim 1,1 -dim 10, -dim -10,10 -dim , -dim 10a,10 -dim ,10
  • Tests en graphique
    • Affichage ok (sauf pour l'affichage sans collection)
    • Export plot OK
    • Export all plots OK

TODO:

changer les noms de PDFExportable et PDFOptions proposition : modifier le nom de PDFUtils en ImageUtils par exemple pour pouvoir sauvegarder en un autre format que PNG

Introduction a Jython :

installer le package a partir de ce lien : http://www.jython.org/downloads.html decompresser le fichier téléchargé : java -jar jython-installer-2.7.0.jar Pour lancer le prompt, il faut entrer la commande suivante : java -jar jython.jar on peut ensuite executer des instructions ligne par ligne.

Pour pouvoir exécuter un fichier en Jython, il faut indiquer le chemin d'accès, ensuite il faut entrer les instructions dans le fichier et l'exécuter de cette façon :

java -jar jython.jar cheminDacces/monFichierJython.py

Premier test : effectuer un moteur Python qui effectue des calculs sur un tableau Java et retourne le résultat en Java :

  • Utiliser le package Numpy: *Necessite de telecharger JyNI
    • Version alpha, compatible avec peu d OS

Deuxieme test : effectuer un moteur Python qui prend en charge des tableaux 2D dans une méthode appelée par main

  • objectif : test de faisabilité avant de passer à l'implémentation sur le logiciel
  • status : OK
  • commentaires

Troisieme test : Implémentation dans une méthode de OIData

  • Objectif : tester l'appel de la nouvelle méthode eval depuis une méthode de OIData afin de retourner un tableau de résultats
  • Description : Implémenter une classe qui a à partir d'une expression donnée effectue le calcul sur toutes les colonnes d'une oitable donnée
  • Impacts : Methodes get de OIData + creation JythonEval.
  • Commentaires : retourne uniquement des double[][] pour l'instant, à noter que dans le cas de double[] en entrée le cas est géré quand meme.

Quatrième test : Déclarer l'expression dans une des classes héritées de OIData

  • Objectif : Permettre d'implémenter dans l'avenir une méthode dans OIData qui calcule n'importe quelle expression donnée en paramètre
  • Statut : OK
  • Description :
  • Impacts : Création d'un construteur pour WaveColumnMeta qui prend en charge un String qui est l'expression à calculer. Ajout de la WaveColumnMeta dans la table voulue.
  • Scénario : inchangé Création d'une méthode dans OIData appellée getJythonExpressionResults qui calcule a partir du nom d'une meta colonne et d'une expression le tableau de double[][] associé.
  • Commentaires : Etape qui va permettre dans l'avenir de regrouper les méthodes de calcul dans getJythonExpressionResults.

Cinquième test : Entrer les expression directement dans la fenetre GUI

  • Objectif : Permettre a l'utilisateur d'entrer une formule et de voir le plot s'afficher à l'ecran.
  • Statut : Refresh
  • Description :
  • Impacts : PlotDefinitionEditor pour l'ajout du layout implémenté par UserExprEditor qui permet d'entrer les paramètres souhaités.
OIFitsCollectionManager : ajout de modifyExprColumnInOIFitsCollection. A partir du nom d'un fichier OIFits et de l'expression entrée dans UserExprEditor, cette méthode va pour chaque table OIData supprimer l expression ou l'updater et effectuer le calcul demandé.
  • Scénario : Charger la collection souhaitée, aller dans une view (à changer) cliquer sur le bouton 'expr editor' et entrer un nom et l'expression voulue dans les champs correspondants.

Sixième test : Gérer les erreurs possibles

  • Objectif : Afficher des messages d'erreurs pour que l'utilisateur puisse comprendre à quel endroit il a fait une erreur + eviter de faire des calculs inutiles sur toutes les tables.
  • Statut : OK
  • Description
  • Impacts : Modification de modifyExprColumnInOIFitsCollection afin de 'catcher' une potentielle erreur avant la partie des calculs.
Création de checkExpression qui sert de lien entre la classe OIFitsCollectionManager et JythonEval ( méthode non plublic). Modification de eval dans JythonEval : ajout d'un paramètre permettant d'indiquer si on souhaiter effectuer l'expression sur un échantillon de tables (testOnly = true pour trouver une eventuelle erreur dans l'expression) ou sur toutes les tables comme avant.
  • Scénario : Inchangé
Exemples de fichiers Jython :

#!/home/grosje/jython2.7.0

print("Hello world ! \n")
a =input("Veuillez entrer un chiffre")
if( a<0) :
	print("Votre chiffre est negatif")
else :
	print("Votre chiffre est positif")

#!/home/grosje/jython2.7.0
# /!\ ne pas oublier les ':' apres les boucles, définitions de fonctions et conditions.
#toujours definir la fonction avant de l appeler :
def multiplication(param=4): # on peut definir les valeurs par défaut avec param = valeurDefaut
	i = 0
	while(i <=10):
		print( " on trouve ",i*param )
		i +=1
        return param*param

nb = input('entrez le nb a multiplier ')
print(multiplication(nb))
print(multiplication())
Parcours multiplier toutes les cases d un tableau et les mettre dans un autre tableau :
from array import zeros, array
tab = array(‘d’, [1.0, 2.0, 3.14]) 
tab2 = array('d')
a = 2.0
for s in tab :
	tab2.append(s*a)
	print (tab2)
#définition de fonction en une ligne 
f = lambda x: x * x

Introduction a JEL :

L'approche JEL est un peu différente de l'approche Jython, il faut compiler l'expression avant de pouvoir l'exécuter. Pour compiler l'expression il faut également indiquer une librairie. A cette librairie on indique un resolver qui va parser l'expression saisie par l'utilisateur. Ensuite il faut créer une variable provider qui va contenir le tableau des colonnes voulues ainsi que leur valeurs (le nom des colonnes étant déterminé par le résolveur). Ensuite il faut exécuter l'expression compilée avec le contexte. Le contexte étant le résolveur et le provider.
Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng exportDiagram.png r1 manage 45.5 K 2015-06-08 - 14:11 JeanPhilippeGros  
Edit | Attach | Watch | Print version | History: r36 < r35 < r34 < r33 < r32 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r36 - 2015-07-08 - JeanPhilippeGros
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback