Accesso ai dati in nested structs

di il
15 risposte

Accesso ai dati in nested structs

Ciao a tutti,
ho un problema con l'accesso ai dati di un file '.mat'. Il file contiene dei segnali EEG prelevati da 38 soggetti, in due condizioni differenti. Esso è così costituito: ci sono 38 elementi 1x1, contenenti ciascuno due sottostrutture ('com' & 'unc') con un numero diverso di oggetti. Per essere precisi, ogni oggetto corrisponde ad una matrice di 31 righe ma numero di colonne variabile. Inoltre, considerando ad esempio la sottostruttura 'com' -> gli indici dispari sono i segnali di 'riferimento', mentre quelli pari sono quelli propri dell'attività di interesse.
Quello che dovrei fare io è analizzare per ogni soggetto, le due sottostrutture e confrontare riferimento ed idea (da cui calcolare dei valori tramite una funzione in MatLab). Ho spezzettato inizialmente il problema, scrivendo il codice per un oggetto nelle due diverse condizioni: il problema è quando cerco di estendere il programma all'intera sottostruttura. Avevo pensato di accedervi tramite un while-loop e porre come condizione l'indice pari o dispari. Quando però lo faccio in Matlab è come se non mi leggesse la condizione:
'while n>0
if mod(n,2)== 0
Com_idea= subj_01.com(n).com;
else
Com_ref = subj_01.com(n).com;
end
end'
Qualcuno sa aiutarmi?

