Vérifier le nombre de canaux sur chaque ligne récepteur pour chaque enregistrement.

Contrôle qualité du nombre de canaux par lignes

Accueil

Journal de mission
Course à pied
Ski de randonnée
Alpinisme
Voile
Ecrits
Diaporamas

Programmation

Carnet des invités

Accueil > Programmation > Contrôle qualité du nombre de canaux par lignes

Vérifier le nombre de canaux sur chaque ligne récepteur pour chaque enregistrement.

Problème

La géométrie s'étant terminée avec un statut "Normal", le nombre de traces écrites en sortie diffère néanmoins du nombre de traces dans le fichier X. Où se trouvent les traces en trop ou en moins?

Solution proposée

  1. Lister le nombre de canaux par "spread" selon Géovecteur.
  2. Lister le nombre de canaux par "spread" selon le X.
  3. Comparer les deux.

1 - Présentation d'un cas pratique et réel.

Nous constatons pour le swath 19, en sortie de géométrie Géovecteur, un nombre de 1,427,594 traces sismiques et auxilliaires;

prompt$ awk '/^ *\*    Number of seismic traces ..   =/' 03_Geometry3D_19.07657.list
                    *    Number of seismic traces ..   =     1427594   *

Le fichier S montre un total de 2306 tirs unitaires;

prompt$ awk '/^S/' sw19.s01 | wc -l
   2306

Et le fichier X montre un total de 1,418,392 traces sismiques;

prompt$ awk '/^X/{tot+=(substr($0,43,4)-substr($0,39,4))+1}END{print tot}' sw19.x01
1418392

Chaque tir comprenant 4 canaux auxiliaires, nous avons un nombre total espéré de traces de 1418392+2306*4, soit 1,427,616 traces. C'est 22 de plus que 1,427,594. La question est; comment trouver, parmi ce million et demi de traces, les 22 manquantes? La solution proposée ici se base sur le principe "diviser pour conquérir". Ainsi, au lieu de comparer le nombre de traces par fichier entier, nous allons le comparer en unités beaucoup plus petites. Il serait intéressant de comparer le nombre de traces par enregistrement. Mais il est encore plus efficace de laisser l'ordinateur chercher dans plus de détail encore, soit en lui faisant chercher le nombre de traces par ligne récepteur et enregistrement.

2 - Nombre de traces par ligne récepteur selon Géovecteur

Listons le nombre de traces par ligne. Le programme Géovecteur suivant est utilisé;

prompt$ pwd
/gvtscr/proj/TUN3216/JOBS
prompt$ cat -n nb_ch_per_line.txt
     1  **==============================================================================
     2  ** File : nb_ch_per_line.mod
     3  ** G. Martineau (gmarti@mediom.qc.ca)
     4  ** Comments:
     5  **============||======||======|=================================================
     6  * LIBRI TR 01                 PREFIX=GE,M19,F1,STG,SELEC=MOT3=1
     7  **============||======||======|=================================================
     8  * DLOOP             1
     9  * INPTR               ++      LTR01,RL100,SI2,
    10  * MODET       ==      ++      *MOT42=MOT22,10000,MULT,MOT36,PLUS,
    11  * MNGTY       ==      ++      WORD42,
    12  * MODET       ==      IS      *MOT48=1,1,PAS,RESTART=Y
    13  * SELEC       IS              BRANCH=IFY,ON1,IFNY,OFF1,
    14  * LISTE SL    IS              SW1,STEP1,22,36,48,
    15  * ENDLP
    16  **============||======||======|=================================================
    17  * PROCS                       X(YB1)
    18  /MASPRO
prompt$ lsub nb_ch_per_line.txt exec

Il lit le fichier géométrisé 19 et construit un nombre artificiel, appelons le Z, qui est le numéro de record multiplié par 10,000 auquel est additionné le numéro de ligne récepteur, toujours exprimé sur quatre chiffres. Il aurait été possible de baser Z sur le seul numéro de ligne récepteur, rendant le programme plus simple, mais moins robuste et surtout inutilisable sur une mission 2D.

