Newer
Older
web-dumps / doiwos-dumps / README.md
# DOI WOS-DUMPS

Procédure de collecte de notices WoS (Web of Science) à partir d'une liste de
DOI.  

## Étapes

L'étape 0 déclenche les suivantes. Si une étape échoue, on peut relancer la
procédure, pour qu'elle redémarre à la même étape, en redémarrant simplement
l'instance de `doiwos-dumps`.

0. déposer manuellement un fichier nommé `00-dois.txt` à la racine de l'instance
1. collecte des _Full Records_ via l'API WOS
2. extraction des champs jugés intéressants
3. enrichissement RNSR (via règles certaines)
4. enrichissement établissements (concaténation des sigles et libellés des
   établissements associés quand un RNSR est trouvé)
5. enrichissment avec les instituts du CNRS (à partir des RNSR, on retrouve les
   instituts du CNRS)
6. enrichissement Teeft (extraction de termes en anglais dans le titre et
   l'_abstract_)
7. enrichissement Pascal (ajout de catégories Pascal déduites du titre et de
   l'_abstract_)
8. extraction du libellé Pascal
9. détection de structures CNRS dans les adresses d'affiliations (excessivement
   simple, sur la base de la présence de `CNRS`, ou `UMR` )

Les fichiers résultant de chaque étape sont mis dans le répertoire `data`.  

> 💡 Pour accéder aux fichiers du répertoire `data`, connectez-vous via WebDav.

## Exemple

Soit une liste comprenant un DOI: `10.1002/2013GL058511`.

### `00-dois.txt`

Ce fichier contient une liste de DOI à aller chercher dans le WoS.  
Un seul DOI par ligne.  

```txt
10.1111/j.1466-8238.2010.00540.x
```

### `01-corpus.json`

Ce fichier contiendra un tableau JSON avec une seule notice au format _Full
Record_ du _Web of Science_.

### `02-corpus-simple.json`

- `uri`: UID du document
- `doi`: DOI(s) du document
- `title`: titre du document (pris dans `static_data.summary.titles.title` avec
  l'attribut `type` qui vaut `item`)
- `abstract`: résumé du document (pris dans
  `static_data.fullrecord_metadata.abstracts.abstract.abstract_text.p`)
- `publication_year`: année de publication (pris dans
  `static_data.summary.pub_info.pubyear`)
- `source`: nom de la source (pris dans `static_data.summary.titles.title` de
  type `source`)
- `affiliations`: adresses des affiliations des auteurs (prises dans `addresse`
  et dans `reprint_addresses`, dédoublonnées)
- `countries`: pays des affiliations (pris dans `address_spec.country`,
  dédoublonnés)
- `keywords`: _keyword plus_ du WoS
- `subjects`: _subject categories_ du WoS
- `subheadings`: _subheadings_ du WoS
- `headings`: _headings_ du WoS

```json
[
{
  "uri": "WOS:000280633800001",
  "doi": [
    "10.1111/j.1466-8238.2010.00540.x"
  ],
  "title": "Anthropogenic transformation of the biomes, 1700 to 2000",
  "abstract": "Aim ; To map and characterize anthropogenic transformation of the terrestrial biosphere before and during the Industrial Revolution, from 1700 to 2000. ; Location ; Global. ; Methods ; Anthropogenic biomes (anthromes) were mapped for 1700, 1800, 1900 and 2000 using a rule-based anthrome classification model applied to gridded global data for human population density and land use. Anthropogenic transformation of terrestrial biomes was then characterized by map comparisons at century intervals. ; Results ; In 1700, nearly half of the terrestrial biosphere was wild, without human settlements or substantial land use. Most of the remainder was in a seminatural state (45%) having only minor use for agriculture and settlements. By 2000, the opposite was true, with the majority of the biosphere in agricultural and settled anthromes, less than 20% seminatural and only a quarter left wild. Anthropogenic transformation of the biosphere during the Industrial Revolution resulted about equally from land-use expansion into wildlands and intensification of land use within seminatural anthromes. Transformation pathways differed strongly between biomes and regions, with some remaining mostly wild but with the majority almost completely transformed into rangelands, croplands and villages. In the process of transforming almost 39% of earth's total ice-free surface into agricultural land and settlements, an additional 37% of global land without such use has become embedded within agricultural and settled anthromes. ; Main conclusions ; Between 1700 and 2000, the terrestrial biosphere made the critical transition from mostly wild to mostly anthropogenic, passing the 50% mark early in the 20th century. At present, and ever more in the future, the form and process of terrestrial ecosystems in most biomes will be predominantly anthropogenic, the product of land use and other direct human interactions with ecosystems. Ecological research and conservation efforts in all but a few biomes would benefit from a primary focus on the novel remnant, recovering and managed ecosystems embedded within used lands.",
  "publication_year": 2010,
  "source": "GLOBAL ECOLOGY AND BIOGEOGRAPHY",
  "affiliations": [
    "Univ Maryland Baltimore Cty, Dept Geog & Environm Syst, Baltimore, MD 21250 USA",
    "Netherlands Environm Assessment Agcy, Bilthoven, Netherlands",
    "Univ Bonn, Inst Crop Sci & Resource Conservat, D-5300 Bonn, Germany",
    "McGill Univ, McGill Sch Environm, Montreal, PQ, Canada",
    "McGill Univ, Dept Geog, Montreal, PQ, Canada",
    "McGill Univ, Earth Syst Sci Program, Montreal, PQ, Canada",
    "Univ Maryland Baltimore Cty, Dept Geog & Environm Syst, 1000 Hilltop Circle, Baltimore, MD 21250 USA"
  ],
  "countries": [
    "USA",
    "Netherlands",
    "Germany",
    "Canada"
  ],
  "keywords": [
    "LAND-USE",
    "COVER",
    "CLASSIFICATION",
    "TRANSITIONS",
    "LANDSCAPES",
    "ECOSYSTEMS",
    "MANAGEMENT",
    "SCIENCE",
    "LAST"
  ],
  "subjects": [
    "Ecology",
    "Geography, Physical",
    "Environmental Sciences & Ecology",
    "Physical Geography"
  ],
  "subheadings": [
    "Life Sciences & Biomedicine",
    "Physical Sciences"
  ],
  "headings": [
    "Science & Technology"
  ]
}
]
```

### `03-corpus-simple-rnsr.json`

Ici, je vais prendre un DOI qui ramène un RNSR, sinon cela n'a pas d'intérêt.
DOI: `10.1111/geb.12093`

```json
[
{
  "uri": "WOS:000329139600007",
  "doi": [
    "10.1111/geb.12093"
  ],
  "title": "Impact of sea level rise on the 10 insular biodiversity hotspots",
  "abstract": "AimDespite considerable attention to climate change, no global assessment of the consequences of sea level rise is available for insular ecosystems. Yet, ... on islands at risk as a result of near future sea level rise.",                                                               "publication_year": 2014,
  "source": "GLOBAL ECOLOGY AND BIOGEOGRAPHY",
  "affiliations": [
    "Univ Paris 11, UMR CNRS 8079, F-91405 Orsay, France"
  ],
  "countries": [
    "France"
  ],
  "keywords": [
    "SPECIES-AREA RELATIONSHIPS",
    "CLIMATE-CHANGE",
    "FUTURE",
    "ISLAND",
    "ENDEMISM"
  ],
  "subjects": [
    "Ecology",
    "Geography, Physical",
    "Environmental Sciences & Ecology",
    "Physical Geography"
  ],
  "subheadings": [
    "Life Sciences & Biomedicine",
    "Physical Sciences"
  ], 
  "headings": [
    "Science & Technology"
  ],
  "ws": {
    "rnsr": [
      [
        {
          "num_nat_struct": "200212739T",
          "intitule": "Écologie, systématique et évolution",
          "sigle": "ESE",
          "ville_postale": "Orsay Cedex",
          "code_postal": "91405",
          "etabAssoc": [
            {
              "etab": {
                "sigle": "CNRS",
                "libelle": "Centre national de la recherche scientifique",
                "sigleAppauvri": "cnrs",
                "libelleAppauvri": "centre national de la recherche scientifique"
              },
              "label": "UMR",
              "labelAppauvri": "umr",
              "numero": "8079"
            },
            {
              "etab": {
                "sigle": "AGROPARISTECH",
                "libelle": "AgroParisTech (Inst Sc et Ind du Vivant et Environnement)",
                "sigleAppauvri": "agroparistech",
                "libelleAppauvri": "agroparistech (inst sc et ind du vivant et environnement)"
              },
              "label": "UMR",
              "labelAppauvri": "umr",
              "numero": "8079"
            },
            {
              "etab": {
                "sigle": "U PARIS-SACLAY",
                "libelle": "Université Paris-Saclay",
                "sigleAppauvri": "u paris saclay",
                "libelleAppauvri": "universite paris saclay"
              },
              "label": "",
              "labelAppauvri": "",
              "numero": ""
            }
          ],
          "intituleAppauvri": "ecologie, systematique et evolution",
          "sigleAppauvri": "ese",
          "ville_postale_appauvrie": "orsay cedex",
          "annee_creation": "2002",
          "an_fermeture": ""
        }
      ]
    ]
  }
}
]
```

Ici, un seul RNSR: `200212739T`, et plusieurs tutelles (CNRS, AgroParisTech, et
l'Université de Paris-Saclay).

### `04-corpus-simple-etab.json`

Cette étape concatène seulement sigle et intitulé de chaque structure trouvée.

```json
[
{
  ...
  "ws": {
    "rnsr": [
      [
        {
          "num_nat_struct": "200212739T",
          "intitule": "Écologie, systématique et évolution",
          "sigle": "ESE",
          "ville_postale": "Orsay Cedex",
          "code_postal": "91405",
          "etabAssoc": [...],
          "intituleAppauvri": "ecologie, systematique et evolution",
          "sigleAppauvri": "ese",
          "ville_postale_appauvrie": "orsay cedex",
          "annee_creation": "2002",
          "an_fermeture": ""
        }
      ]
    ],
    "etab": [
      "ESE: Écologie, systématique et évolution"
    ]
  }
}
]
```

### `05-corpus-simple-instituts.json`

Cette étape n'est utile que quand on a un RNSR, et va chercher dans une table de
correspondance RNSR-Instituts du CNRS.

On ramène à la racine du champ `ws.rnsr` les identifiants RNSR et les instituts
CNRS identifiés.

```json
[
{
  ...
  "ws": {
    "rnsr": [
      [
        {
          "num_nat_struct": "200212739T",
          "intitule": "Écologie, systématique et évolution",
          "sigle": "ESE",
          "ville_postale": "Orsay Cedex",
          "code_postal": "91405",
          "etabAssoc": [...],
          "intituleAppauvri": "ecologie, systematique et evolution",
          "sigleAppauvri": "ese",
          "ville_postale_appauvrie": "orsay cedex",
          "annee_creation": "2002",
          "an_fermeture": ""
        }
      ]
    ],
    "etab": [
      "ESE: Écologie, systématique et évolution"
    ],
    "rnsr_id": [
      "200212739T"
    ],
    "instituts": [
      "INEE"
    ]
  }
}
]
```

### `06-corpus-simple-teeft-en.json`

Ici, nous extrayons automatiquement des termes représentatifs du titre et de
l'abstract.

```json
[
{
  "title": "Impact of sea level rise on the 10 insular biodiversity hotspots",
  "abstract": "AimDespite considerable attention to climate change, no global assessment of the consequences of sea level rise is available for insular ecosystems. Yet, ... on islands at risk as a result of near future sea level rise.",
  ...
  "ws": {
    "rnsr": [
      [{...}]
    ],
    "etab": [
      "ESE: Écologie, systématique et évolution"
    ],
    "rnsr_id": [
      "200212739T"
    ],
    "instituts": [
      "INEE"
    ],
    ,
    "teeft": [
      "insular",
      "sea level rise",
      "biodiversity",
      "endemic",
      "endemic species",
      "caribbean islands",
      "aimdespite considerable attention",
      "climate change",
      "global assessment",
      "insular ecosystems"
    ]
  }
}
]
```

### `07-corpus-simple-pascal.json`

Là, nous faisons une classification automatique, à partir du titre et de
l'abstract, et suivant le plan de classement de la base Pascal, sur 3 niveaux.

```json
[
{
  "title": "Impact of sea level rise on the 10 insular biodiversity hotspots",
  "abstract": "AimDespite considerable attention to climate change, no global assessment of the consequences of sea level rise is available for insular ecosystems. Yet, ... on islands at risk as a result of near future sea level rise.",
  ...
  "ws": {
    "rnsr": [
      [{...}]
    ],
    ...
    "pascal": [
      {
        "code": {
          "id": "002",
          "value": "Sciences biologiques et médicales"
        },
        "confidence": 0.9606534838676453,
        "rang": 1
      },
      {
        "code": {
          "id": "002A",
          "value": "Sciences biologiques fondamentales et appliquées. Psychologie"
        },
        "confidence": 1.0000030994415283,
        "rang": 2
      },
      {
        "code": {
          "id": "002A14",
          "value": "Écologie animale, végétale et microbienne"
        },
        "confidence": 1.0000075101852417,
        "rang": 3
      }
    ]
  }
}
]
```

### `08-corpus-simple-label-pascal.json`

Cette étape concatène les libellés des deux derniers niveaux de la
classification Pascal (et remplace la structure pré-existante).

```json
[
{
  "title": "Impact of sea level rise on the 10 insular biodiversity hotspots",
  "abstract": "AimDespite considerable attention to climate change, no global assessment of the consequences of sea level rise is available for insular ecosystems. Yet, ... on islands at risk as a result of near future sea level rise.",
  ...
  "ws": {
    "rnsr": [
      [{...}]
    ],
    ...
    "pascal": "Sciences biologiques fondamentales et appliquées. Psychologie - Écologie animale, végétale et microbienne"
  }
}
]
```

### `09-corpus-simple-cnrs.json`

Cette étape n'est là qu'à titre d'illustration: elle est censée détecter les
affiliations CNRS (mais elle ne fait pour l'instant que dire si la notice
contient une adresse incluant les chaînes `CNRS` ou `UMR`; ce qui est largement
insuffisant car, par exemple, l'IRD a des laboratoires qui sont des UMR, mais
qui n'appartiennent pas au CNRS).

Une piste d'amélioration est l'utilisation du service web
[`cnrsunit`](https://objectif-tdm.inist.fr/2022/11/09/detection-dunites-cnrs/).

```json
[
{
  "title": "Impact of sea level rise on the 10 insular biodiversity hotspots",
  ...
  "affiliations": [
    "Univ Paris 11, UMR CNRS 8079, F-91405 Orsay, France"
  ],
  ...
  "ws": {
    "rnsr": [
      [{...}]
    ],
    ...
    "pascal": "Sciences biologiques fondamentales et appliquées. Psychologie - Écologie animale, végétale et microbienne",
    "cnrs": "oui"
  }
}
]
```

## Installation

Instancier dans un [ezmaster](https://github.com/Inist-CNRS/ezmaster)
l'application
[inistcnrs/lodex-crontab](https://github.com/Inist-CNRS/ezmaster-apps/tree/main/applications/lodex-crontab)
version 1.4+

## Configuration

La configuration de l'instance doit contenir différentes informations, en plus de la configuration par défaut:

- [WOS_API_KEY](#wos_api_key)
- [tâches](#tâches) (`tasks`)

### WOS_API_KEY

C'est la clé de l'[API Web of
Science](https://developer.clarivate.com/apis/wos), elle est indispensable et
propre à chaque utilisateur.

Le CNRS peut interroger l'API (pas plus d'une fois par seconde), et est limité à
1 million de documents par an (mais peut demander l'extension une fois cette
limite atteinte).

### Tâches

La partie `tasks` de la configuration permet de déclencher le traitement.

C'est un tableau JSON d'objets comprenant trois champs:

1. `CronRule`: quand déclencher l'action
2. `Target`: quel fichier on veut obtenir
3. `RunOnStartup`: doit-on déclencher l'action _aussi_ au (re-)démarrage de
   l'instance.

#### `CronRule`

Champ au format `crontab` (commande UNIX permettant d'exécuter des programmes à
des moments pré-programmés sur une machine locale).

> 💡 Il est conseillé d'utiliser le site <https://crontab.guru/> pour vérifier à
> quel(s) moment(s) l'action sera déclenchée.

La valeur `0 1 * * *` contenue dans la configuration par défaut signifie: à une
heure du matin, tous les jours.

Le zéro du début indique les minutes, le 1 suivant indique l'heure.  
Viennent ensuite le jour (du mois), le mois puis le jour (de la semaine).

L'étoile signifie « _tous_ », alors qu'un intervalle s'écrit avec un tiret.  
Ainsi `0 8-17 * * *` veut dire que l'action se déclenchera tous les jours, à
chaque heure de travail (de 8 heures à 17 heures).  
Le `/` représente un pas: `0 8-17/2 * * *` signifie tous les jours toutes les
deux heures entre 8 heures et 17 heures.  
Pour bien faire, on peut aussi limiter aux jours de la semaine (lundi à
vendredi): `0 8-17/2 * * 1-5`.  
Cette expression peut servir pendant un développement, mais on verra que
`RunOnStartup` est plus pratique pour ça.  

> 📗 Si la procédure a déjà été exécutée au complet, et qu'aucun fichier n'a été
> supprimé ou remplacé, elle ne sera pas rejouée (de toute façon, elle aurait
> fourni les mêmes résultats).

#### `Target`

`Target` est le chemin du fichier qu'on veut produire.  

Par défaut, c'est le fichier produit par la dernière étape (le dernier script).  
Mais si par exemple on veut éviter cette dernière étape (peut-être parce qu'elle
n'est pas encore efficace ?), on peut remplacer la valeur de target par
`data/08-corpus-simple-label-pascal.json`.  
Il faut que ce soit le chemin exact à l'intérieur du répertoire de l'instance.  

Toutes étapes nécessaires (et seulement elles) sont rejouées jusqu'à produire ce
fichier.  
Cela signifie que si aucun fichier d'une étape précédente (ou le fichier numéroté `00-...`) n'est plus récent que le fichier `Target`, il ne sera pas regénéré.  
Pour forcer la regénération d'un fichier, il suffit de le supprimer.  

#### `RunOnStartup`

Ce booléen est à `true` par défaut, mais il vaut mieux, une fois la procédure au
point, le positionner à `false`.  
Quand il est vrai, la procédure est lancée à chaque (re-)démarrage de
l'instance, c'est-à-dire aussi quand on met à jour la configuration.  
Ceci dit, comme ne sont jouées que les étapes qui le nécessitent (le fichier
source de l'étape a changé, ou a été supprimé), ce n'est pas très grave de le
laisser à `true`.  

> 💡 Pour forcer l'exécution d'une étape et des suivantes, il suffit de
> supprimer le fichier résultant de cette étape (dont le nom commence par le
> numéro de l'étape).

### Exemple de configration complète

```json
{
  "environnement": {
    "CRON_VERBOSE": true,
    "EZS_VERBOSE": false,
    "DEBUG": "ezs",
    "WOS_API_KEY": "À RENSEIGNER IMPÉRATIVEMENT!"
  },
  "packages": [
    "@ezs/core@2.1.0",
    "@ezs/basics@1.22.3",
    "@ezs/analytics@2.0.2"
  ],

  "files" : {
    "zip": "https://gitbucket.inist.fr/parmentf/giec-wos/archive/doi-vol2-2.zip"
  },
  "tasks": [
    {
      "CronRule": "0 1 * * *",
      "Target": "data/09-corpus-simple-cnrs.json",
      "RunOnStartup": true
    }
  ]
}
```