Creazione di DEM su scala nanometrica con GDAL


14

Forse una domanda un po 'strana, ma lascia che ti dia una breve spiegazione dello sfondo prima delle mie attuali domande:

La microscopia a forza atomica (AFM) è un metodo che, in breve (e per mia conoscenza limitata), consente ai ricercatori di scansionare aree su micro e nanoscala. Funziona "scansionando" un'area usando una specie di sonda. Più è difficile da spiegare per me, poiché non ne ho una reale comprensione. Quello che so e ciò che ha scatenato la mia curiosità è che il risultato è in realtà una "griglia" di valori di "altezza" (una matrice di valori 512x512 che descrivono l'altezza della sonda in quel punto).

Poi ho pensato: beh, a parte la scala, questo è in realtà un modello di elevazione digitale! E questo significa che se riuscissi a creare un file DEM come compreso dagli strumenti GIS, avrei potuto applicare l'analisi GIS ad esso!

Così com'è, il mio altro significato funziona in un laboratorio che ha una macchina AFM e la sta usando in uno dei suoi progetti. Ho ottenuto alcuni file di scansione da lei, e sono riuscito, usando Python (struct e numpy), ad analizzare questi file binari e quello che ho ora è un array intorpidito di dimensioni 512x512 riempito con valori int16.

Ciò su cui sto pianificando in seguito, e di ciò di cui ho bisogno di aiuto, è la parte "mapping su un DEM corretto". Ho una certa conoscenza di DEMS, ma quando si tratta della loro generazione reale sono abbastanza nuovo.

Quello che sto pensando è che devo georeferenziare i miei dati in qualche modo, e per questo ho bisogno di un sistema di coordinate personalizzato (planare). Immagino che il mio sistema di coordinate userebbe micro o nano-metri come unità. Quindi si tratta solo di trovare la dimensione dell'area scansionata con l'AFM (credo che sia da qualche parte nel file binario, supponiamo che sia noto).

aggiornamento : ho anche diverse scansioni con risoluzioni diverse, ma della stessa area. Ad esempio, ho queste informazioni su due scansioni:

immagine più grande:

Scan Size: 51443.5 nm
X Offset: 0 nm
Y Offset: 0 nm

immagine più piccola (dettaglio):

Scan Size: 5907.44 nm
X Offset: 8776.47 nm
Y Offset: 1486.78 nm

Quello che io ', pensando è che il mio sistema di coordinate personalizzato dovrebbe avere un'origine in 0,0 e per l'immagine più grande assegnerò al pixel 0,0 il valore delle coordinate di (0,0) e al pixel 512.512 il valore delle coordinate (51443.5, 51443.5 ) (Indovina che ottieni l'immagine per gli altri punti necessari).

Quindi, l'immagine più grande mapperebbe pixel (0,0) a (8776,47, 1486,78) e (512,512) a (8776,47 + 5907,44, 1486,78 + 5907,44)

