Annotate - an app of SPPAS

Brigitte Bigi

User manual

Not written yet. This chapter is the help of the person who annotates: what the page shows, how an annotation is chosen and set, what is done to the files, and what is read of what came of it.

Developer manual

Not written yet. This chapter is for whoever reads or changes the code: how it is organised, what the page is made of, the events it answers, and the stylesheets.

Modelling

Problem and scope

Description

SPPAS annotates: it takes files of a person and writes, beside them, what it found in them — the words, the sounds, the syllables, what was said at the same time as something else. What it can find is not one thing but a score of them, each written by somebody, each with its own language, its own settings and its own needs.

This application is what stands between a person and those annotations. It shows what can be run, lets one be chosen and set, runs the chosen ones on the files she chose, says what came of each, and keeps what it said so that it can be read again. It annotates nothing itself.

Three neighbours answer for what it does not: the files are the provision of files', the settings of an annotation are the service of the options', and what an annotation does is the domain of the annotations'. What is left is the annotations as a set — which are offered, which were chosen, what they were run with, and what came of the run.

The annotations are not independent of one another. The phonetization needs the text normalization, the alignment needs the phonetization, the time group analysis needs the syllabification. Every annotation declares what it requires, so the order exists and is written down; what does not exist is anywhere a person can see it. A score of annotations offered as a flat list is a list one gets lost in, and it is the same list whether one knows it holds three chains or twenty unrelated things.

Defining the needs

The needs are those of the person who annotates. None of them says by what it is answered.

  • B1 — To choose, among the annotations which are offered, the ones to run.
  • B2 — To find one's way among the annotations which are offered.
  • B3 — To know what an annotation does before choosing it, and on which published work it rests.
  • B4 — To choose the language of the annotations, and another one for an annotation which does not speak the same.
  • B5 — To give an annotation the values it expects, before it is run.
  • B6 — To choose the extension of every kind of file which is produced.
  • B7 — To run every annotation which was chosen at one go, on the files which were chosen.
  • B8 — To follow what happens while it happens.
  • B9 — To read what happened, annotation by annotation and file by file.
  • B10 — To read the report of a run: at the end of that run, and afterwards.
  • B11 — To delete the reports which are of no use any more.
  • B12 — To obtain one file holding everything which was annotated, to open it in Praat.
  • B13 — To see what an annotation needs, and to be shown the annotations arranged so that it shows.

B2 is where the difficulty is. Every annotation has a type, and a type says how many files it takes and whose: one file on its own, two files of one speaker, or two files of two speakers. That is a real thing to know and it is not a way of finding an annotation: one of the three types holds a score of annotations, so knowing the type shortens nothing. A type says what an annotation takes, and B2 asks where it stands among the others.

There is no annotation without a type. A declaration which names none does not leave the question open: it says the first of the three, one file on its own. That is not a detail of the reading — it decides what an annotation takes, and therefore where it is offered. A declaration which forgets the field says that the annotation takes one file and is offered everywhere, and it says it as firmly as one which writes it. C16

B13 is the one which was not expressed, and the one which is worth the work. It is inferred from B2: what orders a list of a score of lines is already declared, and showing it turns that list into a handful of chains. Where an annotation stands in its chain says what it is for better than its description does. It is the one need of this list which nothing answers anywhere.

B13 asks for two things and they are not the same: seeing what one annotation needs, which is reading one declaration; and being shown the annotations arranged by what they need, which is reading all of them. The first can be answered without the second. Whether both are answered is not decided here, and it is written down so that the decision is taken and not avoided.

What an annotation requires is only what comes before it. An annotation declares what it needs and never what will be made of it: what follows an annotation is read on the others, and is not something that annotation says of itself.

Three needs are answered elsewhere and are named here because the person has them: the files which are annotated are the provision of files' (B7), the values an annotation expects are the service of the options' (B5), and what is made of a produced file afterwards belongs to whoever reads it.

Scope

This document covers a set of annotations: how they are shown, how they are chosen, what they are run with, how they are run, and what is read of what came of it.

What is not covered: what an annotation does and how, which is the domain of the annotations'; which files are annotated, which is the provision of files'; and the values an annotation expects, which the service of the options shows and sets.

sppasParam, annotationParam, sppasAnnotationsManager and sppasAnnReport are read and not modelled. Their functioning is established, and this document names them as it names a neighbour.

Conceptual level

Data dictionary

Four data, and they all belong to one run.

  • D1. A run — the annotations which were chosen, what they were chosen with, the files they were run on, and the moment it started.
  • D2. A choice — one annotation which is to be run, and the language it is to be run in.
  • D3. Where a run stands — which annotation is being run at this moment, and how far it has gone. It is known while the run goes and not afterwards, and nothing of it is kept: what stays of a run is what it wrote.
  • D4. A report — what a run wrote of itself, kept so that it can be read again. It is written line by line while the run goes, every line saying what was done and how it went, and it ends with what every annotation did.

The annotations themselves are not among them. What each declares — its name, what it does, what it requires, its type, its languages, its options, the work it rests on — is written in the domain of the annotations and read from there.

Conceptual model of communication

Four actors border this application: a person, and three neighbouring domains it calls. It writes into none of the three.

Actors

  • A1. The person — reads what is offered, chooses annotations, chooses a language and an extension, sets an annotation, starts a run, follows it, and reads what came of it.
  • A2. The domain of the annotations — holds what every annotation declares of itself, runs an annotation on files, and writes what it did.
  • A3. The provision of files — gives the files a run works on, and makes what was produced reachable among the files of the person.
  • A4. The service of the options — shows the options an annotation declares and gives back what was set on them.

Flows

  • F1. A2 → app — the annotations which are offered, and what each declares of itself [B1, B3].
  • F2. app → A1 — what is offered: for every annotation, its name, what it does, the work it rests on or how far it is from being finished, the languages it speaks, and whether it can be chosen at all [B1, B3].
  • F3. A1 → app — an annotation chosen, or a choice taken back [B1].
  • F4. A1 → app — the language of the run, or the language of one annotation [B4].
  • F5. A1 → app — the extension of one kind of file to be written [B6].
  • F6. app → A4 — the options one annotation declares, to be set [B5].
  • F7. A4 → app — those options, with the values which were set [B5].
  • F8. A3 → app — a workspace holding the files to be annotated, and them only [B7].
  • F9. A1 → app — start the run [B7].
  • F10. app → A2 — what the run is made of: the annotations which were chosen, the workspace, the languages, the values, the extensions, and whether one file is wanted [B7].
  • F11. A2 → app — where it is while it works: which annotation it is running, and how far that one has gone.
  • F12. app → A1 — which annotation is running, and how many remain [B8].
  • F13. app → A1 — what the run wrote of itself: the report, which says annotation by annotation and file by file how it went [B9].
  • F14. app → A3 — the files which were written, to be made known [B7].
  • F15. app → A1 — the reports of the runs which came before [B10].
  • F16. A1 → app — the reports to delete [B11].

