Размер структуры в другой структуре в Matlab (R2010a 64-разрядная версия Linux) - PullRequest
3 голосов
/ 04 февраля 2011

Я работаю с Matlab API, который загружает данные из проприетарного формата в ряд структур.Вот пример того, как выглядит набор данных после загрузки файла:

>> Имена полей (data (1))

ans =

'Grid_Point_ID'
'Grid_Point_Latitude'
'Grid_Point_Longitude'
'Grid_Point_Altitude'
'Grid_Point_Mask'
'BT_Data'

>> data (1) .BT_Data

ans =

BT_Data: [1x66 struct]

>> имена полей (data (1) .BT_Data (1))

ans =

'Flags'
'BT_Value_Real'
'BT_Value_Imag'
'Pixel_Radiometric_Accuracy'
'Incidence_Angle'
'Azimuth_Angle'
'Faraday_Rotation_Angle'
'Geometric_Rotation_Angle'
'Snapshot_ID_of_Pixel'
'Footprint_Axis1'
'Footprint_Axis2'

Я хочу перебрать все data(i).BT_Data(j).У меня уже есть длина data в порядке, но я не могу получить размер / длину BT_Data (которая варьируется для каждого data(i)):

>> length (data (1) .BT_Data)

ans =

 1

>> size (data (1) .BT_Data)

ans =

 1     1

Мой ожидаемый результат здесь ans = 66 (или эквивалентный массив для size()).

Я не очень знаком с форматом данных структуры, который может быть частью моей борьбы.Но length(data) работал нормально, поэтому я запутался, почему он не будет работать на BT_Data (я также пробовал BT_Data(:)).

Наиболее релевантный предыдущий ответ, который я могу найти, это 1757250 , но я не мог заставить его работать (я думаю, что это не применимо здесь).Спасибо за любую информацию, которую вы можете предоставить.

------ РЕДАКТИРОВАТЬ ------

Вот еще немного понимания того, как я должен использовать API, чтобы даже добраться до точки, где я нахожусьat:

>> system ('ln -sf /opt/rwapi-matlab/lib/rwapi/smos/config/xml_rw_api.usr_conf.xml.');
setenv ('XML_RW_API_HOME',' / opt / rwapi-matlab / lib / rwapi ');
путь (путь,' / opt / rwapi-matlab ');