La prima domanda è quindi : come posso creare un def proj4 per un tale sistema di coordinate? Vale a dire: come posso assegnare queste "coordinate del mondo reale" al mio sistema di coordinate personalizzato (o, se seguo il suggerimento dei whubers e usando un sistema di coordinate locale e mentendo sulle unità (cioè trattando i miei nanometri come chilometri)

Quindi devo trasferire il mio numpy array bidimensionale in un formato di file DEM georeferenziato. Stavo pensando di usare GDAL (o, piuttosto, i binding Python).

La seconda domanda è quindi : come posso creare un DEM georeferenziato da dati "arbitrari" come il mio? Preferibilmente in Python e usando librerie open source.

Il resto dovrebbe quindi essere abbastanza semplice, solo una questione di utilizzo dei giusti strumenti di analisi. Il problema è che questo compito è guidato dalla mia stessa curiosità, quindi non sono del tutto sicuro di cosa dovrei effettivamente fare con un DEM su scala nanometrica. Questo implora il

3a domanda : cosa fare con un DEM su scala nanometrica? Che tipo di analisi può essere fatta, quali sono gli strumenti appropriati per l'analisi DEM e infine: è possibile creare una mappa con sfumature e linee di contorno da questi dati? :)

Accolgo con favore tutti i suggerimenti e i suggerimenti, ma tieni presente che sto cercando alternative gratuite, in quanto si tratta di un progetto rigorosamente basato su hobby, senza budget o finanziamenti (e non ho accesso a nessuna applicazione GIS lisenziata). Inoltre, so che Bruker, la società che vende queste macchine AFM, spedisce alcuni software, ma utilizzarlo non sarebbe divertente.


Divertente e interessante! Puoi pubblicare alcuni dati di esempio? È necessario avere una scala nanometrica sulla proiezione? Pensare che forse è più facile ridimensionare, anche se è "barare" un po '. A proposito, immagino che tu possa fare molta strada con GDAL / ogr, anche se il problema della proiezione dovrà ancora essere affrontato. gdal.org/gdal_grid.html
alexanno

Grazie! Immagino che questo sia più un commento che una risposta. Per quanto riguarda la scala dei nanometri, direi che qualunque cosa funzioni alla grande, ma una vera peojection su nanoscala sarebbe la più bella. Quando si tratta di dati di esempio, dovrò verificare se ci sono alcune restrizioni, ma fondamentalmente è una matrice di 2 dim di valori int16.
Atlefren,

3
Perché avresti bisogno dei parametri proj4? Non trasferirai questi dati in un altro sistema di coordinate (specialmente geografico). Imho dovresti essere in grado di fare tutte le tue analisi senza alcun sistema di coordinate. Cosa capisci con un DEM? Esistono diversi tipi come superfici triangolate (ad es. Eseguire una triangolazione delauny) o mappe raster (questa è già disponibile). Questo ovviamente dipende fortemente dal software di analisi. Ovviamente puoi creare altre mappe se sono necessarie come output per comprendere il probe. Puoi dare un'occhiata a code.google.com/p/mtex per l'analisi del grano.
mistapink,

3
Il motivo per cui (penso) ho bisogno di un CRS è questo: se creo semplicemente, diciamo un GeoTIFF senza assegnare un CRS, l'unità di misura sarà pixel. E se volessi misurare le distanze? E se avessi due scansioni AFM e sapessi come si relazionano tra loro (in termini di scala e offset da un certo punto). L'assegnazione di un CRS faciliterebbe la visualizzazione di più scansioni contemporaneamente
atlefren,

1
Di solito mi occupo di tali dati impostando un sistema di coordinate locale (con un'origine coincidente con l'origine dell'immagine) e "mentendo" sulle unità. Ad esempio, è possibile stabilire che le unità sono chilometri quando sono realmente nanometri, il che rende facile la conversione mentale avanti e indietro. Ovviamente non eseguirai alcuna riproiezione, quindi non è un problema. L'impostazione di questo sistema di coordinate è la stessa del georeferenziamento di qualsiasi DEM; può essere semplice come creare un file mondiale non ruotato.
whuber

Risposte:


4

Beh, sembra che ho risolto i problemi 1 e 2 almeno. Codice sorgente completo su github , ma alcune spiegazioni qui:

Per un CRS personalizzato ho deciso (per suggerimento Whubers) di "imbrogliare" e usare i misuratori come unità. Ho trovato un "crs locale" su apatialreference.org ( SR-ORG: 6707 ):

LOCAL_CS["Non-Earth (Meter)",
    LOCAL_DATUM["Local Datum",0],
    UNIT["Meter",1.0],
    AXIS["X",NORTH],
    AXIS["Y",EAST]]

Usando Python e GDAL questo è abbastanza facile da leggere:

def get_coordsys():
    #load our custom crs
    prj_text = open("coordsys.wkt", 'r').read()
    srs = osr.SpatialReference()
    if srs.ImportFromWkt(prj_text):
        raise ValueError("Error importing PRJ information" )

    return srs

Inoltre, l'ottimizzazione di un DEM con GDAL è stata piuttosto semplice (ho finito con un geo-tiff a banda singola). La riga parser.read_layer (0) restituisce la mia matrice 512x512 precedentemente descritta.

def create_dem(afmfile, outfile):

    #parse the afm data
    parser = AFMParser(afmfile)

    #flip to account for the fact that the matrix is top-left, but gdal is bottom-left
    data = flipud(parser.read_layer(0))

    driver = gdal.GetDriverByName("GTiff")
    dst_ds = driver.Create(
        outfile,
        data.shape[1],
        data.shape[0],
        1 ,
        gdal.GDT_Int16 ,
    )

    dst_ds.SetGeoTransform(get_transform(parser, data))
    dst_ds.SetProjection(get_coordsys().ExportToWkt())
    dst_ds.GetRasterBand(1).WriteArray(data)
    dst_ds = None

La parte più terribile è stata capire come "georeferenziare" correttamente il mio file, ho finito per usare SetGeoTransform , ottenendo i parametri così:

def get_transform(parser, data):
    #calculate dims
    scan_size, x_offset, y_offset = parser.get_size()
    x_size = data.shape[0]
    y_size = data.shape[1]
    x_res = scan_size / x_size
    y_res = scan_size / y_size

    #set the transform (offsets doesn't seem to work the way I think)
    #top left x, w-e pixel resolution, rotation, 0 if image is "north up", top left y, rotation, 0 if image is "north up", n-s pixel resolution
    return [0, x_res, 0, 0, 0, y_res]

Quest'ultima parte è probabilmente quella di cui non sono più sicuro, quello che stavo davvero cercando era qualcosa di linea * gdal_transform -ullr *, ma non sono riuscito a trovare il modo di farlo programmaticamente.

Sono in grado di aprire il mio GeoTIFF in Qgis e visualizzarlo (e confrontarlo visivamente con il risultato del programma Bruker sembra corretto), ma non ho davvero risposto alla mia domanda 3; cosa fare con questi dati. Quindi, qui sono aperto per suggerimenti!


Una sfida interessante potrebbe essere quella di confrontare le distanze sulla DEM con le distanze tra i luoghi del globo per dare agli spettatori un'idea di quanto sia piccola la nanoscala. Ad esempio htwins.net/scale2
blah238,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.