F10 carries the whole run and not one annotation. The domain of the annotations runs what was chosen, in the order it declares them, and that order respects what they require already: this application chooses no order and imposes none. What it reads of the declarations, it reads to show — which is B13, and B13 alone.

F10 carries a workspace, and not what an annotation reads. What an annotation reads is found from two things, and neither of them is this application's: what is checked in that workspace and what stands beside it; and the patterns and the extensions that annotation declares. Where an annotation takes two files which belong together, what says they belong together is the workspace as well.

This application chooses no file, pairs no file and looks for none. It gives what was chosen, and what is read of it is settled between the workspace and the declaration.

Nothing goes from this application to A2 but a request to run. What an annotation declares is read and never written: a language chosen for one annotation is held here, for the time of the run, and the declaration is what it was.

Conceptual model of data

Five classes. The annotation is one of them without being modelled: it belongs to the domain of the annotations, and appears here with its identifier and no property.

The classes of entities

ClassPropertiesWhat it is
ANNOTATION# annotationOne annotation which is offered. What it declares is read where it is written
RUN# run, moment, language, one file or severalOne set of annotations started at one moment on one set of files (D1)
EXTENSION# run, # kind, extensionThe extension the files of one kind will be written with
CHOICE# run, # annotation, languageOne annotation which is to be run in that run, and the language it is to be run in (D2)
STANDING# run, annotation, how farWhere a run stands at the moment it is asked (D3). It is read and never written
REPORT# report, moment, runWhat a run wrote of itself, kept so that it can be read again (D4)

The relations

No.VerbLeg 1Leg 2
R1is to be run inCHOICE (1,1)RUN (1,n)
R2choosesCHOICE (1,1)ANNOTATION (0,n)
R3is where it standsSTANDING (1,1)RUN (0,1)
R4was written byREPORT (1,1)RUN (0,1)
R5is written withEXTENSION (1,1)RUN (1,n)

R1 is an aggregation: a choice exists only inside the run it was made for. R1 and R2 together identify a choice, and that is what says an annotation is chosen once in a run and not twice.

R3 reads (0,1) on the side of the run: a run which is going is somewhere, and a run which is over is nowhere. Where it stands is not a property of the run: it is what the domain of the annotations says of itself while it works, and it is gone when it stops saying it.

The language is on the choice and not on the annotation. One language is chosen for the run and every choice takes it; a choice may hold another, and holds it for that run alone. An annotation which does not speak the language of the run is not silently run in another: it is the person who says which one, on that annotation.

Computed, and never held

  • Which annotations are offered, which is what the domain of the annotations declares.
  • What an annotation requires: read from the declarations, and never written here [B13]. It is not what orders a run — the domain of the annotations runs what was chosen in the order it declares them, and that order respects what they require already. What is read from the declarations is what is shown, and how the list is arranged.
  • That a run is over, which is that nothing is advancing it any more.
  • The languages an annotation speaks, which are not a list it declares: it declares where its resources stand and how they are named, and the languages are what is found there. They are read on the machine where SPPAS runs, and a machine which holds fewer resources offers fewer languages.

What is not modelled, and why

  • What an annotation declares of itself — its name, what it does, its type, its languages, its options, the work it rests on, how far it is from being finished, and what it requires. All of it is established, read where it is written, and nothing here adds to it.
  • The work an annotation rests on, which is a set of publications, each with a name of its own and where it is to be read. An annotation declares them or declares none, and this application shows what it declares and holds nothing of it.
  • How far an annotation is from being finished, which is a number an annotation declares of itself. It is shown where an annotation names no publication, because an annotation which is still being made has nothing published to point at yet.
  • The files a run works on and the files it wrote, which are the provision of files'. This application holds their identity for the time of the run.
  • The values an annotation expects, which the service of the options shows and sets. What is held here is that they were set, and for which annotation.
  • What a report says, which is written by the domain of the annotations. This application knows where a report stands and when it was written, and does not read it.

Conceptual model of treatments

Ten treatments. Eight answer a person who asked; two answer the one before them.

The events

No.EventKindComes from
E1The person asks to see what is offeredexternalThe person (A1)
E2The person chooses an annotation, or takes a choice backexternalF3
E3The person chooses a languageexternalF4
E4The person chooses the extension of one kind of fileexternalF5
E5The person asks to set an annotationexternalThe person (A1)
E6The person starts the runexternalF9
E7The person asks where the run standsexternalThe person (A1)
E8Nothing is advancing the run any moreinternalT06
E9The person asks to read a reportexternalThe person (A1)
E10The person asks to delete reportsexternalF16

T01 — Show what is offered

WhatSays
SynchronisationE1
ActionsRead what the domain of the annotations declares; read, of every annotation, what it requires
ResultWhat is offered, every annotation with its name, what it does, the publications it rests on or how far it is from being finished, and the languages it speaks (F2). Always

What is shown of an annotation is what that annotation declares, and nothing this application wrote. What it requires is read here and shown or not, and that is the whole of B13.

What is offered is not always all of it. An annotation which takes two files which belong together is offered where something says that two files belong together, and not elsewhere. What is read of an annotation to know it is its type, and it is read here with the rest — including where the declaration names none, which says one file on its own. C16

T02 — Choose an annotation

WhatSays
SynchronisationE2
ActionsHold that the annotation is to be run, with the language of the run; or hold that it is not
ResultWhat is chosen (F2). Always

An annotation which requires another is chosen all the same: nothing is chosen in its place and nothing is refused. What is done with what it requires is decided at the run, and not here.

The reason is the way people work. One annotation is run, what it wrote is corrected by hand in the editor, and the next one is run on the corrected version. Choosing what an annotation requires in its place would make that impossible: the chain would run to the end on what was not corrected, which is the opposite of what is wanted.

