La documentation officielle est hébergée sur readthedocs.
Segyio est une petite bibliothèque C sous licence LGPL pour une interaction facile avec les données sismiques au format SEG-Y et Seismic Unix, avec des liaisons de langage pour Python et Matlab. Segyio est une tentative de créer une bibliothèque facile à utiliser, intégrable et orientée vers la communauté pour les applications sismiques. Les fonctionnalités sont ajoutées au fur et à mesure de leurs besoins ; les suggestions et contributions de toutes sortes sont les bienvenues.
Pour rester informé des derniers développements et fonctionnalités, consultez le journal des modifications. Pour écrire du code à l’épreuve du temps, consultez les modifications majeures prévues.
Lorsque segyio est construit et installé, vous êtes prêt à commencer la programmation ! Consultez le didacticiel, les exemples, les exemples de programmes et les exemples de blocs-notes. Pour une référence technique avec des exemples et des petites recettes, lisez la documentation. Les documents API sont également disponibles avec pydoc - démarrez votre interpréteur Python préféré et tapez help(segyio)
, qui devrait bien s'intégrer avec IDLE, pycharm et d'autres outils Python.
import segyio
import numpy as np
with segyio . open ( 'file.sgy' ) as f :
for trace in f . trace :
filtered = trace [ np . where ( trace < 1e-2 )]
Voir les exemples pour en savoir plus.
Une copie de segyio est disponible à la fois sous forme de binaires prédéfinis et de code source :
apt install python3-segyio
pip install segyio
git clone https://github.com/statoil/segyio
Pour construire Segyio, vous avez besoin de :
Pour construire la documentation, vous avez également besoin de sphinx
Pour créer et installer segyio, effectuez les actions suivantes dans votre console :
git clone https://github.com/equinor/segyio
mkdir segyio/build
cd segyio/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON
make
make install
make install
doit être effectué en tant que root pour une installation du système ; si vous souhaitez installer dans votre répertoire personnel, ajoutez -DCMAKE_INSTALL_PREFIX=~/
ou un autre répertoire approprié, ou make DESTDIR=~/ install
. Veuillez vous assurer que votre environnement récupère les emplacements d'installation non standard (PYTHONPATH, LD_LIBRARY_PATH et PATH).
Si vous avez plusieurs installations Python ou si vous souhaitez utiliser un interpréteur alternatif, vous pouvez aider cmake à trouver le bon en passant -DPYTHON_EXECUTABLE=/opt/python/binary
avec le préfixe d'installation et le type de build.
Pour créer les liaisons matlab, appelez CMake avec l'option -DBUILD_MEX=ON
. Dans certains environnements, les binaires Matlab se trouvent dans un emplacement non standard, auquel cas vous devez aider CMake à trouver les binaires Matlab en passant -DMATLAB_ROOT=/path/to/matlab
.
Il est recommandé de construire en mode débogage pour obtenir plus d'avertissements et d'intégrer des symboles de débogage dans les objets. Remplacer Debug
par Release
dans CMAKE_BUILD_TYPE
est suffisant.
Les tests se trouvent dans les répertoires langue/tests, et il est fortement recommandé que les nouvelles fonctionnalités ajoutées soient démontrées pour vérifier leur exactitude et se contracter en ajoutant un test. Tous les tests peuvent être exécutés en appelant ctest
. N'hésitez pas à utiliser les tests déjà rédigés comme guide.
Après avoir construit segyio, vous pouvez exécuter les tests avec ctest
, exécutés à partir du répertoire build.
Veuillez noter que pour exécuter les exemples Python, vous devez indiquer à votre environnement où trouver la bibliothèque Python. Il peut être installé en tant qu'utilisateur ou en ajoutant la bibliothèque segyio/build/python à votre chemin python.
Tout le code de ce didacticiel suppose que segyio est importé et que numpy est disponible en tant que np.
import segyio
import numpy as np
Ce didacticiel suppose que vous connaissez Python et numpy. Pour une actualisation, consultez le didacticiel Python et le démarrage rapide de numpy
L'ouverture d'un fichier en lecture se fait avec la fonction segyio.open
, et est utilisée de manière idiomatique avec les gestionnaires de contexte. En utilisant l'instruction with
, les fichiers sont correctement fermés même en cas d'exceptions. Par défaut, les fichiers sont ouverts en lecture seule.
with segyio . open ( filename ) as f :
...
Open accepte plusieurs options (pour une référence plus complète, consultez la docstring de la fonction open avec help(segyio.open)
. L'option la plus importante est le deuxième argument de position (facultatif). Pour ouvrir un fichier en écriture, faites segyio.open(filename, 'r+')
, à partir de la fonction C fopen
.
Les fichiers peuvent être ouverts en mode non structuré , soit en passant segyio.open
les arguments facultatifs strict=False
, auquel cas ne pas établir de structure (numéros en ligne, numéros croisés, etc.) n'est pas une erreur, et ignore_geometry=True
, auquel cas segyio n'essaiera même pas de définir ces attributs internes.
L'objet fichier segy possède plusieurs attributs publics décrivant cette structure :
f.ilines
Numéros en ligne déduitsf.xlines
Nombres de lignes croisées déduitsf.offsets
Numéros de décalages déduitsf.samples
Décalages d'échantillon déduits (fréquence et délai d'enregistrement)f.unstructured
Vrai si non structuré, Faux si structuréf.ext_headers
Le nombre d'en-têtes textuels étendus Si le fichier est ouvert non structuré , toutes les propriétés de ligne seront None
.
Dans Segyio, les données sont récupérées et écrites via ce qu'on appelle les modes . Les modes sont des tableaux abstraits, ou des schémas d'adressage, et modifient la signification des noms et des indices. Tous les modes sont des propriétés sur l'objet descripteur de fichier, prennent en charge la fonction len
et les lectures et écritures sont effectuées via f.mode[]
. Les écritures se font avec affectation. Les modes prennent en charge le découpage de tableau inspiré de numpy. Les modes suivants sont disponibles :
trace
Le mode trace offre un adressage brut des traces telles qu'elles sont disposées dans le fichier. Ceci, avec header
, est le seul mode disponible pour les fichiers non structurés. Les traces sont énumérées 0..len(f.trace)
.
La lecture d'une trace donne un numpy ndarray
, et la lecture de plusieurs traces donne un générateur de ndarray
s. La sémantique du générateur est utilisée et le même objet est réutilisé. Par conséquent, si vous souhaitez mettre en cache ou adresser les données de trace ultérieurement, vous devez explicitement les copier.
> >> f . trace [ 10 ]
> >> f . trace [ - 2 ]
> >> f . trace [ 15 : 45 ]
> >> f . trace [: 45 : 3 ]
header
Avec un comportement d'adressage similaire à trace
, l'accès aux éléments génère des objets d'en-tête au lieu de numpy ndarray
s. Les en-têtes sont des objets de type dict, où les clés sont des entiers, des clés sismiques de style Unix (dans le module segyio.su) et des énumérations segyio (segyio.TraceField).
Les valeurs d'en-tête peuvent être mises à jour en leur attribuant un dict-like, et les clés non présentes sur le côté droit de l'affectation ne sont pas modifiées .
> >> f . header [ 5 ] = { segyio . su . tracl : 10 }
> >> f . header [ 5 ]. items ()
> >> f . header [ 5 ][ 25 , 37 ] # read multiple values at once
iline
, xline
Ces modes généreront une erreur si le fichier n'est pas structuré. Ils considèrent les arguments de []
comme les clés des lignes respectives. Les numéros de ligne augmentent toujours, mais peuvent avoir un espacement arbitraire et inégal. Les noms valides peuvent être trouvés dans les propriétés ilines
et xlines
.
Comme pour les traces, l'obtention d'une ligne donne un ndarray
, et une tranche de lignes donne un générateur de ndarray
. Lors de l'utilisation de tranches avec une étape, certains éléments intermédiaires peuvent être ignorés s'ils ne correspondent pas à l'étape, par exemple en faisant f.line[1:10:3]
sur un fichier avec des lignes [1,2,3,4,5]
équivaut à rechercher 1, 4, 7
et à trouver [1,4]
.
Lorsque vous travaillez avec un fichier pré-stack 4D, le premier décalage est implicitement lu. Pour accéder à un décalage différent ou à une plage, utilisez des indices ou des plages séparés par des virgules, comme tels : f.iline[120, 4]
.
fast
, slow
Ce sont des alias pour iline
et xline
, déterminés par la façon dont les traces sont disposées. Pour les fichiers triés en ligne, fast
donnerait iline
.
depth_slice
La tranche de profondeur est une coupe horizontale en profondeur à l'échelle du fichier. Les valeurs obtenues sont ndarray
et les générateurs de tableaux.
gather
La gather
est l'intersection d'une ligne en ligne et d'une ligne transversale, une colonne verticale de l'enquête, et à moins qu'un seul décalage ne soit spécifié, renvoie un décalage x échantillons ndarray
. En présence de plages, il renvoie un générateur de tels ndarray
s.
text
Le mode text
est un tableau d'en-têtes textuels, où text[0]
est l'en-tête textuel standard et 1..n
sont les en-têtes étendus facultatifs.
Les en-têtes de texte sont renvoyés sous forme de blobs de type octet de 3 200 octets tels qu'ils figurent dans le fichier. La fonction segyio.tools.wrap
peut créer une version orientée ligne de cette chaîne.
bin
Les valeurs de l'en-tête binaire à l'échelle du fichier avec une interface de type dict. Se comporte comme le mode header
, mais sans l'indexation.
> >> for line in f . iline [: 2430 ]:
... print ( np . average ( line ))
> >> for line in f . xline [ 2 : 10 ]:
... print ( line )
> >> for line in f . fast [:: 2 ]:
... print ( np . min ( line ))
> >> for factor , offset in enumerate ( f . iline [ 10 , :]):
... offset *= factor
print ( offset )
> >> f . gather [ 200 , 241 , :]. shape
> >> text = f . text [ 0 ]
> >> type( text )
< type 'bytes' >
> >> f . trace [ 10 ] = np . zeros ( len ( f . samples ))
Plus d'exemples et de recettes peuvent être trouvés dans l' help(segyio)
et dans la section exemples.
Segyio ne tente pas nécessairement d'être la fin des interactions SEG-Y ; notre objectif est plutôt de réduire les obstacles à l'interaction avec les fichiers SEG-Y pour l'intégration de nouvelles applications ou de programmes autonomes.
De plus, l’objectif n’est pas de prendre en charge l’intégralité des fichiers au format standard ou tous les fichiers au format exotique (mais conformes aux standards). Certaines hypothèses sont faites, telles que :
Actuellement, segyio prend en charge :
La fonctionnalité d'écriture de segyio est en grande partie destinée à modifier ou adapter des fichiers. Un fichier créé à partir de zéro n'est pas nécessairement un fichier SEG-Y conforme aux spécifications, car nous écrivons uniquement nécessairement les champs d'en-tête dont Segyio a besoin pour donner un sens à la géométrie. Il est toujours fortement recommandé que les fichiers SEG-Y soient conservés et écrits conformément aux spécifications, mais segyio ne l'applique pas .
Segyio peut gérer de nombreux fichiers de type SEG-Y, c'est-à-dire que Segyio gère des fichiers qui ne sont pas strictement conformes à la norme SEG-Y. Segyio ne fait pas non plus de distinction entre les révisions, mais essaie plutôt d'utiliser les informations disponibles dans le fichier. Pour une référence réelle d'une norme, veuillez consulter les publications de SEG :
Nous acceptons toutes sortes de contributions ; veuillez consulter CONTRIBUTING.md.
xarray
Alan Richardson a écrit un excellent petit outil pour utiliser xarray avec des fichiers segy, dont il fait la démonstration dans ce cahier.
De petits fichiers au format SEG-Y sont inclus dans le référentiel à des fins de test. Les données n'ont aucun sens et sont conçues pour être prévisibles, et elles sont reproductibles en utilisant segyio. Le fichier de tests se trouve dans le répertoire test-data. Pour reproduire le fichier de données, construisez segyio et exécutez le programme de test make-file.py
, make-ps-file.py
et make-rotated-copies.py
en tant que tel :
python examples / make - file . py small . sgy 50 1 6 20 25
python examples / make - ps - file . py small - ps . sgy 10 1 5 1 4 1 3
python examples / make - rotated - copies . py small . sgy
Le fichier small-lsb.sgy a été créé en exécutant le programme flip-endianness. Ce programme est inclus dans l'arborescence des sources de segyio, mais ne fait pas partie du package, et n'est pas destiné à la distribution et à l'installation, uniquement à la reproduction de fichiers de test.
Les fichiers sismiques unix small.su et small-lsb.su ont été créés par les commandes suivantes :
segyread tape=small.sgy ns=50 remap=tracr,cdp byte=189l,193l conv=1 format=1
> small-lsb.su
suswapbytes < small.su > small-lsb.su
Si vous disposez de petits fichiers de données avec une licence gratuite, n'hésitez pas à les soumettre au projet !
Importez des bibliothèques utiles :
import segyio
import numpy as np
from shutil import copyfile
Ouvrez le fichier segy et inspectez-le :
filename = 'name_of_your_file.sgy'
with segyio . open ( filename ) as segyfile :
# Memory map file for faster reading (especially if file is big...)
segyfile . mmap ()
# Print binary header info
print ( segyfile . bin )
print ( segyfile . bin [ segyio . BinField . Traces ])
# Read headerword inline for trace 10
print ( segyfile . header [ 10 ][ segyio . TraceField . INLINE_3D ])
# Print inline and crossline axis
print ( segyfile . xlines )
print ( segyfile . ilines )
Lisez le cube de données post-pile contenu dans le fichier segy :
# Read data along first xline
data = segyfile . xline [ segyfile . xlines [ 1 ]]
# Read data along last iline
data = segyfile . iline [ segyfile . ilines [ - 1 ]]
# Read data along 100th time slice
data = segyfile . depth_slice [ 100 ]
# Read data cube
data = segyio . tools . cube ( filename )
Lisez le cube de données pré-empilée contenu dans le fichier segy :
filename = 'name_of_your_prestack_file.sgy'
with segyio . open ( filename ) as segyfile :
# Print offsets
print ( segyfile . offset )
# Read data along first iline and offset 100: data [nxl x nt]
data = segyfile . iline [ 0 , 100 ]
# Read data along first iline and all offsets gath: data [noff x nxl x nt]
data = np . asarray ([ np . copy ( x ) for x in segyfile . iline [ 0 : 1 , :]])
# Read data along first 5 ilines and all offsets gath: data [noff nil x nxl x nt]
data = np . asarray ([ np . copy ( x ) for x in segyfile . iline [ 0 : 5 , :]])
# Read data along first xline and all offsets gath: data [noff x nil x nt]
data = np . asarray ([ np . copy ( x ) for x in segyfile . xline [ 0 : 1 , :]])
Lire et comprendre des données assez « non structurées » (par exemple, des données triées dans des regroupements de prises de vue courants) :
filename = 'name_of_your_prestack_file.sgy'
with segyio . open ( filename , ignore_geometry = True ) as segyfile :
segyfile . mmap ()
# Extract header word for all traces
sourceX = segyfile . attributes ( segyio . TraceField . SourceX )[:]
# Scatter plot sources and receivers color-coded on their number
plt . figure ()
sourceY = segyfile . attributes ( segyio . TraceField . SourceY )[:]
nsum = segyfile . attributes ( segyio . TraceField . NSummedTraces )[:]
plt . scatter ( sourceX , sourceY , c = nsum , edgecolor = 'none' )
groupX = segyfile . attributes ( segyio . TraceField . GroupX )[:]
groupY = segyfile . attributes ( segyio . TraceField . GroupY )[:]
nstack = segyfile . attributes ( segyio . TraceField . NStackedTraces )[:]
plt . scatter ( groupX , groupY , c = nstack , edgecolor = 'none' )
Écrivez le fichier segy en utilisant le même en-tête d'un autre fichier mais multipliez les données par *2
input_file = 'name_of_your_input_file.sgy'
output_file = 'name_of_your_output_file.sgy'
copyfile ( input_file , output_file )
with segyio . open ( output_file , "r+" ) as src :
# multiply data by 2
for i in src . ilines :
src . iline [ i ] = 2 * src . iline [ i ]
Créer un fichier segy à partir de sctrach
filename='name_of_your_file.sgy'
% Inspect segy
Segy_struct=SegySpec(filename,189,193,1);
% Read headerword inline for each trace
Segy.get_header(filename,'Inline3D')
%Read data along first xline
data= Segy.readCrossLine(Segy_struct,Segy_struct.crossline_indexes(1));
%Read cube
data=Segy.get_cube(Segy_struct);
%Write segy, use same header but multiply data by *2
input_file='input_file.sgy';
output_file='output_file.sgy';
copyfile(input_file,output_file)
data = Segy.get_traces(input_file);
data1 = 2*data;
Segy.put_traces(output_file, data1);
Très souvent, des problèmes surviennent lorsque quelqu'un a des difficultés avec les performances de segyio, en particulier lors de la création de nouveaux fichiers. Le coupable est souvent ce code :
with segyio.create('new.sgy', spec) as dst:
dst.header = headers
Le code lui-même est parfaitement correct, mais il a un comportement subtil sur certains systèmes lorsque le fichier est nouvellement créé : il effectue de nombreuses écritures dispersées dans un fichier fragmenté. Cela peut être rapide ou lent, en grande partie selon le système de fichiers.
Réécrivez la boucle pour écrire dans le fichier de manière contiguë :
with segyio.create('new.sgy', spec) as dst:
for i in range(spec.tracecount):
dst.header[i] = headers[i]
dst.trace[i] = traces[i]
Si le fichier est une copie modifiée d'un autre fichier, sans modifier la longueur des traces, il est souvent plus rapide (et plus facile !) de copier d'abord le fichier sans segyio, puis d'utiliser segyio pour modifier la copie sur place :
shutil.copyfile(srcfile, dstfile)
with segyio.open(dstfile) as f:
f.header = headers
Cette erreur apparaît lorsque le chargeur ne trouve pas la bibliothèque principale segyio. Si vous avez explicitement défini le préfixe d'installation (avec -DCMAKE_INSTALL_PREFIX
), vous devez configurer votre chargeur pour qu'il recherche également ce préfixe, soit avec un fichier ld.conf.d
, soit avec la variable LD_LIBRARY_PATH
.
Si vous n'avez pas défini CMAKE_INSTALL_PREFIX
, cmake s'installera par défaut sur /usr/local
, ce que votre chargeur connaît généralement. Sur les systèmes basés sur Debian, la bibliothèque est souvent installée dans /usr/local/lib
, ce que le chargeur n'est peut-être pas au courant. Voir le numéro 239.
sudo ldconfig
fait souvent l'affaire)-DCMAKE_INSTALL_LIBDIR=lib64
Cette exception est levée lorsque segyio tente d'ouvrir le fichier en mode strict, en supposant que le fichier est un volume 3D ordinaire et trié. Si le fichier n’est qu’une collection de traces dans un ordre arbitraire, cela échouera.
Vérifiez si les paramètres d'entrée segyio.open iline
et xline
sont corrects pour le fichier actuel. Segyio prend également en charge les fichiers qui ne sont qu'une collection de traces, mais il faut lui dire que vous pouvez le faire. Passez strict = False
ou ignore_geometry = True
à segyio.open
pour autoriser ou forcer le mode non structuré respectivement. Veuillez noter que les fonctionnalités f.iline
et similaires sont désormais désactivées et généreront des erreurs.
Segyio a été initialement écrit et est maintenu par Equinor ASA comme moyen gratuit, simple et facile à utiliser d'interagir avec des données sismiques qui peuvent être adaptées à nos besoins, et comme contribution à la communauté du logiciel libre.