15 Risposte

  • Re: Accesso ai dati in nested structs

    Risposta standard:
    pubblica un esempio concreto dei dati di input in modo che si possa provare ad eseguire il codice.
  • Re: Accesso ai dati in nested structs

    Volevo spiegare bene il problema perché pensavo non fosse chiaro.
    Nel mio file 'subj_01' ho una struct 1x1 avente un campo 'com' (1x30) ed uno 'unc' (1x22).
    Organizzazione subj_01
    Organizzazione subj_01

    Ciascun campo ha all'interno n matrici quanto le colonne del campo stesso: ogni matrice ha poi 31 righe fisse e il numero di colonne variabile. Inoltre, le matrici associate agli indici dispari di 'com' (quindi la 1,3,5 etc) sono i miei dati di riferimento che mi serviranno successivamente; quelle associate agli indici pari (quindi la 2,4,6 etc) sono dell'attività che devo confrontare con il riferimento.
    Gli indici, però, vengono considerati a coppie perché riferite ad uno stesso oggetto mostrato al paziente in due condizioni diverse.
    Esempio pratico:
    Considero sempre la struct 'com' (1x30). In totale, il numero di oggetti è pari a 15 per via del fatto che ho sia l'attività che riferimento.
    Se io considero il primo oggetto: io ho che la prima matrice (perché indice dispari) è il riferimento e la seconda (indice pari) è la mia idea.


    Per praticità consideriamo che la mia com sia (1x4) così fatta:
    1. (3x5) [1 4 5 9 3; 4 9 53 46 10; 98 0.2 45 2.7 22];
    2. (3x8) [2 3 4 1 6 7 34 0.9; 1 0.5 6 98 12 6.5 85 16; 22 1.7 86 3.4 7.4 21 5.2 4.6];
    3. (3x4) [32 5 7.9 1; 12 3.6 2.7 46; 32 4.8 7.9 56];
    4. (3x7) [3.5 0.7 15 2.9 1.1 4.6 11; 8.2 4.6 5 0.6 6 11 7.4; 22 1.8 7.4 61 3.3 44 7.8];

    Quello che vorrei fare è questo:
    leggo da com i dati -> se io ho l'indice 1 so che è dispari ed è il mio riferimento quindi il codice del riferimento; se ho l'indice pari quindi 2, ad esempio, faccio eseguire il codice relativo all'attività di analisi. Solo che scrivendolo con il while non ottengo il risultato pensato.
    Spero che adesso sia un po' più chiaro..
  • Re: Accesso ai dati in nested structs

    Le immagini sono illeggibili e la descrizione non è affatto chiara.
    In totale, il numero di oggetti è pari a 15 per via del fatto che ho sia l'attività che riferimento.
    Considerando che scrivi di avere due serie di dati (attività e riferimento) ci si aspetterebbe un numero di oggetti pari, non dispari (15).
    faccio eseguire il codice relativo all'attività di analisi. Solo che scrivendolo con il while non ottengo il risultato pensato
    Pubblica il codice, i dati di input ed il risultato atteso
  • Re: Accesso ai dati in nested structs

    Sono riuscita a risolvere questo problema. Adesso però ne è subentrato un altro perché il file per cui devo utilizzare il codice scritto è organizzato così -> 'EEGrecordings.mat' -> 38 sottostrutture nominate da 'S_01' fino a 'S_38' -> e poi le ulteriori sotto strutture. Come faccio a leggere le strutture da 'S_01' a 'S_38'? Avevo pensato di scriverlo così per evitare di utilizzare la funzione eval ma non legge la doppia cifra (es. Non trova la S_01 ma la S_ 1'):
    [for idx=1:38
        data=EEGrecordings.(sprintf('S_%2d',num2str(idx,2)));
    end
        ]
  • Re: Accesso ai dati in nested structs

    Nella definizione del formato, devi specificare il numero "0", inoltre, dal momento che nel formato specifiche "d" (un intero) non devi usare la funzione "num2str" per convertire il numero (idx) in una stringa:
    
    for idx=1:38
        data=EEGrecordings.(sprintf('S_%02d',idx));
    end
    
  • Re: Accesso ai dati in nested structs

    Perfetto, ho capito! E se invece non fossero in numero progressivo ma avessero solo la parte 'S_' in comune?
  • Re: Accesso ai dati in nested structs

    In che senso?
    Quali potrebbero essere i nomi?
  • Re: Accesso ai dati in nested structs

    Praticamente sono:
    S_01
    S_02
    S_03
    S_05
    S_06
    S_07
    S_08
    S_09
    S_10
    S_11
    S_12
    S_13
    S_14
    S_15
    S_16
    S_17
    S_18
    S_19
    S_20
    S_21
    S_22
    S_23
    S_24
    S_25
    S_26
    S_27
    S_28
    S_29
    S_30
    S_31
    S_32
    S_33
    S_34
    S_35
    S_36
    S_37
    S_39
    S_40
  • Re: Accesso ai dati in nested structs

    Non capisco.
    Manca la parte "EEGrecordings"?
    Nella lista sembrano mancare alcuni elementi (ad esempio S_04, S_38).
    Se i vari "S_" sono strutture, la definizione "dinamica" dei nomi si applica solo ai campi delle strutture, non al nome delle strutture
  • Re: Accesso ai dati in nested structs

    Scusami, sono stata poco chiara e non sono molto pratica in MatLab come hai potuto notare.
    L'elenco che ho inviato sono tutte le sottostrutture del file 'EEGrecordings.mat'.
    Quello che mi chiedo io è se c'è un modo per leggere ogni sottostruttura EEGrecordings.S_xx dato che la numerazione anche se crescente non è consecutiva perché, appunto, mancano la S_04 e la S_38
  • Re: Accesso ai dati in nested structs

    Per verificare se una struct ha un determinato campo puoi usare la funzione

    Nell'esempio che segue, nel primo loop viene creata una struct con dei campi con numeri dispari nel nome, nel secondo si verificano tutti i numeri che possono comparire nel nome; se il campo esiste, il suo valore viene stampato, se non esiste viene stampato un messaggio di errore che segnala che il campo non esiste
    
    % Create some fields
    for idx=1:2:10
        EEGrecordings.(sprintf('S_%02d',idx))=idx*123
    end
    
    % Loop over the struct
    for idx=1:10
        if(isfield(EEGrecordings,sprintf('S_%02d',idx)))
            EEGrecordings.(sprintf('S_%02d',idx))
        else
            sprintf('S_%02d is not a field of EEGrecordings',idx)
        end
    end
    ]
  • Re: Accesso ai dati in nested structs

    Okay, credo di aver capito. Grazie del tuo aiuto davvero!
  • Re: Accesso ai dati in nested structs

    Ho scritto il codice per interno però mi runna praticamente all'infinito. Cioè il file 'EEGrecordings' è di circa 850MB però penso sia proprio un problema di codice:
    [load EEGrecordings;
    
    %parametri di riferimento da specificare
    fc = 500;
    num_ch = 31;
    
    
    
    for idx=1:38
        if(isfield(EEGrecordings,sprintf('S_%02d',idx)))
            data(idx)=EEGrecordings.(sprintf('S_%02d',idx));
    results(38)=struct('rP_com',[],'TRP_com',[],'rP_uncom',[],'TRP_uncom',[]);
    
    num_com = size(data(idx).com,2)/2;
    num_uncom = size(data(idx).unc,2)/2;
    
    %creo delle matrici di zeri che andrà a sovrascrivere
    rP_com = zeros(31,num_com,6);
    TRP_com = zeros(31,num_com,6);
    rP_uncom = zeros(31,num_uncom,6);
    TRP_uncom = zeros(31,num_uncom,6);
    
    
    
    for j=1:num_com
        for k=1:num_uncom
          Obj_ref_com = data(idx).com(j*2-1).com;
          Obj_idea_com= data(idx).com(j*2).com;
          Obj_ref_unc = data(idx).unc(k*2-1).unc;
          Obj_idea_unc = data(idx).unc(k*2).unc;
        
        for i=1:num_ch
            [f_ref_com,PSD_ref_com] = est_PSD(Obj_ref_com(i,:),fc);
            aP_ref1_com = sum(PSD_ref_com(f_ref_com >= 0 & f_ref_com<4));
            aP_ref2_com = sum(PSD_ref_com(f_ref_com >= 4 & f_ref_com<7.5));
            aP_ref3_com = sum(PSD_ref_com(f_ref_com >= 7.5 & f_ref_com<12.5));
            aP_ref4_com = sum(PSD_ref_com(f_ref_com >= 12.5 & f_ref_com<30));
            aP_ref5_com = sum(PSD_ref_com(f_ref_com >= 30 & f_ref_com<45));
            aP_ref6_com = sum(PSD_ref_com(f_ref_com >= 45 & f_ref_com<250));
            
            [f_ref_unc,PSD_ref_unc] = est_PSD(Obj_ref_unc(i,:),fc);
            aP_ref1_unc = sum(PSD_ref_unc(f_ref_unc >= 0 & f_ref_unc<4));
            aP_ref2_unc = sum(PSD_ref_unc(f_ref_unc >= 4 & f_ref_unc<7.5));
            aP_ref3_unc = sum(PSD_ref_unc(f_ref_unc >= 7.5 & f_ref_unc<12.5));
            aP_ref4_unc = sum(PSD_ref_unc(f_ref_unc >= 12.5 & f_ref_unc<30));
            aP_ref5_unc = sum(PSD_ref_unc(f_ref_unc >= 30 & f_ref_unc<45));
            aP_ref6_unc = sum(PSD_ref_unc(f_ref_unc >= 45 & f_ref_unc<250));
            
            [f_idea_com,PSD_idea_com]= est_PSD(Obj_idea_com(i,:),fc);
            aP_idea1_com = sum(PSD_idea_com(f_idea_com >= 0 & f_idea_com <4));
            aP_idea2_com = sum(PSD_idea_com(f_idea_com >= 4 & f_idea_com< 7.5));
            aP_idea3_com = sum(PSD_idea_com(f_idea_com>= 7.5 & f_idea_com<12.5));
            aP_idea4_com = sum(PSD_idea_com(f_idea_com >= 12.5 & f_idea_com<30));
            aP_idea5_com = sum(PSD_idea_com(f_idea_com>= 30 & f_idea_com<45));
            aP_idea6_com = sum(PSD_idea_com(f_idea_com >= 45 & f_idea_com<250));
            
            [f_idea_unc,PSD_idea_unc]= est_PSD(Obj_idea_unc(i,:),fc);
            aP_idea1_unc = sum(PSD_idea_unc(f_idea_unc >= 0 & f_idea_unc <4));
            aP_idea2_unc = sum(PSD_idea_unc(f_idea_unc >= 4 & f_idea_unc< 7.5));
            aP_idea3_unc = sum(PSD_idea_unc(f_idea_unc>= 7.5 & f_idea_unc<12.5));
            aP_idea4_unc = sum(PSD_idea_unc(f_idea_unc >= 12.5 & f_idea_unc<30));
            aP_idea5_unc = sum(PSD_idea_unc(f_idea_unc>= 30 & f_idea_unc <45));
            aP_idea6_unc = sum(PSD_idea_unc(f_idea_unc >= 45 & f_idea_unc <250));
            
            results(idx).rP_com(i,j,1) = 100*aP_idea1_com/sum(PSD_idea_com);
            results(idx).rP_com(i,j,2) = 100*aP_idea2_com/sum(PSD_idea_com);
            results(idx).rP_com(i,j,3) = 100*aP_idea3_com/sum(PSD_idea_com);
            results(idx).rP_com(i,j,4) = 100*aP_idea4_com/sum(PSD_idea_com);
            results(idx).rP_com(i,j,5) = 100*aP_idea5_com/sum(PSD_idea_com);
            results(idx).rP_com(i,j,6) = 100*aP_idea6_com/sum(PSD_idea_com);
            
            
            results(idx).rP_uncom(i,k,1) = 100*aP_idea1_unc/sum(PSD_idea_unc);
            results(idx).rP_uncom(i,k,2) = 100*aP_idea2_unc/sum(PSD_idea_unc);
            results(idx).rP_uncom(i,k,3) = 100*aP_idea3_unc/sum(PSD_idea_unc);
            results(idx).rP_uncom(i,k,4) = 100*aP_idea4_unc/sum(PSD_idea_unc);
            results(idx).rP_uncom(i,k,5) = 100*aP_idea5_unc/sum(PSD_idea_unc);
            results(idx).rP_uncom(i,k,6) = 100*aP_idea6_unc/sum(PSD_idea_unc);
            
            results(idx).TRP_com(i,j,1) = log10(aP_idea1_com) - log10(aP_ref1_com);
            results(idx).TRP_com(i,j,2) = log10(aP_idea2_com) - log10(aP_ref2_com);
            results(idx).TRP_com(i,j,3) = log10(aP_idea3_com) - log10(aP_ref3_com);
            results(idx).TRP_com(i,j,4) = log10(aP_idea4_com) - log10(aP_ref4_com);
            results(idx).TRP_com(i,j,5) = log10(aP_idea5_com) - log10(aP_ref5_com);
            results(idx).TRP_com(i,j,6) = log10(aP_idea6_com) - log10(aP_ref6_com);
            
            results(idx).TRP_uncom(i,k,1) = log10(aP_idea1_unc) - log10(aP_ref1_unc);
            results(idx).TRP_uncom(i,k,2) = log10(aP_idea2_unc) - log10(aP_ref2_unc);
            results(idx).TRP_uncom(i,k,3) = log10(aP_idea3_unc) - log10(aP_ref3_unc);
            results(idx).TRP_uncom(i,k,4) = log10(aP_idea4_unc) - log10(aP_ref4_unc);
            results(idx).TRP_uncom(i,k,5) = log10(aP_idea5_unc) - log10(aP_ref5_unc);
            results(idx).TRP_uncom(i,k,6) = log10(aP_idea6_unc) - log10(aP_ref6_unc);
        end
      end
    end
    
        else
            idx=idx+1;
        end
    end
    save results.mat results
    ]
  • Re: Accesso ai dati in nested structs

    Difficile dire qualcosa non avendo i dati a disposizione, 850MB sono tanti, ma non tantissimi.
    Una cosa che puoi provre3 a fare è il del codice.

    Usando la funzione puoi analizzare il tempo il tempo di esecuzione del codice per identificare le parti critiche.

    Potresti iniziare con una sola iterazione del loop più esterno, eliminando il loop e settando direttamente idx =1.
Devi accedere o registrarti per scrivere nel forum
15 risposte