T03 — Choose a language

WhatSays
SynchronisationE3
ActionsHold the language, for the run or for one annotation
ResultThe language of the run, and of every annotation which speaks it (F2). When the language is that of the run
ResultThe language of that annotation (F2). When it is that of one annotation

An annotation which does not speak the language of the run loses the one it had. It is not run in another, it is not unchosen, and it is not refused: it is left with no language, and the person is the one who gives it another on that annotation. An annotation which needs no language resource is not concerned at all.

T04 — Choose an extension

WhatSays
SynchronisationE4
ActionsHold the extension of one kind of file which will be written
ResultThe extension of that kind (F2). Always

An annotation does not write one kind of file. What is written is annotations, measures or tables, and it may be a sound, an image or a video as well. There is one extension per kind of file which may be written, and choosing one says nothing of the others.

T05 — Set an annotation

WhatSays
SynchronisationE5
ActionsHand the options that annotation declares to the service of the options (F6); take back what was set (F7)
ResultThe options of that annotation hold the values which were set. Always

Nothing is judged here: what a value may be is that service's to answer, and what it means is the annotation's.

T06 — Run the annotations which were chosen

Purpose: that every annotation which was chosen is run on the files which were chosen, and that the person is not made to wait for it.

WhatSays
SynchronisationE6, and at least one annotation chosen and files which are not none
ActionsWrite the run and its moment; name the report it is to write; hand the whole of it to the domain of the annotations, which runs every annotation which was chosen (F10)
ResultThe run has started, and the person is answered before it ends. Always
ResultE8, nothing is advancing the run any more. When what advances it has stopped, whether it went to the end or not

A run is a series and not an operation. The annotations are run one after another, and one which fails does not undo the run: it goes on to the next, and what was written before the failure was written. What every one of them did is written in the report as it goes.

The order is the domain's. The annotations are run in the order that domain declares them, and that order respects what they require: one which needs another to have run before it stands after it there. When what it requires was not chosen, it is run all the same, and what it finds is what is already beside the files.

Nothing here waits for the run. What starts it answers as soon as it is started: a run is longer than a request, and the person who started it is given a page and not a wait.

T07 — Say where the run stands

WhatSays
SynchronisationE7
ActionsRead where the domain of the annotations says it is (F11)
ResultWhich annotation is being run and how far it has gone (F12). While a run is going
ResultThat no run is going (F12). Otherwise

Where a run stands is not counted here: it is said by the one which does the work, into what it was given for that, and read from there as it is. This application adds no number of its own and keeps none.

T08 — Close the run

WhatSays
SynchronisationE8
ActionsGive the files which were written and the report to the provision of files
ResultThe files which were written, and the report with them (F14). Always: a run which wrote no file wrote a report
ResultThe report, shown (F13). Always

It runs at the end and not at every annotation: what a run writes is not finished until it has finished. Gathering what was written into one file when one was asked for is not done here either — it is asked for before the run and done by the domain of the annotations, at the end of its own work, for the same reason.

The report goes where the files go. It is handed to the provision of files with them, it is reached the same way they are, and it lasts as long as they do. It is shown at the end of the run as well, because that is when it is read.

T09 — Read a report

WhatSays
SynchronisationE9
ActionsGive what that report holds
ResultThe report (F15). When it is there
ResultThat it is not there (F15). Otherwise

A report of a run which came before is read as the report of the run which has just happened: they are the same thing, and one of them is only older.

A report is read and not interpreted, and its lines carry their own state. Every line says how what it is about went — done, refused, worth a warning, worth saying, or passed over — and it is the line which says it, not this application. What is shown of a report is what it holds, and what that state is used for is to show it as what it is.

T10 — Delete reports

WhatSays
SynchronisationE10
ActionsDelete the reports which were named
ResultThe reports which are left (F15). Always

What a report was written about is not deleted with it. The files an annotation wrote are the person's, and they were hers the moment they appeared.

A report is one run, and one run is one report: the reports are told apart by the moment they were written, and a report which is deleted is deleted alone.

Organisational level

Organisational model of treatments

One procedure per treatment, numbered as it is. One table and not two: nothing here is done in one context of execution and not in the other, and an annotation is run the same way whether the machine is the one of the person or a server she reaches.

PFWhat it doesTriggered byIn chargeWhereWhenNature
PF1 (T01)Shows what is offeredE1the appthe serverwhen the person asksconversational
PF2 (T02)Chooses an annotationE2the personthe browser, then the servereach time she chooses or takes backconversational
PF3 (T03)Chooses a languageE3the personthe browser, then the servereach time she chooses oneconversational
PF4 (T04)Chooses an extensionE4the personthe browser, then the servereach time she chooses oneconversational
PF5 (T05)Sets an annotationE5the service of the optionsthe serverbefore a run, as often as she wantsconversational
PF6 (T06)Runs the annotations which were chosenE6the domain of the annotationsthe serverwhen she starts the runautomated
PF7 (T07)Says what came of one annotationE7the appthe serveras soon as an annotation has been runautomated
PF8 (T08)Closes the runE8the app, then the provision of filesthe serverwhen the last annotation has been runautomated
PF9 (T09)Reads a reportE9the appthe serverwhen she asksconversational
PF10 (T10)Deletes reportsE10the appthe serverwhen she asksconversational

Everything is decided on the server. What the browser holds is the gesture — the annotation ticked, the language picked, the extension picked — and the choices already made, which it carries from one request to the next. It decides nothing, because what an annotation is, which languages it speaks and what it requires are declared where the annotations are and read nowhere else. RO2

The table holds for both contexts of execution, and no procedure is missing from either. Where SPPAS runs on the machine of the person, the server of this table is that machine and one person is alone on it. Where SPPAS answers from a server, several persons are on it at once: each has her own run, her own choices and her own reports, and what the machine can carry at one time is not the same thing as what one person may start. RO3, RO9

PF8, PF9 and PF10 do not differ between the two contexts. A run writes one report, it is handed over with the files and shown at the end, and it is read again or deleted as any of them is. What changes from one machine to another is how long the provision of files holds what it was given, and that is that domain's question and not this one's. RO7, RO10

