Affichage des articles dont le libellé est ontology. Afficher tous les articles
Affichage des articles dont le libellé est ontology. Afficher tous les articles

07/09/2016

Sparql update un Polymer element pour mettre a jour un sparql endpoint

Objectif de cet article : Créer un element Polymer pour mettre à jour un sparql endpoint (fuseki)

inspiration : https://www.youtube.com/watch?v=k1eR_3KqJms

premier test : sparql-statements (recupérer les infos RDF sur un serveur sparl / fuseki en utilisant iron-ajax)

serveur fuseki  : http://rdf-smag0.rhcloud.com/

prérequis :
installation de nodejs, yeoman

Polymer propose polymer:seed, un element modèle servant d'exemple pour la création d'elements Polymer.

Au boulot on va créer un element "sparql-update"
sous l'invite de commande dos tapez :

yo polymer:seed sparql-update

complétez avec vos infos -6> un module modèle est créé dans votre repertoire.
Pour le lancer utilisez la commande :  polyserve

Le nouvel element généré est accessible à l'adresse :
http://localhost:8080/components/sparql-update

quelques soucis parfois d'affichage, (un certain temps pour mettre à jour ? allez voir dans le fichier README.RD généré pour avoir différents liens et testez notamment celui-ci : http://localhost:8080/components/sparql-update/test/ ) , une page de tests devrait finir par s'afficher.

Ce qui nous intéresse, Thérèse , ensuite c'est le module lui-même, on utilisera deux pages :

  • la page du module :  http://localhost:8080/components/sparql-update/
  • la page de demo accessible par le bouton "DEMO" en haut à droite
Laisser le terminal ou vous avez lancez polyserve ouvert et ouvrez un autre terminal pour installer l'element "iron-ajax" avec la commande  : 
bower install --save PolymerElements/iron-ajax

et incorperez cet element dans sparql-update.html avec : <link rel="import" href="../iron-ajax/iron-ajax.html"> juste après <link rel="import" href="../polymer/polymer.html">

supprimer les elements inutiles dans le modeles : 
  • dans le fichier  sparql-update.html 
.author dans template/style
et ne garder que "properties" dans la definition js de l'element : 
il ne devrait vous rester plus que ceci : 


<link rel="import" href="../polymer/polymer.html">

<link rel="import" href="../iron-ajax/iron-ajax.html">

<!--
An element providing a solution to update sparql endpoint like Fuseki.
(https://github.com/scenaristeur/sparql-update)

Example:

    <sparql-update></sparql-update>

Example:

    <sparql-update>
      <h2>Hello sparql-update</h2>
    </sparql-update>

@demo demo/index.html
@hero hero.svg
-->

<dom-module id="sparql-update">
  <template>
    <style>
      :host {
        display: block;
        box-sizing: border-box;
      }
    </style>


  </template>

  <script>
    Polymer({
      is: 'sparql-update',

      properties: {
       
      }
    });
  </script>
</dom-module>


Nous avons maintenant un élement propre et on va pouvoir y mettre notre propre (ou sale ?) code

On incorpore maintenant notre element "iron-ajax" qui va se charger d'effectuer la requete POST vers notre serveur Fuseki :

<iron-ajax/iron-ajaxauto
url=""
handle-as="json"
on-response="{{handleResponse}}"></iron-ajax>



le mieux c'est de jeter un oeil au code




26/02/2016

Dreamcatcher V3 integration dans Meteor

in English, at the bottom of this post ;-)

La version hébergée sur Météor n'est plus, préférez la version "Autonome Collaboratif "







