|
|
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èmeLa 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 - 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éovecteurListons 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 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 SPSEn 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, awkL'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èseQuoiqu'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. ConclusionIl 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.
|
| Tous droits réservés © 2003-2006 Gaétan Martineau |