The first is what PF1 offers. An annotation takes one file on its own, or two files of one speaker, or two files of two speakers. The last two take files which belong together, and what says that two files belong together is a workspace. Where SPPAS answers from a server there is none of hers, so only the annotations of the first kind are offered there: the others are not refused at the run, they are not offered at all. RO8

An annotation offers the languages whose resources are on that machine. A declaration says where its resources stand and how they are named; which languages there are is found by looking there. The same annotation therefore offers three languages on one machine and eight on another, and it offers none where nothing was installed for it. What a server offers is what whoever runs it installed, and this application reads it the same way in both contexts: it asks, it does not look itself. C17

Showing what an annotation requires costs nothing more. What is declared is read when the list is shown, and it is read then anyway: the name, what it does and the languages come from the same declaration. Answering B13 adds a reading of one field, and no request. What it may add is the arranging of the list, which is a matter of what is shown and not of when it is read.

How a run which lasts is followed

A run is a score of annotations on a set of files, and it lasts as long as that takes. The request which starts it cannot hold the answer for minutes, and nothing of what happens reaches a page which is not asking.

A run is therefore started by one request and followed by others which ask where it stands. It is what the setting up of SPPAS does with the installation of its features and what the app of the plugins does with a run of one: a thread advances it, something holds where it stands, and later requests read that. There is no reason for a third way.

What those later requests obtain is what F12 carries: the annotation which is being run, and how far it has gone. A run which is over answers that it is over, and what it wrote is then F13: the report, which is read as long as the person wants to read it.

Rules of organisation

  • RO1 — A run outlives the request which started it. It is advanced by a thread of the process where SPPAS runs, and it is the one thing this application holds between two requests.
  • RO2 — What was chosen — the annotations, the languages, the extension — is carried from one request to the next by the page, and nothing of it is held on the server between two requests.
  • RO3 — One run at a time for one person. A second run started while one is going is refused, and the refusal says which one is still going.
  • RO4 — The order in which the chosen annotations are run is the domain of the annotations', and it respects what each of them declares it requires. It is not asked of the person, and this application neither chooses it nor changes it. What this application works out from those declarations is the order the annotations are shown in.
  • RO5 — The options of an annotation are set before a run and read once, when that run starts. An annotation set during a run is set for the next one.
  • RO6 — This application reads nothing into what an annotation said. It shows that text and takes the number of files from the annotation itself.
  • RO7 — The report of a run is given to the provision of files with the files that run wrote: it is reached as they are and lasts as long as they do. It is shown at the end of the run in both contexts of execution.
  • RO10 — One run writes one report, in both contexts of execution and in the same way. Where a report stands, how it is reached and how long it lasts are the provision of files' to answer, and this application asks it the same question wherever it runs.
  • RO8 — Every procedure is the same in both contexts of execution, and none is missing from either. What differs is what is offered: where SPPAS answers from a server, only the annotations which take one file on their own are offered.
  • RO9 — Where SPPAS runs on the machine of the person, one run at a time is one run on that machine. Where it answers from a server, several persons run at once, and what bounds the number of runs the machine takes at one time is the business of whoever runs it.

RO3 is not a limit of the machine: two runs on one set of files would write the same files at the same moment, and the person could not tell which run produced what. RO4 is what makes one run enough — the chosen annotations are run in an order which respects what they require, so there is nothing to gain by starting a second.

Constraints

What the code holds to

No.ConstraintImposed by
C1An annotation is chosen at most once in a run.R1 with R2
C2Choosing an annotation chooses no other.T02, and the way people work
C3An annotation is never run in a language it does not speak: choosing that language takes it out of what can be chosen, and the person is told so.T03, B4
C4An annotation is shown after every chosen annotation it requires.RO4, B13
C5An annotation whose requirement was not chosen is chosen, shown and run all the same.C2, T06
C6The failure of one annotation never stops a run.T06, B9
C7What an annotation said is not read: it is written in the report by the domain which ran it, and shown from there as it stands.RO6, B9
C8One run at a time for one person.RO3
C9The values an annotation is run with are those it held when the run started.RO5
C10A run works on the workspace it was given, and on nothing else.B7
C11One file gathering everything is written only where it was asked for.B12
C12A report is one of the files a run gives back: it is reached as they are and lasts as long as they do.RO7
C13Deleting a report deletes nothing of what the run wrote.T10, B11
C14What is shown of an annotation is what that annotation declares, and nothing this application wrote.T01, B3
C15What an annotation requires is read and never written here.B13
C16Every annotation has a type. One which declares none takes one file on its own.The declaration, where the absence of the field is a value
C17The languages offered for an annotation are those whose resources stand on the machine where SPPAS runs.A declaration names where its resources are, not which languages there are

C2 and C5 are the same decision seen twice. Nothing is chosen for the person, so an annotation may be run without what it requires having been run just before: it then works on what is already beside the files, which is what somebody who corrected by hand wants. Written otherwise, a chain would run to its end on what was not corrected.

C4 does not contradict them. It bears on what is shown and on nothing else: it says that the alignment is shown after the phonetization it requires when both were chosen, never that choosing the one chooses the other.

Logical level

The tables

Each class of entities becomes a table, and its identifier becomes its key.

TableColumnsComes from
ANNOTATIONannotationThe class ANNOTATION
RUNrun, moment, language, one file or severalThe class RUN
EXTENSIONrun, kind, extensionThe class EXTENSION, and R5
CHOICErun, annotation, languageThe class CHOICE, and R1 with R2
none—STANDING is no table: where a run stands is read while it goes and held by nobody
REPORTreport, moment, runThe class REPORT, and R4

R1 and R2 both have their low cardinality on the side of the choice, which is (1,1): the table takes both keys, and the two together identify it. That is C1 written as a key rather than as a rule: one run holds one annotation at most once.

R3 gives no table. Where a run stands is asked of the domain of the annotations while it works, and there is nothing to key and nothing to write: a value which is true for a second and read by one request is not a table.

The report is not keyed by its run, and that is not an oversight. A report is read long after the run which wrote it, and a run does not last: keyed by the run, a report would stop being reachable the moment its run was gone. It is keyed by itself, carries the moment it was written, and names its run where that run can still be named — which is why R4 reads (0,1) on the side of the run.

EXTENSION is a table because a run writes more than one kind of file. An annotation writes annotations, and some write a sound or an image as well: there is one extension per kind, which is as many values as there are kinds. Written as a column of the run, they would be one string nobody can read back kind by kind.