La ligne 12 du programme demande, à chaque nouvelle trace sismique lue, d'incrémenter une variable et de l'assigner à l'adresse 48 de cette trace, son "mot" 48. Advenant que nous changions de nombre Z, nous imprimons les dernières valeurs des

  • numéro d'enregistrement (mot 22)
  • numéro de ligne récepteur (mot 36)
  • nombre cumulé de traces pour cet enregistrement et cette ligne récepteur (mot 48).

    Nous remettons le compteur à 1 et poursuivons l'incrémentation. Nous faisons ceci pour le quelque million et demi de traces du fichier. Ceci n'apparait pas sur la sortie standard, mais dans un fichier texte qui est un genre de rapport de l'exécution du programme. Ce rapport, du reste extrêmenent verbeux, ne présente réellement d'intérêt que dans les lignes satisfaisant l'expression régulière "^ LISIS", dont quelques exemples sont donnés ici;

    prompt$ pwd
    /gvtscr/proj/TUN3216/LISTS
    awk '/^ LISIS/' nb_ch_per_line.07780.list  | head
     LISIS# 1 ;22=          1 ;36=       5281 ;48=         72
     LISIS# 1 ;22=          1 ;36=       5286 ;48=         72
     LISIS# 1 ;22=          1 ;36=       5291 ;48=         72
     LISIS# 1 ;22=          1 ;36=       5296 ;48=         72
     LISIS# 1 ;22=          1 ;36=       5301 ;48=         71
     LISIS# 1 ;22=          1 ;36=       5306 ;48=         72
     LISIS# 1 ;22=          2 ;36=       5281 ;48=         72
     LISIS# 1 ;22=          2 ;36=       5286 ;48=         72
     LISIS# 1 ;22=          2 ;36=       5291 ;48=         72
     LISIS# 1 ;22=          2 ;36=       5296 ;48=         72

    La première ligne fichier lue montre, pour l'enregistrement 1 sur la ligne récepteur 5281, 72 récepteurs. Nous simplifions, on verra pourquoi, la lecture de ce flux en ne conservant que l'information vraiment intéressante. Ainsi invoquons-nous l'éditeur de flux d'unix de cette façon;

    prompt$ awk '/^ LISIS/' nb_ch_per_line.07780.list | sed 's/^.*# 1//;s/;..=//g;' | head 
               1        5281          72
               1        5286          72
               1        5291          72
               1        5296          72
               1        5301          71
               1        5306          72
               2        5281          72
               2        5286          72
               2        5291          72
               2        5296          72

    Et nous sauvegardons cette information dans un fichier que l'on rappellera au besoin;

    prompt$ awk '/^ LISIS/' nb_ch_per_line.07780.list | sed 's/^.*# 1//;s/;..=//g;' > selon_OUTBD

    Je regarde mon total de traces au passage, en faisant le total de la colonne 3 et obtient 1,418,370 traces;

    prompt$ awk '{s+=$3}END{printf ( "%d\n",s)}' selon_OUTBD
    1418370

    Nous retrouvons donc la même différence de; 1418392-1418370 = ... 22, signalant que le principe suivit doit être bon et que nous nous approchons de la solution.

    3 - Nombre de traces par ligne récepeteurs selon SPS

    En le répertoire des fichiers SPS, nous appliquons exactement le même traitement au fichier X que nous avons fait à l'aide de Géovecteur avec le fichier OUTBD, c'est à dire de lister le nombre de traces pour chaque ligne récepteur. Le programme ici est écrit, non pas en Géovecteur, mais en langage "awk";

    prompt$ cat -n nb_ch_per_line.awk
         1  #!/bin/awk
         2  /^X/ {
         3     mot22 = substr($0,8,4);
         4     mot36 = substr($0,51,4);
         5     lo17 = substr($0,39,4);
         6     hi17 = substr($0,43,4);
         7     if ( cumul!=0 && (mot22 != prev22 || mot36 != prev36 )) {
         8        printf ( "%7d %7d %7d %10d\n", prev22, prev36, nbch, cumul );
         9        nbch = 0;
        10     }
        11     nbch += abs ( hi17 - lo17 ) + 1;
        12     cumul += abs ( hi17 - lo17 ) + 1;
        13     prev22 = mot22;
        14     prev36 = mot36;
        15  } END {
        16     printf ( "%7d %7d %7d %10d\n", prev22, prev36, nbch, cumul );
        17  }

    On pourrait écrire quelque chose équivalent en perl;

    prompt$ cat -n nb_ch_per_line.pl
         1  #!/usr/bin/perl -w
         2  ($cumul, $prev_record, $prev_line ) = ( 0, "", "" );
         3  while (<>) {
         4     if ( /^X/ ) {
         5        $ch_units = substr($_,42,4)-substr($_,38,4)+1;
         6        ( $record, $r_line ) = ( substr($_,7,4), substr($_,50,4) );
         7        if ( $cumul != 0 && ($record . $r_line) != ($prev_record . $prev_line) ) {
         8           printf "%7d %7d %7d %10d\n", $prev_record, $prev_line, $nb_ch, $cumul;
         9           $nb_ch = 0;
        10        }
        11        ( $prev_record, $prev_line ) = ( $record, $r_line);
        12        $nb_ch += $ch_units;
        13        $cumul += $ch_units;
        14     }
        15  }
        16  printf "%7d %7d %7d %10d\n", $prev_record, $prev_line, $nb_ch, $cumul;

    La proposition perl, je crois, aurait pu être simplifiée de beaucoup. En fait, il ne serait pas surprenant que les vrais maniaques de ce langage n'arrivent à compacter le programme en une seule ligne beaucoup plus efficace.

    Quoiqu'il en soit, dans les deux cas, nous lisons le X ligne de fichier par ligne de fichier et retenons les numéros de record, canaux, ligne récepteur que l'on stocke en des variables. Lorsque survient à la fois un changement de record et de numéro de ligne récepteur, nous imprimons le nombre cumulé de canaux pour le record et ligne récepteurs précédents. Lorsque tout est terminé, nous devons nécessairement imprimer la dernière saisie lue du flux.

    Parenthèse ; remarque sur les interpréteurs perl, awk

    L'intérêt de ce genre de programme, par rapport à Géovecteur, est que si vous faites une erreur de syntaxe, vous êtes avertis du fait aussi rapidement que l'éclair. L'information crève de suite les yeux puisque tout message d'erreur est acheminé sur le canal d'erreur standard, lequel, à moins de redirection, est l'écran. Comparativement, la façon Géovecteur de faire nécessite, après une très lente compilation terminée en erreur, de manuellement rechercher un quelconque message la plupart du temps peu explicite, de surcroit camouflé dans un énorme fichier de plusieurs centaines de lignes, parfois beaucoup plus.

    Pour ces raisons, on améliore de beaucoup sa productivité si l'on a une quelconque connaissance de ces petits langages dans sa boite à outils. Et si l'on peut, dans la mesure du possible, éviter de s'empêtrer en Géovecteur, lequel reste encore bien perfectible, c'est bienvenu.

    Il reste une contrainte; savoir se comprendre les uns les autres et parler la ou les mêmes langues.

    ...fin de la parenthèse

    Quoiqu'il en soit, notre programme donne par exemple les numéros de records, ligne R, nombre de canaux et cumul de canaux sous cette forme;

    prompt$ awk -f nb_ch_per_line.awk sw19.x01 | tail
       3461    5291     114    1417398
       3461    5296     114    1417512
       3461    5301     101    1417613
       3461    5306     111    1417724
       3462    5281     114    1417838
       3462    5286     114    1417952
       3462    5291     114    1418066
       3462    5296     114    1418180
       3462    5301     101    1418281
       3462    5306     111    1418392

    L'intérêt supplémentaire ici est de pouvoir lister le cumul, ce qui nous donne en fin de flux le nombre total espéré de traces, soit 1,418,392 et prouve que notre script fonctionne bien. Le flux entier est sauvegardé en un fichier, le nombre de suite de canaux sur une même ligne récepteur est comparé avec celui d'OUTBD et enfin, advenant un nombre égal, les deux fichiers sont juxtaposés et la différence des colonnes 3 et 6 est faite.

    prompt$ awk -f nb_ch_per_line.awk sw19.x01 > selon_X
    prompt$ wc -l selon_X ../../LISTS/selon_OUTBD
      13836 selon_X
      13836 ../../LISTS/selon_OUTBD
      27672 total

    A tout le moins, nous avons un même nombre de 13,836 "spreads" dans un fichier comme dans l'autre. Regardons en lesquels de ce 13,836 spreads se trouve la ou les erreurs. On juxtapose les fichiers à l'aide de "paste";

    prompt$ paste -d"\0" selon_X ../../LISTS/selon_OUTBD|head
          1    5281      72         72           1        5281          72
          1    5286      72        144           1        5286          71
          1    5291      72        216           1        5291          72
          1    5296      72        288           1        5296          72
          1    5301      71        359           1        5301          71
          1    5306      72        431           1        5306          72
          2    5281      72        503           2        5281          72
          2    5286      72        575           2        5286          71
          2    5291      72        647           2        5291          72
          2    5296      72        719           2        5296          72

    L'intérêt, bien sûr, est de faire la différence des colonnes 3 et 7, et, pourquoi pas, le cumul de ces différences, comme on pourrait faire dans un tableur;

    prompt$ paste -d"\0" selon_X ../../LISTS/selon_OUTBD | awk '{s+=($7-$3);printf ("%s %d %3d\n", $0, ($7-$3),s)}' | head
          1    5281      72         72           1        5281          72 0   0
          1    5286      72        144           1        5286          72 0   0
          1    5291      72        216           1        5291          72 0   0
          1    5296      72        288           1        5296          72 0   0
          1    5301      71        359           1        5301          71 0   0
          1    5306      72        431           1        5306          72 0   0
          2    5281      72        503           2        5281          72 0   0
          2    5286      72        575           2        5286          72 0   0
          2    5291      72        647           2        5291          72 0   0
          2    5296      72        719           2        5296          72 0   0

    Ce qui nous intéresse sont les seuls "spreads" pour lesquels on a une différence non nulle; toute ligne fichier dont l'élément de la colonne 8 est non nul est filtré avec '$8!=0', de cette façon;

    prompt$ paste -d"\0" selon_X ../../LISTS/selon_OUTBD |\
       awk '{s+=($7-$3);printf ("%s %d %3d\n", $0, ($7-$3),s)}' | awk '$8!=0'
        528    5296     109     247180         528        5296          96 -13 -13
       1127    5281     122     653610        1127        5281         121 -1 -14
       1131    5281     122     656538        1131        5281         121 -1 -15
       1133    5281     122     658002        1133        5281         121 -1 -16
       1134    5281     122     658734        1134        5281         121 -1 -17
       1136    5281     122     660198        1136        5281         121 -1 -18
       1137    5281     122     660930        1137        5281         121 -1 -19
       1138    5281     122     661662        1138        5281         121 -1 -20
       1139    5281     122     662394        1139        5281         121 -1 -21
       1306    5281     102     763330        1306        5281         101 -1 -22

    Nous avons donc trouvé, non pas une, mais plusieurs petites erreurs minimes dont le cumul, comme l'indique la dernière ligne fichier ci-dessus, fait bien notre différence de 22. La première, chose vraiment surprenante, est que pour un tir, on a un saut dans les numéros de canaux. Sur cette ligne 5296, pour ce seul record 528, on a 96 au lieu de 109 canaux. On peut voir en "selon_OUTBD";

             527        5281         109
             527        5286         109
             527        5291         109
             527        5296         109
             527        5301         109
             527        5306         109
             528        5281         109
             528        5286         109
             528        5291         109
             528        5296          96
             528        5301         109
             528        5306         109
             529        5281         109
             529        5286         109
             529        5291         109
             529        5296         109
             529        5301         109
             529        5306         109
             530        5281         109

    Bien que surprenant, tel est le fichier d'entrée provenant de la lecture de le bande reçue du terrain. Ainsi, on passe du canal 360, récepteur 1249 à subitement 374, récepteur 1263. Pour avoir le coeur net, nous relisons la bande contenant l'enregistrement 528 et si nous listons les mots 22, 27, 36 et 37 par pas de un, nous obtenons un message d'erreur à l'endroit précis où se trouve le saut;

     LISA$# 1 ;22=        528 ;17=        358 ;36=       5296 ;37=       1247
     LISA$# 1 ;22=        528 ;17=        359 ;36=       5296 ;37=       1248
    *** SEGIN (PM) : READ ERROR IST= 6
    *** SEGIN (PM) : LOGICAL TAPE #  1 FILE #    73
    *** SEGIN (PM) : TRACE SKIPPED
     LISA$# 1 ;22=        528 ;17=        360 ;36=       5296 ;37=       1249
     LISA$# 1 ;22=        528 ;17=        374 ;36=       5296 ;37=       1263
     LISA$# 1 ;22=        528 ;17=        375 ;36=       5296 ;37=       1264

    Tiens donc. Ceci nous fait apporter la correction suivante dans le X (notons que ceci devrait se faire sous Geoland aux fins de préservation de l'intégrité du flux de géométrie);

    prompt$ diff sw19.x01_new sw19.x01
    8392,8393c8392,8393
    < X6      5281119-1260             53081 359 360119-5296             1248    12492
    < X6      5281119-1260             53081 374 391119-5296             1263    12801
    ---
    > X6      5281119-1260             53081 359 366119-5296             1248    12552
    > X6      5281119-1260             53081 367 391119-5296             1256    12801

    ... diminuant ainsi son nombre de traces de 13 en un premier temps. Pour les autres différences, il appert que le canal 72, pour les records 1131, 1133, 1134, 1136, 1137, 1138 et 1139 n'existe pas. Pour le record 1306, c'est le canal 52 qui est absent. La particularité de cette dernière anomalie est qu'à chaque fois, le récepteur 1308 de cette ligne 5281 est en cause. Voici deux traces consécutives;

         WORD 11  ...     0 7         51   52811307 
         WORD 11  ...     0 7         53   52811309

    C'est surprenant de passer d'un canal N à N+2. Peut-être ce "gap" ne se trouve t'il pas sur la bande et que le canal ait été zappé lors de la lecture. On pourrait regarder ceci plus en détail, mais disons qu'à ce point, même si on a un curieux X, sans canal 72 ou 52, ce X présente une bonne syntaxe, s'accorde avec le fichier à géométriser et présente des gaps de canaux analogues à ceux que nous formulons lorsque se présente une coupure ligne.

    Conclusion

    Il aurait bien sûr été possible d'utiliser un quelconque tableur pour lister ces 13836 spreads. L'option présentée ici est une, parmi, sans doute, autant de personnes qui auraient fait face au problème.

    Son avantage est qu'elle peut entièrement être codée en "MASPRO" dans le programme Géovecteur de départ, "nb_ch_per_line.txt". Ainsi peut-elle devenir complètement transparente et être invoquée sans aucune intervention de l'utilisateur. Il n'y aurait alors plus, une fois le contenu de cette colonne 8 listé, qu'à examiner s'il se présente des spreads avec différence non-nulle, accélérant d'autant la découverte de l'erreur, laquelle, avouons-le, fut présentée ici avec longueur d'explications.

    Un exemple de script réalisant tout ceci en une passe pourrait être;

    #!/bin/bash
    if [ $# != 2 ] ; then
       printf "Usage: %s x_file list_file\n" $0
    fi
     
    # Writing spreads as from X;
    awk '/^X/ {
       mot22 = substr($0,8,4);
       mot36 = substr($0,51,4);
       lo17 = substr($0,39,4);
       hi17 = substr($0,43,4);
       if ( cumul!=0 && (mot22 != prev22 || mot36 != prev36 )) {
          printf ( "%7d %7d %7d %10d\n", prev22, prev36, nbch, cumul );
          nbch = 0;
       }
       nbch += abs ( hi17 - lo17 ) + 1;
       cumul += abs ( hi17 - lo17 ) + 1;
       prev22 = mot22;
       prev36 = mot36;
    } END {
       printf ( "%7d %7d %7d %10d\n", prev22, prev36, nbch, cumul );
    }' $X > spread_X_$$
     
    # Writing spreads as from LISTE;
    awk '/^ LISIS/' $list_file | sed 's/^.*# 1//;s/;..=//g;' > spread_OUTBD_$$
     
    # Compare; (FIXME: perl and a hash table would make a more robust script..)
    printf "H Spreads QC\n"  > $outfile
    printf "H %s : %d spreads\n" $X `wc -l spread_X_$$|awk '{print $1}'` >> $outfile
    printf "H %s : %d spreads\n" $list_file `wc -l spread_OUTBD_$$|awk '{print $1}'` >> $outfile
    printf "H ffidX      rX      nX      cumul   ffidOUTBD      rOUTBD      nOUTBD     dif\n" >> $outfile
    paste -d"\0" spread_X_$$ spread_OUTBD_$$ | awk '{
       s+=$7-$3;
       printf ("%s %7d %7d\n", $0, ($7-$3),s);
    }' >> $outfile
    rm spread_X_$$ spread_OUTBD_$$
    

    Et si l'on invoque le script en fin d'exécution de job, tel que suit;

    **==============================================================================
    ** File : nb_ch_per_line.mod
    ** G. Martineau (gmarti@mediom.qc.ca)
    ** Comments:
    ** #lina
    **============||======||======|=================================================
    * LIBRI TR 01                 PREFIX=GE,M#01#,F1,STG,SELEC=MOT3=1
    **============||======||======|=================================================
    * DLOOP             1
    * INPTR               ++      LTR01,RL100,SI2,
    * MODET       ==      ++      *MOT42=MOT22,10000,MULT,MOT36,PLUS,
    * MNGTY       ==      ++      WORD42,
    * MODET       ==      IS      *MOT48=1,1,PAS,RESTART=Y
    * SELEC       IS              BRANCH=IFY,ON1,IFNY,OFF1,
    * LISTE SL    IS              SW1,STEP1,22,36,48,
    * ENDLP
    **============||======||======|=================================================
    * PROCS                       X(YB1)
    /MASPRO
    end
    cp /proj/#C1#/SCRIPTS/diff_spreads.sh ./
    ./diff_spreads.sh /proj/#C1#/FIELD/Swath#01#/sw#01#.x01 LIST
    mv diff_spreads.sh.out /proj/#C1#/FIELD/Swath#01#/sw#01#.diff_spreads

    Alors il n'y a rien d'autre à faire que de vérifier, après exécution terminée normalement, le contenu du fichier ;

    /proj/#C1#/FIELD/Swath#01#/sw#01#.diff_spreads

    Par exemple;

    H Spreads QC
    H sw10.x01 : 762 spreads
    H ../../LISTS/nb_ch_per_line_10.07772.list : 762 spreads
    H ffidX      rX      nX      cumul   ffidOUTBD      rOUTBD      nOUTBD     dif
          1    5011      58         58           1        5011          58       0       0
          1    5016      58        116           1        5016          58       0       0
          1    5021      58        174           1        5021          58       0       0
          1    5026      58        232           1        5026          58       0       0
          1    5031      58        290           1        5031          58       0       0
          1    5036      58        348           1        5036          58       0       0

    Dans le cas d'erreurs éventuelles, la consultation de ce fichier devrait beaucoup faciliter la recherche du problème.

  •  

    Haut de page

    Tous droits réservés © 2003-2006 Gaétan Martineau