>> prod = RWAPI.product (' SM_OPEB_MIR_SCLF1C_20110202T236110110110641102102641101)

Array SMOS Matlab Interface версия 1.4
(c) 2010 Array Systems Computing Inc. из Канады (http://www.array.ca)
Для распространения или модификации этого программного обеспечения требуется письменное разрешение от Array

prod =

RWAPI.product handle
Package: RWAPI

Properties:
     filename: 'SM_OPEB_MIR_SCLF1C_20110202T013659_20110202T014642_346_060_1'
       header: [1x1 struct]
xml_datablock: []

Методы, события, суперклассы

>> data = prod.dataset (2)

data =

RWAPI.datasetобрабатывать без свойств. Пакет: RWAPI

Методы, события, суперклассы

>> data (1)

ans =

       Grid_Point_ID: 251721
 Grid_Point_Latitude: 25.5000
Grid_Point_Longitude: -102.2590
 Grid_Point_Altitude: 1.4714e+03
     Grid_Point_Mask: 2
             BT_Data: [1x66 struct]

>>данные(1) .BT_Data

ans =

BT_Data: [1x66 struct]

>> data (1) .BT_Data (1)

ans =

                     Flags: 6229
             BT_Value_Real: 262.5275
             BT_Value_Imag: 0
Pixel_Radiometric_Accuracy: 6160
           Incidence_Angle: 31966
             Azimuth_Angle: 10299
    Faraday_Rotation_Angle: 65277
  Geometric_Rotation_Angle: 58605
      Snapshot_ID_of_Pixel: 65752530
           Footprint_Axis1: 19649
           Footprint_Axis2: 14625

>> whos
Имя Размер Байты Атрибуты класса

и 1x1 1 логический
данные 1x19091 112 RWAPI.dataset
prod 1x2 112 RWAPI.product

Ответы [ 3 ]

2 голосов
/ 04 февраля 2011

Я нашел обходной путь, хотя он не очень удовлетворяет:

>> a = data (1) .BT_Data

a =

BT_Data: [1x66 struct]

>> длина (a.BT_Data)

ans =

66

Я отмечу это как ответ на данный момент, потому что я сомневаюсь, что будет какой-то другой «правильный» способ сделать это. Ответ Эндрю действительно обострил проблему (и почему этот обходной путь работает).

2 голосов
/ 04 февраля 2011

Хорошо, я действительно подозреваю, что это странность в переопределенном методе subsref в этих классах RWAPI.Я смог воспроизвести все ваше наблюдаемое поведение, определив класс со слегка патологическим подреф.

classdef stupidref
    %STUPIDREF Reproduce odd indexing behavior that jpatton saw. Buggy.
    properties
        BT_Data = repmat(struct('foo',42, 'bar',42), [1 66]);
    end
    methods
        function B = subsref(A,S)
            s = S(1);
            subs = s.subs;
            chain = S(2:end);

            switch s.type
                case '()'
                    B = builtin( 'subsref', A, s );
                    if ~isempty(chain)
                        B = subsref(B, chain);
                    end

                case '.'
                    % Non-standard behavior!
                    if ~isempty(chain) && isequal(chain(1).type, '()')
                        B = subsref(A.(s.subs), chain);
                    else
                        B = struct(s.subs, A.(s.subs));
                    end
            end
        end
    end
end

Это согласуется со странной разницей между data(1).BT_Data и fieldnames(data(1).BT_Data(1)) и завершением табуляции, котороемногократно добавляет ".BT_Data".

>> data = stupidref;
>> data(1).BT_Data
ans = 
    BT_Data: [1x66 struct]
>> fieldnames(data(1).BT_Data)
ans = 
    'BT_Data'
>> fieldnames(data(1).BT_Data(1))
ans = 
    'foo'
    'bar'
>> length(data(1).BT_Data)
ans =
     1
>> data(1).BT_Data.BT_Data.BT_Data.BT_Data.BT_Data.BT_Data % produced by tab-completion
ans = 
    BT_Data: [1x66 struct]
>> 

Ваш обходной путь хорош - после того, как вы позвоните a = data(1).BT_Data, у вас будет нормальная структура, и нестандартный подреф уже не существует.Вы можете получить тот же эффект в одной строке с getfield.

>> btdata = getfield(data(1).BT_Data, 'BT_Data')
btdata = 
1x66 struct array with fields:
    foo
    bar

Я бы сообщил об этом как возможной ошибке авторам библиотеки RWAPI.

Не стесняйтесь просто редактироватьэтот код в вашем собственном обходном ответе;на самом деле это не столько ответ, сколько поддержка диагностики.

1 голос
/ 04 февраля 2011

Некоторые из ваших результатов кажутся противоречивыми.Для начала, если бы поле BT_Data содержало структурный массив размером 1 на 66, я бы ожидал, что результат будет выглядеть так:

>> data(1).BT_Data

ans =

1x66 struct array with fields:
     Flags
     ...    %# etc.

Тот факт, что вы видите это:

>> data(1).BT_Data

ans =

BT_Data: [1x66 struct]

подсказывает мне, что BT_Data на самом деле является структурой 1 на 1 с одним полем, называемым BT_Data, а , что поле содержит структурный массив 1 на 66.Это объясняет, что вы видите, когда получаете длину и размер первого BT_Data (структура 1 на 1).Если дело обстоит именно так, вы должны получить следующие результаты:

>> size(data(1).BT_Data.BT_Data)

ans =

     1     66

Однако это по-прежнему не объясняет вывод, который вы видите, когда вы делаете:

fieldnames(data(1).BT_Data(1))

Это бросает менявыкл.Вы можете проверить, что BT_Data на самом деле является структурой, а не каким-либо другим типом объектов, которые могут иметь различное поведение индексации и отображения, выполнив это:

isstruct(data(1).BT_Data)

И это должно вернуть 1, еслиBT_Data является структурой.

...