ANNOTATION is a key and nothing else. The table exists so that a choice may name what it is about; what an annotation is made of is written in the domain which holds it.

Computed, and never held

  • Everything an annotation declares: its name, what it does, its type, its languages, its options, the work it rests on, and what it requires.
  • How the annotations are arranged when they are shown, which follows from what they require.
  • Where a run stands, which the domain of the annotations says while it works.
  • That a run is over, which is that nothing is advancing it any more.

Physical level

Where each table stands

Here the machines are named, and not before. One table stands in a neighbouring domain, one stands on a disk, and the three others change place when the run starts.

TableBefore the runFrom the run onWhat the person sees
ANNOTATIONThe domain of the annotations, read at every requestThe sameWhat is offered
RUNNowhere: there is no run yetThe process where SPPAS runsWhat is running, and since when
CHOICEWhat the page transmitsThe process, written into the run when it startsWhat she chose
EXTENSIONThe sameThe sameOne extension per kind of file
STANDINGNowhere: there is no run yetWhat the domain of the annotations was given to say where it is, held by the process for as long as the runWhich annotation is being run, and how far
REPORTA file, given to the provision of files with what the run wroteThe same, written while the run goes and closed with itWhat a run wrote of itself, at the end of the run and by what it was given to reach it

The choices change place when the run starts, and that is the whole arrangement. While the person chooses, nothing is held on the server: the page carries what was chosen and gives it back at every request. The moment the run starts, what was chosen is written into the run, and the run is held by the process — because a thread cannot read a page, and because what a run was started with must not change under it. RO1, RO2, C9

The report is the one thing which stays. It is a file, written where SPPAS keeps what it writes about itself, and it is not deleted with the run: a run lasts as long as the process and a report lasts until somebody deletes it. That is what B10 and B11 rest on, and it is why the report is not keyed by its run.

A run gives back what it produced, and the report is one of it. One run, one report: it is handed to the provision of files with the files the run wrote, it is reached as they are, and it lasts as long as they do. Where that is, is that domain's answer and not this one's. C12, RO10

Operational model of treatments

The organisational level said by what and when; this says in what tasks, and what among them cannot be half done. One request is one unit: what was chosen is rebuilt from what the page transmitted, the one thing which was asked is done, and what is to be shown is sent back.

PFThe tasks, in orderWhat cannot be half done
PF1Read what the domain of the annotations declares; read, of each, what it requires; build what is to be shownNothing: nothing is written
PF2, PF3, PF4Rebuild what was chosen; hold the choice, the language or the extensionNothing
PF5Rebuild; hand the options over; take back the valuesNothing
PF6Rebuild; verify one annotation was chosen and the files are not none; name the report; make the run; hand the whole of it to the domain of the annotations, which runs what was chosenThe making of the run, which finds a run of that person or makes one. Not the run itself
PF7Read where the domain of the annotations says it is, and say itNothing: nothing is written
PF8Give the files which were written and the report to the provision of filesNothing of this application's
PF9, PF10Read a report; delete the reports which were namedThe deletion of one report

A run is never half done, because nothing of it is undone

What a run writes, it writes as it goes, beside the files. There is no moment at which a run is half made and has to be undone: an annotation which failed leaves the files as they were before it, and the ones which ran before it wrote what they wrote.

A run which stops is not repaired. A process which is killed, an annotation which never returns: nothing more is written and nothing more is said. What tells a run which stopped from a run which is slow is the thread which advances it, and nothing else is needed. What it wrote before it stopped is in the report, and the report says where it stopped.

The order is not this application's

The chosen annotations are run in the order the domain of the annotations declares them, and that order respects what each of them requires: this application does not put them in order and does not ask to. An annotation which requires one which was not chosen is run all the same: what it requires is not there to wait for.

What is read from the declarations is read for the person: to show what an annotation requires, and to arrange the list so that what depends on what can be seen. That is B13, and it changes nothing of a run.

Where the code goes

In sppas/ui/swapp/app_annotate/, cut as every application of swapp is cut: one module for the model, one for the view, one for what dispatches, one for what answers the URL, and one module per part of the page.

ModuleWhat it doesProcedure
annotate_modelHolds what the domain of the annotations offers and what is set on it, reads what an annotation requires, starts a run in a thread and reads where that domain says it is, and knows where the reports are. The only module of this application which speaks to that domain and to the two servicesPF1, PF5, PF6, PF7, PF8, PF9, PF10
annotate_viewBuilds the page and holds its partsThe view of every procedure
annotate_controllerReads the task a request carries, calls what has to be called, and has the view build its treeEvery procedure
annotate_makerAnswers the URL, builds the view and what dispatches, and bakes the treeEvery procedure
annotaction, annotselect, annotlogOne part of the page each: what is set and what starts a run, with the reports beside it; the annotations of one type; where a run stands and the report it gaveThe view of PF1, PF5, PF6, PF7, PF8, PF9, PF10

What each one promises, which is the reason for the cutting:

  • The model is the only one which calls the domain of the annotations and the two services, so it is the only one to be read again the day one of them changes. It relays what it reads and adds one thing: the order the annotations are run in.
  • The view decides nothing, and shows what an annotation declares as it declares it.
  • What dispatches holds nothing between two requests: what has to survive is what the page carries.
  • The parts of the page know the page and nothing else. None of them reads a file, a thread or a declaration.

Implementation model: MVC

The model holds what the annotations offer, what is set on them, the run which is going and the reports which were written; it exposes neither the domain of the annotations nor the two services to the rest of the application. The controller is called once per request, reads the task it carries, and holds nothing afterwards. The view renders and collects, and takes no decision. Three components, three class diagrams.

The page is one page. What the interface which exists today shows one panel at a time, this one holds as sections of a single page, shown and hidden where they stand. Nothing is asked of the server to go from one to another, and which one is under the eye is carried by nobody.

The classes of the model

/ marks what is derived and held by nobody. What the operations promise is the chapter on the contracts.

ClassFromAttributesOperations
AnnotateModelANNOTATION, CHOICE, EXTENSION, REPORTparam, manager, log, progress, thread, runparameters(), requires(id), arranged(chosen, requirements), set_workspace(workspace), start(), is_running(), where_it_stands(), the_run(), give_back(), reports(), read_report(id), delete_reports(ids)
AnnotateRunRUNrun, moment, parameters, report, /overis_over(), serialize(), parse(data)