Nous en sommes maintenant à la V3 de Dreamcatcher : les plus curieux peuvent déjà y jeter un oeil : http://smag0.meteor.com/

  1.  v1 : http://smag-smag0.rhcloud.com/DreamCatcher/
    1. explications : http://smag0.blogspot.fr/2015/08/dreamcatcher-lattrape-reves.html
    2. Fonctionnalités :
      1. test de la bibliothèque de la bibliothèque traer pour processingjs pour gérer un environnement physique de répulsion, attraction des noeuds, deplacement à la souris, zoom avec les flèches (voir notice/help)
      2. test de drag&drop
      3. test d'integration, export de fichier rdf , n3
      4. sauvegarde de graphe avec touche "s" chargement des données depuis un serveur Fuseki, un sparql endpoint, via une requete sparl ou un service web hebergé ailleurs avec Java/Jena
      5. Creation de sessions pour travailler à plusieurs sur un graphe
    3. utilisationhttp://smag-smag0.rhcloud.com/DreamCatcher/help.html
  2. v2 : http://smag-smag0.rhcloud.com/DreamCatcher1/
    1. explications : http://smag0.blogspot.fr/2015/12/dreamcatcher-ou-comment-partager-des.html
    2. Fonctionnalités : une evolution de la V1, avec prise en charge de la 3D, grâce à P5JS, test égalment avec three.js 
    3. utilisation
      1. cliquer sur "charger Demo" puis sur afficher texte
      2. les curseurs permettent de zoomer, déplacer la caméra
  3. v3 ; http://smag0.meteor.com/
    1. explications : http://smag0.blogspot.fr/2016/02/dreamcatcher-v3-integration-dans-meteor.html
    2. besoin; besoin d'une identification, authentification pour partager, donner des droits sur les graphes, les sessions
    3. dépôt github : https://github.com/scenaristeur/dreamcatcher-smag0
    4. utilisation
      1. en arrivant sur la page d'accueil, on peut s'authentifier, ou créer son compte, 
      2. ensuite on peut créer un post ou participer aux post existants
        1. creer un post : rien de plus simple (attention aux lien, s'il existe déjà, ça empeche de créer le post)
        2. ajouter un triplet ou statement à un post existant, en insérant un sujet, une propriete, et un objet, et en validant. ce triplet/statement devrait s'insérer dans le graphe en haut de page . si aucun graphe n'apparait : revenez sur la page d'accueil, puis actualisez, ( tous les fichiers ne semblent pas encore chargés si on atterit directement sur un post)



version anglaise : 

Dreamcatcher V3 integration in Meteor
We are now in V3 Dreamcatcher: the curious can already have a look: http://smag0.meteor.com/

 v1: http://smag-smag0.rhcloud.com/DreamCatcher/
explanations http://smag0.blogspot.fr/2015/08/dreamcatcher-lattrape-reves.html
features:
test library for the library traer processing.js to manage a physical environment repulsion, attraction knots, displacement mouse, zoom with the mouse (see manual / help)
drag & drop test
integration testing, rdf file export, n3
Backup graph with "s" key data loading from a Fuseki server, endpoint sparql, via a request sparl or a hosted web service elsewhere with Java / Jena
Creation of sessions to work together on a graph
Use: http://smag-smag0.rhcloud.com/DreamCatcher/help.html
v2: http://smag-smag0.rhcloud.com/DreamCatcher1/
explanations http://smag0.blogspot.fr/2015/12/dreamcatcher-ou-comment-partager-des.html
Features: an evolution of the V1, with support of 3D, thanks to P5JS, égalment test Three.js
use :
click "Load Demo" and then display text
sliders allow you to zoom, move the camera
v3; http://smag0.meteor.com/
explanations http://smag0.blogspot.fr/2016/02/dreamcatcher-v3-integration-dans-meteor.html
need; require identification, authentication to share, give rights on graphs, sessions
use :
arriving on the home page, you can authenticate or create an account,
then you can create a post or participate in existing post
create a post: nothing simpler (watch link, if it exists, it prevents creating the post)
add a triplet or statement to an existing post, inserting a subject, a property and an object, and validating. this triplet / statement should be part of the graph to the top. if no graph will appear: return to the home page and then refresh, (all files do not yet appear directly responsible if it lands on a post)

13/07/2015

Visualiser le graphe d'une ontologie online (Processing, Javascript, XML)

Vous avez un fichier (ontologie ou base de connaissance) au format owl ou rdf, vous pouvez visualiser les classes le graphe (enfin pour l'instant, il n'y a que les classes : http://smag-smag0.rhcloud.com/saisie_projet (update : une version plus récente : http://smag0.blogspot.fr/2015/08/dreamcatcher-lattrape-reves.html )

Si vous n'en avez pas, vous pouvez tester avec la méthode Diamond, http://smag-smag0.rhcloud.com/ontologies/diamondMethode.owl que l'on a créé précedemment (http://smag0.blogspot.fr/2015/06/comment-creer-une-methode-pour-smag0-la.html)

Ou mieux, encore avec la pizza.owl ( http://protege.stanford.edu/ontologies/pizza/pizza.owl ), bien connue de tous ceux qui se sont intéressés un jour aux ontologies ;-).

--> possibilité de charger un fichier depuis votre disque dur
--> possibilité de glisser de nouveaux éléments pour créer un nouveau Projet (projet, acteur, environnement...)
--> possibilité de déplacer les noeuds,
--> possibilité de selectionner les noeuds (se positionner sur un noeud + touche CTRL)
--> possibilité de sauvegarde/chargement  des graphes ( les données sont stockées sur votre ordinateur, dans le localstore (en test) :



Tout ça avec P5Js, version web de Processing, en mode Javascript... 

17/06/2015

Ajouter une méthode simple à un projet Smag0

Nous avons tenté d'expliquer dans l'article http://smag0.blogspot.fr/2015/06/comment-creer-une-methode-pour-smag0-la.html comment créer une méthode, en nous attaquant à la méthode Diamond. Mais cette méthode est complexe, et longue à mettre en place, on verra ça plus tard.

N'allons pas trop vite en besogne, procédons par ordre. Pour l'instant nous avons la possibilité d'enregistrer les projets ou les instructions que l'on veut envoyer à notre maison, via l'appli Coolitude4, ou via la page des projets, nous avons la possibilité d'ajouter des commentaires sur les projets proposés, et d'extraire de ces projets les termes importants, de les enregistrer au format RDF. Si RDF ne vous dit rien, jetez un petit coup d'oeil sur https://fr.wikipedia.org/wiki/Resource_Description_Framework pour que ce soit plus clair.
(NB : les liens mentionnés sont susceptibles de changer, merci de me le signaler, si vous n'y trouvez plus rien).

Une fois que l'on a notre projet, ou notre requête envers notre maison (voir ASACURQRSC ), 
le système doit posséder des méthodes pour analyser, interpréter, exécuter les instructions.
Partons donc d'un truc tout simple, par exemple... il est 20h36, c'est l'heure de manger, je voudrais manger des pâtes, c'est mon projet, ça devient une requête envers le système qui serait peut-être un jour capable de me faire cuire des pâtes sans me répondre " va te faire cuire un œuf".
Pour que le système puisse y parvenir, il va avoir besoin d'une méthode, comme nous quand on va sur http://www.marmiton.org ... mais en attendant qu'il aille y chercher des recettes complexes, tentons d'établir une méthode simple pour transmettre au système la méthode pour cuire des pâtes.

Primo : c'est quoi la méthode pour faire cuire des pâtes ??
source  : Farfalle - Barilla
 (je dois être le seul mec de tout l'internet à prendre mon code source sur les paquets de pâtes Barilla ;-%)

Modalité de cuisson pour 100g de pâtes :
1 litre d'eau
7g de sel

Faire bouillir l'eau et ajouter le sel.
Verser les pâtes et remuer de temps en temps.
Temps de cuisson 10 min.
Egoutter les pâtes.

En décomposant par étape, en gros, ça ferait :
1. Faire bouillir l'eau
2. Ajouter le sel
3. Verser les pâtes
4. Remuer de temps en temps (pendant 10 minutes )
5 Egoutter les pâtes

Le but étant de créer une méthode exploitable, enregistrable, partageable, modifiable, n'ayant pas trouvé mieux que RDF pour décrire, on va tenter de se le faire avec des triplets, comme ça  :
(voir aussi http://www.w3.org/2001/sw/BestPractices/OEP/SimplePartWhole/)

ici, on va utiliser la propriété rdf:type pour dire que CuireDesPâtes est_une Methode, ou que FairteBouillirEau est_une Etape...

{CuireDesPâtes  rdf:type  Methode}
{FaireBouillirEau rdf:type Etape}
{AjouterSel rdf:type Etape}
{VerserPâtes rdf:type Etape}
{Remuer rdf:type Etape}
/* avoir comment faire le de temps en temps, et le attendre 10 mins... faire les deux actions en parrallèle ??? temporiser ??*/
{EgoutterPâtes rdf:type Etape }

Voilà nos 5 étapes.

Ensuite, pour dire que la méthode CuireDesPâtes est composée de plusieurs étapes nommées FaireBouillirEau, AjouterSel..., on utilisera dc:hasPart, ce qui donnera

{CuireDesPâtes dc:hasPart FaireBouillirEau }
{CuireDesPâtes dc:hasPart AjouterSel
{CuireDesPâtes dc:hasPart VerserPâtes
{CuireDesPâtes dc:hasPart Remuer
{CuireDesPâtes dc:hasPart Attendre10Min } //encore à définir
{CuireDesPâtes dc:hasPart EgoutterPâtes }


on pourra compléter de la manière suivante en utilisant rdf:first pour dire que FaireBouillirEau est la première étape de la méthode CuireDesPâtes.

{CuireDesPâtes rdf:first FaireBouillirEau }

A ce stade, on serait tenter d'utiliser les Collections RDF : https://code.google.com/p/collections-ontology/wiki/RDFContainersAndCollections
mais ceci ne conviendrait pas, on créerait une Sequence avec rdf:Seq, mais on serait obligé de numéroter les étapes, alors que nous voulons quelque chose de souple. Ainsi, si j'ai envie de me créer ma propre méthode CuireDesPâtes2, et que moi, quand je fais des pâtes, j'ai l'habitude de mettre un couvercle, pour que la température de l'eau augmente plus vite ( ce qui n'est pas recommandé par Barilla, cela dit en passant... que ce soit clair entre vous et moi !). Bon admettons que l'on veuille rajouter une étape comme MettreCouvercle... Si on numérote les étapes avec les  propriétés préconisées rdf:_1, rdf:_2..., on sera embêté lors de l'insertion, il faudra renommer toute la suite, de même si on veut supprimer une étape. On va plutôt utiliser une propriété qui nous dira le "suivant" de FaireBouillirEau est AjouterSel.  Cette propriété "suivant" ou "next" (en anglais) ne semble pas avoir été prévu dans les vocabulaires rdf ou rdfs... Comment faire ...??? là se pose la question de tout développeur normalement constitué, qui s'est un peu penché sur RDF, et la notion de réutilisation des vocabulaires. Dois-je créer ma propre propriété avec mon propre prefix, un truc du style "smag:next"???

Que nenni, car c'est là qu'intervient notre ami Lovokfnorg ou plutôt http://lov.okfn.org/... Qui c'est celui-là ? un moteur de recherche de vocabulaires RDF... et en lui demandant s'il connait quelque chose qui correspondrait à notre "next" tant désiré, il nous répond :

on a 71 réponses (peut-être plus quand vous lirez cet article), et déjà, les trois premières nous conviennent... Quelle utilité d'en créer une 72ème qui ne sera utilisée par personne d'autre que par moi. Prenons la plus populaire : xhv:next

On peut donc écrire (non, je ne met pas le couvercle, vous le mettrez si vous voulez... en plus , y'a des risques de débordement...) les triplets suivants :

{ FaireBouillirEau xhv:next AjouterSel }
{AjouterSel xhv:next VerserPâtes }
{VerserPâtes xhv:next RemuerDeTempsEnTemps }
{VerserPâtes xhv:next Attendre10Min }
{Attendre10Min xhv:next EgoutterPâtes }



On a maintenant une structure cohérente sans trop mettre les pieds dans le plat... de pâtes. Bon ok, c'est nul... Avec VerserPâtes qui possède deux xhv:next : RemuerDetempsEnTemps et Attendre10Min.

On a maintenant tout ce qu'il faut pour compléter notre méthode CuireDesPâtes. on peut par exemple décomposer les étapes... avec les propriétés dc:hasPart, rdf:first et xhv:next
L'étape FaireBouillirEau pourrait être composée d'autres étapes, comme SortirCasserole, RemplirEau, PoserSurGaziniere, AllumerLeFeu... et oui, Johnny...
SortirCasserole se décomposerait en AllerDevantPlacardBasGauche, OuvrirPortePlacardBasGauche, AttrapperCasserole, Reculer, FermerPlacardBasGauche, SeDeplacerVersEvier...


On peut ainsi stocker n'importe quelle méthode sur notre serveur RDF (avec Fuseki), ou sous forme de fichier rdf/owl téléchargeable.
ps : j'ai zappé pas mal de principes RDF, préfixe, etc... pour que ce soit plus clair à un non initié, mais l'intéressé pourra se rendre là : https://fr.wikipedia.org/wiki/Resource_Description_Framework ou là http://www.w3.org/TR/rdf-syntax-grammar/
 ou là en français : https://www.google.fr/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=rdf%20francais 

Reste à créer une interface conviviale pour enregistrer, éditer, visualiser les méthodes...















06/05/2014

serveur Fuseki sur le pcduino

ça fait un bout que je suis pas passé.. M'enfin !!!
La livraison du pcDuino a pas mal tardé, ensuite les vacances...

Mais j'ai tout bien reçu (voir les articles précedents).
Quelques tests faits : installer vnc, librairie pyduino, brancher une caméra, une Led, (mon-club-elec.fr) , test des servos moteurs, et moteurs de déplacement (linksprite.com)...

Mais l'étape d'aujourd'hui concerne la mise en place d'un serveur fuseki afin de gérer la base de connaissance du robot

Fuseki :
sur le pcduino, decompresser le repertoire fuseki

Lancer fuseki au démarrage (modif du fichier autostart):
sudo geany /etc/xdg/lxsession/Lubuntu/autostart

ajouter une des deux  lignes suivante en fonction du mode de démarrage préféré :
- pour fuseki en mode non persistant pour faire des tests (en mémoire):
@/home/ubuntu/fuseki/fuseki-server --update --mem /ds

- pour fuseki en mode persistant pour que les données restent :
/home/ubuntu/fuseki/fuseki-server --update --loc=/home/ubuntu/fuseki/DEFAUT /ds
!!! pensez à créer le repertoire DEFAUT dans le repertoire fuseki et bien mettre un espace devant /ds qui défini le nom du dataset

(voir la doc de fuseki pour les différents modes de démarrage)


Le serveur Fuseki est accessible à l'adresse http://localhost:3030
on peut y uploader les fichiers de tests proposés sur le tutoriel Jena Sparql

aide pour construire les requetes Jena / Sparql : http://www.slideshare.net/rajighawi/java-and-sparql (diapo 5/26)

on peut même y accéder en mode distant, avec Processing et Jena
(modifier l'adresse : remplacez 10.42.0.1 par l'adresse de votre pcduino):


import java.io.Reader;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.query.ResultSet;
import javax.xml.transform.Result;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.query.ResultSetFormatter;
import com.hp.hpl.jena.ontology.OntModelSpec;


void setup() {
  /*
  http://host/dataset/query -- the SPARQL query endpoint.
   http://host/dataset/update -- the SPARQL Update language endpoint.
   http://host/dataset/data -- the SPARQL Graph Store Protocol endpoint.
   http://host/dataset/upload -- the file upload endpoint.
   */
  String endpoint = "http://10.42.0.1:3030/ds/query";
  String requete = "SELECT * WHERE {?S ?P ?O}";
  //String requeteJS = "SELECT ?x WHERE { ?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> 'John Smith' }";
  // select-query
  QueryExecution qe = QueryExecutionFactory.sparqlService(endpoint, requete);
  //qe.setInitialBinding( );
  println (qe);
  ResultSet result = qe.execSelect();

  ////////////////////////:::::::::::::
 // Pour afficher les resultats deux solutions ResultSetFormatter.out(System.out, result); ou While / has next
   ResultSetFormatter.out(System.out, result);
  /*while (result.hasNext ()) {
    QuerySolution querySolution = result.next();
    println(querySolution);
  }*/
  //////////////////////////:::::::

  int numb = result.getRowNumber();
  println (numb);

  
}

void draw() {
}



ce sketch processing permet de visualiser les infos présentes sur le serveur Fuseki du pcduino. Pour une requête plus précise et notamment obtenir un graphe/model à la place d'un ResultSet, on devra utiliser Construst plutôt que Select qui retourne un tableau itérateur des solutions. http://jena.apache.org/tutorials/sparql_results.html

voir aussi les tutoriels Jena en français : http://jena.apache.org/tutorials/index.html

pour reinitialiser le serveur fuseki (effacer toutes les données) :
s-update --service http://localhost:3030/ds/update 'CLEARDEFAULT'






25/03/2014

Pourquoi du RDF ? pour jouer de la musique ?

- RDF ( resource description Framework) ? c'est un langage permettant de décrire des ressources d'un domaine... (voir wikipedia). Partageable, distribuable, interprétable par les machines....
- Ok ! c'est donc pour ça que tu veux absolument l'utiliser ?
- Oui, distribuable : donc les ressources sont décrites une fois et partagées entre les modules / robots , à condition de gérer la confidentialité des infos ... Et je me suis dit que je pouvais décrire avec la méthode Diamond qui est une méthode pour construire des systèmes multi-agents... J'en ai d'ailleurs fait une première version sur une autre page du blog, c'est diamond.owl. Et je suis en train d'essayer de la visualiser avec Processing.
Par extension, et si j'y arrive, je devrais pouvoir appliquer ce principe :
 [- visualiser / modifier les fichiers RDF/ontologies sous forme de graphes (Processing ? javascript + D3 ou jointjs)
- transmettre des infos à des machines (ordi/robot/module/agent) dans un format interpretable par elles.]
 à n'importe quelle méthode, comme une recette de cuisine, ou la procédure pour faire du café, pour ouvrir un placard ou y ranger les satanés légos qui trainenet.
- N'importe quelle méthode ou procédure ? Pourquoi pas une chanson, alors ? c'est comme une méthode ! Regarde : si on prend par exemple cette page http://www.francetabs.com/tablatures-partitions/brigitte/battez-vous-tab-guitare12488.html où on trouve les tablatures de Brigitte (désolé, je ne suis pas un crack en solfège, mais la suite doit être applicable aussi !)

ACCORDS
Accord guitare D (xx0232) Accord guitare E (022100) Accord guitare Em (022000) Accord guitare Em7 (022030) Accord guitare A (x02220)
TABLATURE
d|———————————|——————————|————————————||
a|———————————|——————————|————2—0—————||
e|—12———11———|—10———9———|—0—3————3—0—|| clap-clap
   .tremolo-------------    ¬¬        


d|—–2————4———|——5————7———|—2—————————2——||
a|—–2————6———|—–5———–4———|—2———2—0———2——||
e|—––———––———|————––––––—|—0—3————–3—0—|| clap-clap
   .tremolo-------------     ¬¬


       Em       EmM7          Em7       Em6
Faites-vous la guerre pour me faire la cour
 Em
Maintenant battez-vous
  Em       EmM7    Em7    Em6
Soyez gangsters, soyez voyous
 Em
Maintenant battez-vous
      

(...) 
--Fin de l'extrait.

ça nous dit : à la basse : sur la corde de MI faire les notes 12, puis 11, puis 10, puis 9, puis 0, 3, corde de LA : 2, puis 0, re-corde de MI 3 puis 0, puis Clap-Clap.


Et tu dis que tu peux transmettre ça à une machine ?
- Bien sûr, le format rdf est fait pour ça ! Attend, je te montre ! D'abord , tu lance Protégé, et dedans, tu y décris tout ce dont tu as besoin pour ta méthode, ou tout autre chose ( On pourrais par exemple y décrire la procédure pour une opération chirurgicale ( ;-) Oh Coco... Private Joke !) .
Ensuite tu décris des Classes qui regroupent des éléments de même type, avec des sous classes éventuellement, puis des Entités (ou des Individuals) avec des propriétés.
Pour notre exemple, on pourra par exemple creer une classe Note, une classe Accord, une classe Corde, une classe Position, c'est à toi de décrire ton domaine comme tu le souhaite.
Deux personnes différentes pourront décrire le même domaine de deux manières différentes... ce n'est pas un problème, on pourra toujours rapprocher ensuite deux ontologies...
Dans diamond.owl, j'ai utilisé des Classes Etape et des propriétés first (pour indiquer la première Etape) puis des proprietes next pour lier les différents Individuals ou entités...
Un accord peut être décrit comme un ensemble de 3 notes...
On peut dans le même fichier décrire à la fois tous les instruments, et n'afficher (on ne jouer que les bonnes informations en fonction des requêtes).
Exemple qui ne fonctionnera pas en l'état mais possible :  SELECT Accord WHERE {?Accord ?Instrument ?Guitare} ORDERBY ?Ordre

Essaie Protégé,  si tu veux un exemple : tu peux récupérer diamond-first.owl, et si tu veux des infos sur comment utiliser Protégé pour décrire un domaine, tu peux aller voir tout en bas de cet article : http://smag0.blogspot.fr/2014/03/creer-une-interface-pour-visualiser-les.html et récupérer le tutoriel Pizza-Gloria

+++ On peut même certainement s'amuser avec les machines à états finis dans une Ontologie... à voir : http://www.w3.org/TR/2014/CR-scxml-20140313/




21/03/2014

Interface : Visualisation d'une ontologie owl créée avec Protégé, convertie au format Json pour l'integrer à D3.js ou exhibit

Pour créer une visualisation d'ontologie dans une interface Web.


Démarrer le serveur Fuseki avec les options suivantes :
fuseki-server --update --mem /diamond
ensuite sur le serveur fuseki (http://127.0.0.1:3333), utiliser le cadre File upload au bas de la page sparql.tpl.
Puis sur la même page, dans le cadre SPARQL Query,  lancer la requête (en selectionnant OUTput : JSON) :
SELECT  *  WHERE {?Sujet ?Propriete ?Objet}

Télécharger le fichier nouvellement créé et le renommer avec l'extension .json

Ce fichier peut maintenant être directement utilisable par les moteurs de visualisation javascript tels que D3 ou Exhibit.

par exemple pour l'integrer dans une page html utilisant d3.js, utilisez le code suivant :

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script type="text/javascript" src="d3/d3.js"></script>
</head>
<body>
<script type="text/javascript">
// DATA

d3.json("data/diamond.json", function(diamond) {
console.log(diamond);
});

//  test paragraphe
d3.select("body")
.append("p")
.text("Smag0!");
</script>
</body>
</html>

ensuite vous pouvez vérifier l'insertion des données dans la page en utilisant la console de développement fournie par GoogleChrome , ou Firefox  :


GRRRRRR ! Après  2 jours à me prendre la tête, je me rend compte que le Json de Fuseki n'est pas le même que le Json de D3.js... et que je ne suis pas le premier à me prendre la tête dessus...
Sommes nous bloqués ? Non, on va le tenter en csv d'après la procédure décrite sur ce blog : http://www.d3noob.org/2013/03/d3js-force-directed-graph-example-basic.html

cet article semble également interessant http://graus.nu/thesis/algorithm-performance-measurement-confusion-matrix/ parlant de matrice de confusion dans le domaine du Machine Learning (aprentissage des machines)

Sinon une autre option pourrait-être d'utiliser : http://jointjs.com/demos (mais y'a un truc à voir avec la license Free / pas free ?)

Le but étant d'obtenir quelque chose comme ça : http://bl.ocks.org/d3noob/5141278

et pour le fun, j'aime bien celui-là : http://bl.ocks.org/mbostock/1249681

reprendre aussi l'idée de cluster : http://bl.ocks.org/mbostock/7881887

et le rendre en plus zoomable : http://bl.ocks.org/mbostock/7607535 et oui, rien que ça...
Une autre idée du cluster : https://github.com/Leaflet/Leaflet.markercluster



22/12/2013

Test d'intégration de Apache Jena -Sparql dans Processing.org pour visualiser les rdf

Voir le tutoriel plus récent : http://smag0.blogspot.fr/2014/03/creer-une-interface-pour-visualiser-les.html


import com.hp.hpl.jena.query.* ;

int nodeCount;
Node[] nodes = new Node[10];
HashMap nodeTable = new HashMap();

int edgeCount;
Edge[] edges = new Edge[5];

static final color nodeColor   = #F0C070;
static final color selectColor = #FF3030;
static final color fixedColor  = #FF8080;
static final color edgeColor   = #000000;

PFont font;

void setup() {
  size(600, 600);
  // loadData();
  // println(edgeCount);
  font = createFont("SansSerif", 10);


  // File file = new File();
  Rdf rdftest = new Rdf();
}

void addEdge(String fromLabel, String toLabel) {
  // Filter out unnecessary words
  if (ignoreWord(fromLabel) || ignoreWord(toLabel)) return;

  Node from = findNode(fromLabel);
  Node to = findNode(toLabel);
  from.increment();
  to.increment();

  for (int i = 0; i < edgeCount; i++) {
    if (edges[i].from == from && edges[i].to == to) {
      edges[i].increment();
      return;
    }
  }

  Edge e = new Edge(from, to);
  e.increment();
  if (edgeCount == edges.length) {
    edges = (Edge[]) expand(edges);
  }
  edges[edgeCount++] = e;
}


String[] ignore = {
  "a", "of", "the", "i", "it", "you", "and", "to"
};

boolean ignoreWord(String what) {
  for (int i = 0; i < ignore.length; i++) {
    if (what.equals(ignore[i])) {
      return true;
    }
  }
  return false;
}


Node findNode(String label) {
  label = label.toLowerCase();
  Node n = (Node) nodeTable.get(label);
  if (n == null) {
    return addNode(label);
  }
  return n;
}


Node addNode(String label) {
  Node n = new Node(label);
  if (nodeCount == nodes.length) {
    nodes = (Node[]) expand(nodes);
  }
  nodeTable.put(label, n);
  nodes[nodeCount++] = n;
  return n;
}

void draw() {
  if (record) {
    beginRecord(PDF, "output.pdf");
  }

  background(255);
  textFont(font);
  smooth();

  for (int i = 0 ; i < edgeCount ; i++) {
    edges[i].relax();
  }
  for (int i = 0; i < nodeCount; i++) {
    nodes[i].relax();
  }
  for (int i = 0; i < nodeCount; i++) {
    nodes[i].update();
  }
  for (int i = 0 ; i < edgeCount ; i++) {
    edges[i].draw();
  }
  for (int i = 0 ; i < nodeCount ; i++) {
    nodes[i].draw();
  }

  if (record) {
    endRecord();
    record = false;
  }
}
boolean record;

void keyPressed() {
  if (key == 'r') {
    record = true;
  }
}


Node selection;


void mousePressed() {
  // Ignore anything greater than this distance
  float closest = 20;
  for (int i = 0; i < nodeCount; i++) {
    Node n = nodes[i];
    float d = dist(mouseX, mouseY, n.x, n.y);
    if (d < closest) {
      selection = n;
      closest = d;
    }
  }
  if (selection != null) {
    if (mouseButton == LEFT) {
      selection.fixed = true;
    } else if (mouseButton == RIGHT) {
      selection.fixed = false;
    }
  }
}


void mouseDragged() {
  if (selection != null) {
    selection.x = mouseX;
    selection.y = mouseY;
  }
}


void mouseReleased() {
  selection = null;
}

// EDGE
// Code from Visualizing Data, First Edition, Copyright 2008 Ben Fry.
// Based on the GraphLayout example by Sun Microsystems.


class Edge {
  Node from;
  Node to;
  float len;
  int count;



  Edge(Node from, Node to) {
    this.from = from;
    this.to = to;
    this.len = 50;
  }


  void increment() {
    count++;
  }


  void relax() {
    float vx = to.x - from.x;
    float vy = to.y - from.y;
    float d = mag(vx, vy);
    if (d > 0) {
      float f = (len - d) / (d * 3);
      float dx = f * vx;
      float dy = f * vy;
      to.dx += dx;
      to.dy += dy;
      from.dx -= dx;
      from.dy -= dy;
    }
  }


  void draw() {
    stroke(edgeColor);
    strokeWeight(0.35);
    line(from.x, from.y, to.x, to.y);
  }
}


//NODE

// Code from Visualizing Data, First Edition, Copyright 2008 Ben Fry.
// Based on the GraphLayout example by Sun Microsystems.


class Node {
  float x, y;
  float dx, dy;
  boolean fixed;
  String label;
  int count;
  int taille;


  Node(String label) {
    this.label = label;
    x = width/2;
    y = height/2;
  }


  void increment() {
    count++;
  }


  void relax() {
    float ddx = 0;
    float ddy = 0;

    for (int j = 0; j < nodeCount; j++) {
      Node n = nodes[j];
      if (n != this) {
        float vx = x - n.x;
        float vy = y - n.y;
        float lensq = vx * vx + vy * vy;
        if (lensq == 0) {
          ddx += random(1);
          ddy += random(1);
        }
        else if (lensq < 100*100) {
          ddx += vx / lensq;
          ddy += vy / lensq;
        }
      }
    }
    float dlen = mag(ddx, ddy) / 2;
    if (dlen > 0.00000000000001) {
      dx += ddx / dlen;
      dy += ddy / dlen;
    }
  }


  void update() {
    if (!fixed) {    
      x += constrain(dx, -10, 10);
      y += constrain(dy, -10, 10);

      x = constrain(x, 0, width);
      y = constrain(y, 0, height);
    }
    dx /= 2;
    dy /= 2;
  }


  void draw() {
    fill(nodeColor);
    stroke(0);
    strokeWeight(0.5);
    taille =count;
    taille = constrain(taille, 20, 200);
    ellipse(x, y, taille, taille);
    float w = textWidth(label);

  // if (taille > w+2) {
      fill(0);
      textAlign(CENTER, CENTER);
      text(label, x, y);
   //}
  }
}

// RDF

import com.hp.hpl.jena.query.* ;
import com.hp.hpl.jena.rdf.model.Resource;

class Rdf {
Model model;
  Rdf() {

    test();
    lister();
    afficheConsole();
  }
  void test() {
    // some definitions
    String personURI    = "http://somewhere/JohnSmith";
    String givenName    = "John";
    String familyName   = "Smith";
    String fullName     = givenName + " " + familyName;
    String personURIMe    = "http://fada-range.appspot.com/DavidFaveris";
    String givenNameMe    = "David";
    String familyNameMe   = "Faveris";
    String fullNameMe     = givenNameMe + " " + familyNameMe;
    // create an empty Model
    model = ModelFactory.createDefaultModel();

    // create the resource
    Resource johnSmith =  model.createResource(personURI);
    Resource davidFaveris =  model.createResource(personURIMe);

    // add the property
    johnSmith.addProperty(VCARD.FN, fullName)
      .addProperty(VCARD.N, model.createResource()
        .addProperty(VCARD.Given, givenName)
        .addProperty(VCARD.Family, familyName));
    ;
    davidFaveris.addProperty(VCARD.FN, fullNameMe)
      .addProperty(VCARD.N, model.createResource()
        .addProperty(VCARD.Given, givenNameMe)
        .addProperty(VCARD.Family, familyNameMe));

    println(johnSmith);
    println(davidFaveris);
    addNode("johnSmith");
    addNode("davidFaveris");

  }


void afficheConsole(){
  model.write(System.out);
}

  void lister() {
    // list the statements in the Model
    StmtIterator iter = model.listStatements();

    // print out the predicate, subject and object of each statement
    while (iter.hasNext ()) {
      Statement stmt      = iter.nextStatement();  // get next statement
      Resource  subject   = stmt.getSubject();     // get the subject
      Property  predicate = stmt.getPredicate();   // get the predicate
      RDFNode   object    = stmt.getObject();      // get the object
addEdge(subject.toString(), object.toString());
        System.out.print("Sujet : "+subject.toString());
      System.out.print(" "+"\tPredicat : " + predicate.toString() + " ");
      if (object instanceof Resource) {
        System.out.print("\tObjet : "+object.toString());
      } 
      else {
        // object is a literal
        System.out.print(" \"" + object.toString() + "\"");
      }

      System.out.println(" .");
    }
    
  }
}

//File

class File {
  File() {
    String lines[] = loadStrings("vcard.rdf");
    println("there are " + lines.length + " lines");
for (int i = 0 ; i < lines.length; i++) {

      lines[i] = lines[i].replaceAll("  ", "");

      //PREFIXES
      lines[i] = lines[i].replaceAll("http://www.semanticweb.org/fada/ontologies/2013/10/smag/monde#", "");
      lines[i] = lines[i].replaceAll("http://www.semanticweb.org/fada/ontologies/2013/10/smag/monde#", "");
      lines[i] = lines[i].replaceAll("http://www.w3.org/2002/07/owl#", "");
      println(lines[i]);
    }
    for (int i = 0; i < lines.length; i++) {
      // Make this phrase lowercase
      //  String line = lines[i].toLowerCase();
      String line = lines[i];
      // Split each phrase into individual words at one or more spaces
      String[] words = splitTokens(line, "|");
 /*     for (int w = 0; w < words.length-1; w=+3) {
        words[w]=words[w].replaceAll(" ", "");
        words[w+2]=words[w+2].replaceAll(" ", "");
        if ((words[w+2]=="<Class>") || (words[w]=="<Class>")) {
          print ("classe");
        }
        else {
          addEdge(words[w], words[w+2]);
          print (words[w+1]+" entre "+words[w]+ " et " + words[w+2]+"\n");
        }
      }
   */ }
  }
}