One class, and the classes of the core under it. What is offered and what each annotation declares, which are activated, the language of each, the extension of every kind of file, the workspace and the name of the report: sppasParam holds all of it, and it is what the domain of the annotations is run with. Running them is sppasAnnotationsManager. Naming a report so that no run overwrites another's is sppasLogFile, and what a report holds is written by sppasAnnReport, line by line, with the state each line carries. A class of this application holding any of that under another name would be a second truth.

Where a run stands is read and not counted. The domain of the annotations is given something to say where it is — a swappProgressBar, which is a sppasBaseProgress — and it sets on it which annotation it is running and how far that one has gone. where_it_stands() reads it. This application counts nothing of its own, and holds nothing of it once the run is over.

What the model adds is how the list is arranged. arranged() is given what was chosen and what each one requires, and gives back the order in which they are shown. It reads nothing, which is what lets it be verified with nothing installed, and it is where B13 is answered. It is not the order of a run: the annotations are run in the order the domain of the annotations declares them.

What is tied to what

TieLegsWhat it is
holdsAnnotateModel 1 — 0..1 AnnotateRunA composition: the run exists inside what advances it, and goes with the process
usesAnnotateModel → swappProgressBarA dependency: it makes one, hands it over, and reads it
usesAnnotateModel → sppasParam, sppasAnnotationsManager, sppasLogFileA dependency, and the only tie of this application to the domain of the annotations
usesAnnotateModel → the provision of files, the service of the optionsA dependency, and the only tie to the two services

In yUML

To be read at yuml.me, class diagram.

[AnnotateModel|param;manager;log;progress;thread;run|parameters();requires();arranged();set_workspace();start();is_running();where_it_stands();the_run();give_back();reports();read_report();delete_reports()]++1-0..1>[AnnotateRun|run;moment;parameters;report;/over|is_over();serialize();parse()]

[AnnotateModel]-.->[swappProgressBar]

[AnnotateModel]-.->[sppasParam]
[AnnotateModel]-.->[sppasAnnotationsManager]
[AnnotateModel]-.->[sppasLogFile]

The classes of the view

The parts of the page are those of the interface which exists today, and they bear its names: what is set and what starts a run, the reports beside it, one list per type of annotation, one row per annotation, and where a run stands with the report it gave.

What is set and what was written stand side by side, and the person says how much of each she wants to see. A group of three choices — the left alone, both, the right alone — governs the two panels, as it does on the page of the journal: two half-width panels are unreadable on a narrow window, and someone who is starting a run has no use for the reports of the ones before. The group is made of radio buttons, so that reaching it with a keyboard and hearing which one holds come from the buttons themselves and not from a script. Both is what a page opens on.

ClassOperationsWhat it shows
AnnotateViewpopulate_tree_content(record)The page, and the sections it holds
ActionAnnotatePanel—On the left: the language, one extension per kind of file which may be written, whether one file is wanted, the way to each list of annotations, and what starts a run
ReportsPanel—On the right: the reports which were written, one to read, and those to delete
AnnotationsPanel—The annotations of one type, one row each. One of these sections per type
EnableAnnotation—One annotation: whether it is chosen, what it says of itself, the work it rests on or how far it is from being finished, the languages it speaks, what it requires, and what sets its options
LogAnnotatePanel—A run as it advances: which annotation is being run and how far it has gone; then the report it wrote, line by line with the state each line carries, and the files which were given back

What is tied to what

TieLegsWhat it is
holdsAnnotateView 1 — 1 ActionAnnotatePanel, 1 ReportsPanel, 1 LogAnnotatePanelA composition: a section exists inside the page it is a part of
holdsAnnotateView 1 — 0..n AnnotationsPanelA composition: one section per type of annotation the domain declares, and no section for a type which offers nothing
holdsAnnotationsPanel 1 — 0..n EnableAnnotationA composition: one row per annotation of that type
usesAnnotateView → AnnotateRecordA dependency: it is given what is to be shown and reads nothing else

In yUML

[AnnotateView|populate_tree_content()]++1-1>[ActionAnnotatePanel]
[AnnotateView]++1-1>[ReportsPanel]
[AnnotateView]++1-0..*>[AnnotationsPanel]
[AnnotateView]++1-1>[LogAnnotatePanel]
[AnnotationsPanel]++1-0..*>[EnableAnnotation]

[AnnotateView]-.->[AnnotateRecord]

The classes of the controller

ClassAttributesOperations
AnnotateControllerrecordhandle(data), populate_view()
AnnotateRecordtask, run, to_be_shownserialize(), parse(data)
AnnotateResponseRecipe—bake(), _process_events()

What a request holds is the task it carries, the run it follows and what is to be shown. Which section is under the eye is not among them: the page shows and hides them where they stand.

What is tied to what

TieLegsWhat it is
holdsAnnotateResponseRecipe 1 — 1 AnnotateView, 1 AnnotateControllerA composition: it builds them, and they go when it goes
holdsAnnotateController 1 — 1 AnnotateRecordA composition: one record per request, kept by nobody
usesAnnotateController → AnnotateModelA dependency: it reads, it starts a run, it asks where one stands, and it asks for the reports
usesAnnotateController → AnnotateViewA dependency: it has the page built from the record

In yUML

[AnnotateResponseRecipe|bake();_process_events()]++1-1>[AnnotateController|record|handle();populate_view()]
[AnnotateResponseRecipe]++1-1>[AnnotateView]
[AnnotateController]++1-1>[AnnotateRecord|task;run;to_be_shown|serialize();parse()]

[AnnotateController]-.->[AnnotateModel]
[AnnotateController]-.->[AnnotateView]

The states

An annotation, in a run being prepared
StateWhenWhat is shown
cannot be chosenIt declares nothing to run, or what it needs is not thereIts line, shown as not choosable, and nothing which chooses it
not chosenNothing was said of itIts line, and what chooses it
chosenIt is to be runIts line, that it is chosen, and the language it will run in
chosen, and what it requires is notIt is to be run, and what it requires is notThe same, and that what it requires is not chosen

Chosen, and what it requires is not is neither a refusal nor a warning about a mistake: it is a statement of fact, because running an annotation on what was corrected by hand is a way of working and not an error. C2, C5

Cannot be chosen is another thing altogether: an annotation which declares nothing to run is declared and cannot run, and choosing it would be choosing nothing. It is shown, because hiding it would make a person look for it — and it is shown as not choosable, which is a thing the line has to carry and not the absence of a button. An absent button reads as a page which forgot something.

A run
StateWhen
goingThe thread which advances it is alive
overThat thread is no longer alive, and the report it wrote says every annotation which was chosen was reached
stoppedThat thread is no longer alive, and the report stops before the last annotation which was chosen

The sequence, from the page to the report

  1. The page is asked for. What is offered is read, with what each annotation requires, and shown.
  2. The person chooses annotations, a language, an extension for a kind of file. Each is one request, and each carries back everything chosen so far.
  3. She sets one of them: its options are handed to the service which shows them, and what was set comes back.
  4. She starts the run. The files she chose are read, the report is named, and the whole of it — the annotations chosen, the languages, the extensions, the workspace — is handed to the domain of the annotations, which starts running them in the order it declares them. She is answered at once.
  5. That domain writes what it does into the report as it goes, and says where it is into what it was given for that.
  6. Her page asks where the run stands, and is answered: this annotation, and how far it has gone.
  7. Steps 5 and 6 happen again, at their own pace, until nothing is advancing the run any more.
  8. The run is over. The files which were written and the report are given to the provision of files.
  9. She reads the report, then or another day.

Steps 1 to 3 happen in any order and any number of times. Step 4 happens once per run and is refused while a run of that person is still going. RO3

The error policy

LevelWhat happensWhat is done
1What was asked cannot be done now: no annotation chosen, no file chosen, a run already goingNothing is started, and what is missing or what stands in the way is said. Nothing is raised
2One annotation is concerned: it failed, or succeeded on fewer files than it was givenNothing of this application's: the domain of the annotations writes it in the report, with the state of the line which says it, and goes on to the next
3A report cannot be read or cannot be deletedIt is said in the words of what was attempted, and the other reports are untouched
4Whoever runs the machine has to know: a run which cannot be made, the domain of the annotations which cannot be readSaid where he reads it, and the person is told that the run could not be started

What is raised is caught by whatever answers a request, and by nothing below it. What an annotation writes about its own difficulties is not an error of this application: it is what that annotation said, and it is shown as such.

The contracts

How to read them

pre is what has to be true on the way in, and what the operation does not check; post is what the caller can count on without looking.

What holds everywhere

  • Only AnnotateModel speaks to the domain of the annotations and to the two services.
  • Nothing is read into what an annotation said. What it said is in the report, with the state the line carries, and it is shown as it stands. RO6, C7
  • Nothing of a run is written on a disk. A run belongs to the process which holds it and goes with it; the report is what stays.
  • What is absent gives back an empty thing — no annotation, no run, no report — and never nothing at all.
  • What is raised is caught by whatever answers a request, and no class below it writes a catch.

Class by class

AnnotateModel
OperationContract
Give the parameterspre: none. post: the parameters of the set of annotations, as the domain of the annotations makes them: every annotation which is offered with what it declares, none activated, and the extensions each kind of file is written with. Nothing is read of an annotation beyond its declaration. C14
Say what an annotation requirespre: an identifier. post: what that annotation declares it requires, as it declares it; empty when it requires nothing. It is read and never written. C15
Arrange what is shownpre: the annotations which were chosen, and for each of them what it requires. post: those annotations and no others, each standing after every chosen annotation it requires. An annotation whose requirement was not chosen keeps its place all the same. It reads nothing and changes no run. C4, C5
Take the filespre: none. post: the workspace the provision of files gives, holding the files to be annotated and them only, is what the run will be made on; nothing of it is altered here. C10
Start a runpre: a workspace which is not empty, and at least one annotation activated. post: the run exists, holding its moment, the parameters it was started with and the name of the report it is to write; a thread advances it, and it is answered without waiting for it. When a run of that person is already going, nothing is started and the refusal says so. C8
Say whether a run is goingpre: none. post: true while the thread which advances the run is alive, false afterwards. It is what tells a run which stopped from a run which is slow
Say where a run standspre: none. post: which annotation the domain of the annotations says it is running and how far that one has gone, as that domain said it; that no run is going when none is. Nothing is counted here
Give the runpre: none. post: the run, with its moment, what it was started with and the report it writes. Answered while it goes, and answered after it is over
Give back what the run wrotepre: the run is over. post: the files which were written and the report are handed to the provision of files, once for the run and not once per annotation; they are known among the files of the person, and reachable as her own. T08
Give the reportspre: none. post: the reports which were written, with the moment each was written; empty when there are none. C12
Read one reportpre: an identifier. post: what that report holds, as it was written, every line with the state that line carries; nothing at all when it is not there. It is not read for a meaning
Delete reportspre: the identifiers of reports. post: those reports are gone and the others are untouched. What the runs wrote beside the files is untouched. C13

What an annotation is, which languages it speaks, whether it can be chosen at all and what it is set with are read on the parameters, which hold them already; and running them is the business of the domain of the annotations. Arranging them is the one operation here which rests on nothing installed: what was chosen comes back, in another order, nothing added and nothing removed — and no run is changed by it.

What a run was started with does not change while it goes: an annotation set again, a language picked again, a file added, change the next run and not this one. C9

AnnotateRun
OperationContract
Say whether a run is overpre: none. post: true when nothing is advancing it any more. A run which stopped is over as well, and what it did is in its report
Serialise, parsepre: none. post: everything a page needs to show a run, and nothing of the machine. A run parsed twice gives the same run

Writing a report is not an operation of this application. A run is given the name of the report it is to write, and sppasLogFile gives a name no report bore before; what the run then writes under it, sppasAnnReport writes, line by line, with the state each line carries. This application asks for the name, hands it to the run, and afterwards lists, reads and deletes. C12 and C13 hold on names, not on lines.

AnnotateController, AnnotateView
OperationContract
Handle a requestpre: called once for that request, and never twice. post: the record is rebuilt from what was transmitted, the task is read, and one treatment ran — or none ran and what stood in the way is said. Nothing of a record is held after the request
Populate the treepre: a record. post: what the record says and nothing more — no annotation it invented, no progress it counted, no text it wrote. C14
EnableAnnotationpost: the annotation it stands for, with what it declares, whether it is chosen, the language it will run in, and what it requires; and, when a requirement of it is not chosen, that it is not. One way in for every publication it names, and how far it is from being finished where it names none
LogAnnotatePanelpost: which annotation is running and how many remain; nothing at all when no run is going

Where each need is held

No.Held by
B1EnableAnnotation, one per annotation, which shows what the parameters hold and says whether it is chosen
B2AnnotationsPanel, one section per type, and AnnotateModel.arranged(), which puts what was chosen in the order it is shown
B3EnableAnnotation, which shows what an annotation declares and writes nothing of its own
B4The parameters, which carry what is set on every annotation, and AnnotateRun, which holds those a run was started with
B5AnnotateModel, which hands the options to the service of the options and takes the values back
B6ActionAnnotatePanel, and the parameters, which carry one extension per kind of file
B7AnnotateModel.start(), which runs every chosen annotation on the workspace the provision of files gave
B8AnnotateModel.where_it_stands(), which reads what the domain of the annotations set, shown by LogAnnotatePanel
B9LogAnnotatePanel, which shows the report the run wrote, line by line and with the state each line carries
B10AnnotateModel.reports() and read_report(), shown by ReportsPanel
B11AnnotateModel.delete_reports()
B12The domain of the annotations, which gathers what was written into one file when it was asked to. This application asks and holds nothing of it
B13AnnotateModel.requires(), shown by EnableAnnotation; and AnnotateModel.arranged(), which is the same knowledge used to arrange

B13 is held in two places and it is one thing. What an annotation requires is read once and used twice: shown on the line of that annotation, and given to what arranges the list. Written as two pieces of knowledge it would be two, and one of them would drift. It is used a third time by nobody: the order a run happens in is the domain's.

What is tested, and where

Without anything installed

The one thing this application does which nothing else does is to arrange the chosen annotations so that what depends on what can be seen. It is given everything it needs and reads nothing, so it is tested with nothing at all.

No.What is checkedWhat it holds
TE1What comes back is what was chosen: not one annotation added, not one removedThe contract of the arranging
TE2An annotation is shown after every chosen annotation it requiresC4
TE3An annotation whose requirement was not chosen is in the list all the sameC5
TE4A chain of three is arranged the same way whatever order it was given in, the reverse includedC4
TE5A requirement which names no annotation of the set changes nothing of the arrangementC4, and what the declarations hold
TE6The same set given twice is arranged the same wayThe contract of the arranging

TE5 is written because the declarations are not all sound. One of them names a requirement which no annotation bears. What is arranged must not depend on that being repaired, and must not hold an annotation back for something which does not exist.

With the annotations, and without a run

No.What is checkedWhat it holds
TE7Every annotation the domain of the annotations declares is given, and no otherB1
TE8What is given of an annotation is what it declares: its name, what it does, its type, the publications it rests on or how far it is from being finishedC14, B3
TE9An annotation which declares nothing to run cannot be chosen, and is given all the sameThe states
TE10An annotation which declares no type takes one file on its ownC16
TE11The languages of an annotation are those whose resources stand on the machine; one which declares no resource speaks noneC17
TE12Choosing a language which an annotation does not speak takes that annotation out of what can be chosen, and choosing it afterwards does not choose itC3
TE13What an annotation requires is read from its declaration, and one which declares none requires nothingC15, B13

TE13 fails until the field is read. It is written that way on purpose: what an annotation requires is declared and never loaded, and this test is what says whether the extension of the annex was made.

With a run which really happens

These need annotations to run, and the ones they run are written for the tests: one which writes a file, one which fails, one which takes its time. What is tested is this application, never an annotation of SPPAS — and never the domain which runs them, which has its own tests. What is checked here is what was handed over, that nothing waited for it, and what was done with what came back.

No.What is checkedWhat it holds
TE14What is handed over holds every annotation which was chosen, and holds no otherC1, C10
TE15Starting a run answers before the run is over, and the run goes on after the answerRO1
TE16An annotation which fails stops nothing: the run reaches its end and the report holds bothC6
TE17A second run started while one is going is refused, and the refusal says which one is goingC8
TE18An annotation set again while the run goes does not change what that run is running withC9
TE19While a run goes, where it stands is what the domain of the annotations said, and no run going is answered as suchB8, the states
TE20When the run is over, the files which were written and the report are given to the provision of files, once and not at every annotationT08

TE16 is C6 made checkable, and C7 with it. What an annotation said of its difficulty is written in the report by the domain which ran it. This application does not read it, does not count it, and does not decide from it that a run failed: a run which reached its end reached its end.

What no test covers, and where they stand

  • What an annotation does. It belongs to the domain of the annotations and is tested there; this application is answerable for what it started, in which order, and with what.
  • The two services, which have their own dossiers and their own tests. What is checked here is the tie: which files were asked for, and what was given back.
  • Where a report stands and how long it lasts, which the provision of files answers.
  • The WCAG rules, which are verified on the page and not on a fragment of it.

The tests stand where the project puts its own, in tests/swapp/. Six of the twenty need nothing at all, and they are the six which check the one thing this application does alone.

Annexes

Annex: Extension of the declaration of an annotation

One extension is required by this document, and it is required by B13 alone.

E1 — What an annotation requires, read

What it is. The identifier of the annotation which has to have run before, carried by the declaration of an annotation and read with the rest of it.

Why it is needed. The field is already written in the declarations — the phonetization says it requires the text normalization, the alignment says it requires the phonetization, the time group analysis says it requires the syllabification — and what reads a declaration does not read it. It reads the identifier, the name, the description, the type, the interface to run, the references, the degree of development, the options and the resources, and it passes over that one field. B13 asks for a value which is written and never loaded.

What it costs. One field read where the others are read. Nothing of what exists changes, and an annotation which declares nothing there requires nothing, which is what most of them say already.

What it is not. It says what has to have run before, and never what will be made of an annotation afterwards: what follows one is read on the others.

What is written there is not all sound. One declaration names a requirement which no annotation bears, and one writes a requirement with a mark in front of it which no other has. Both are read the day the field is read, and neither is settled here.

Annex: Legal notices

  • Author: Brigitte Bigi
  • Document License: GNU Free Documentation License (GFDL) 1.3
  • Copyright (C) 2026 Brigitte Bigi, CNRS
  • Creation Date: 2026-09-19
  • Last update: 2026-09-19