1. Пользоваться форумом на планшетах и телефонах стало удобнее благодаря Tapatalk

Чтение из сета - проблема с очередностью.

Тема в разделе "Maya", создана пользователем Юрий., 20 май 2006.

Модераторы: Dark™, Skif
  1. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Добрый всем день.
    Хочу поделиться одним наблюдением и, может быть, разобраться, что же это такое - баг или фича. Сразу оговорюсь, что проблема была мной исследована, её признаки определены. Но решение этой проблемы найдено не было. А посему, за неимением времени на исследования и опыты, было решено обойти эту проблему дополнительными парой срок кода MEL. И ещё: вероятно, уважаемому Решателю было бы интересно прочитать этот пост :) Итак,
    Из определённого текстового файла на вход скрипта поступают данные об имени, номерах и координатах атомов. В скрипте посредством следующих строк они образуют уникальный идентификатор объекта и последовательно заносятся в массив $allaa (в моём случае это joints):
    global string $allaa[];
    global string $bonez[];
    global string $joints;
    string $buffer[]; // токенизированная строка из файла.
    string $buf2=(string) $buffer[2]; // Потребовалась для преобразования имеющихся цифр в этом поле в текст.
    $allaa[size($allaa)]=($buffer[3]+$buffer[5]+$buf2);

    Элементы массива $allaa имеют, как правило, следующий вид: SER111HB, SER112HB, SER11HG, ILE12N, ILE12CA, ILE12C, ARG3H, ARG3HA, ARG31HB, ARG32HB, ARG31HG, ARG32HG, ARG31HD, ARG32HD, ARG3HE, ARG31HH1, ARG32HH1 и так далее, всего порядка 550-и (небольшой кусок белка).

    Затем все эти joints, составляющие содержимое массива $allaa выделяются и помещаются в сет bonez:
    select -cl;
    select $allaa;
    $joints=`sets -n bonez`;
    sets -add $joints $allaa;

    После этого идёт чтение содержимого сета в массив $bonez и передача содержимого этого нового массива в dynexpression для дальнейшей обработки.
    $bonez=`sets -q bonez`;

    И вот тут возникла одна очень неприятная проблема. Как выяснилось, с некоторого момента (с 148-го элемента сета) происходило перемешивание посдедующих элементов. Приведу распечатки работы скрипта. Первая колонка - переменная $allaa, которая использовалась для формирования сета bonez и последовательность элементов этого сета в outliner, последняя колонка - считанная из этого сета переменная $bonez:

    allaa= LYS10N => 143 ... LYS10N
    allaa= LYS10CA => 144 ... LYS10CA
    allaa= LYS10C => 145 ... LYS10C
    allaa= LYS10O => 146 ... LYS10O
    allaa= LYS10CB => 147 ... LYS10CB
    allaa= LYS10CG => 148 ... HIS13CA На этом месте машина перескакивает на 13-й Histidine, вместо того, чтобы продолжать Lysine
    allaa= LYS10CD => 149 ... HIS13C
    allaa= LYS10CE => 150 ... HIS13O
    allaa= LYS10NZ => 151 ... HIS13CB
    allaa= LYS10H => 152 ... HIS13CG
    allaa= LYS10HA => 153 ... HIS13ND1
    allaa= LYS101HB => 154 ... HIS13CD2
    allaa= LYS102HB => 155 ... HIS13CE1
    allaa= LYS101HG => 156 ... HIS13NE2
    allaa= LYS102HG => 157 ... HIS13H
    allaa= LYS101HD => 158 ... HIS13HA
    allaa= LYS102HD => 159 ... HIS131HB
    allaa= LYS101HE => 160 ... HIS132HB
    allaa= LYS102HE => 161 ... HIS13HD1
    allaa= LYS101HZ => 162 ... HIS13HD2
    allaa= LYS102HZ => 163 ... HIS13HE1
    allaa= LYS103HZ => 164 ... HIS13HE2
    allaa= SER11N => 165 ... ILE14N Вслед за 13 His идёт 14 Ile
    allaa= SER11CA => 166 ... ILE14CA
    allaa= SER11C => 167 ... ILE14C
    allaa= SER11O => 168 ... ILE12H
    allaa= SER11CB => 169 ... LYS10CG Но тут он прерывается - скачок назад по сету и чтение 10-го Lysine.
    allaa= SER11OG => 170 ... LYS10CD
    allaa= SER11H => 171 ... LYS10CE
    allaa= SER11HA => 172 ... LYS10NZ
    allaa= SER111HB => 173 ... LYS10H
    allaa= SER112HB => 174 ... LYS10HA
    allaa= SER11HG => 175 ... LYS101HB
    allaa= ILE12N => 176 ... LYS102HB
    allaa= ILE12CA => 177 ... LYS101HG
    allaa= ILE12C => 178 ... LYS102HG
    allaa= ILE12O => 179 ... LYS101HD
    allaa= ILE12CB => 180 ... LYS102HD
    allaa= ILE12CG1 => 181 ... LYS101HE
    allaa= ILE12CG2 => 182 ... LYS102HE
    allaa= ILE12CD1 => 183 ... LYS101HZ
    allaa= ILE12H => 184 ... LYS102HZ
    allaa= ILE12HA => 185 ... LYS103HZ
    allaa= ILE12HB => 186 ... SER11N За 10-м Лизином идёт 11 Serine
    allaa= ILE121HG1 => 187 ... SER11CA

    И такая катавасия продолжается до конца сета!
    Было замечено, что при чтении из файла, в котором было не более 32-х атомов с названиями типа RES1C25 или RES1_intro_1C15 перемешивания не происходило.

    Была предпринята попытка изменить процедуру добавления в сет - не скопом, а последовательно выделяя каждый joint массива $allaa и добавляя его в сет bonez:
    for ($numof==0; $numof<size($allaa); $numof++)
    {
    select -r $allaa[$numof];
    sets -add bonez $allaa[$numof] ;
    }
    Но по непонятной пока причине сет оказывался пуст. На выяснение причин времени не было.

    Промаявшись 2 дня, я всё-таки нашёл решение проблемы, которое, собственно, лежало на поверхности:
    $bonez=$allaa; // !!!! :)

    Но всё-таки осталась некоторая неудовлетворённость (научная жилка :) ) - почему такое происходило? Хуже всего, что мне не удалось установить закономерностей этого перемешивания ни по алфавиту, ни по порядковому померу. Единственное, что приходит в голову, что чтение из сета происходит по "численным" значениям имён его элементов. Но как это проверить я не знаю - увы, биолог :)

    Вот, собственно, и всё. Проблема решена. Вопросы остались. Кто что думает по этому поводу?

    Спасибо, что дочитали до конца.
    С уважением.
    Юра.

    PS. Вся эта штука - скелет. Скелет очень ветвистый. Но ветвиться он начинает задолго до десятого Лизина.
     
  2. Миша Ершов

    Миша Ершов Мастер

    С нами с:
    02.11.2003
    Сообщения:
    1.415
    Симпатии:
    2
    Баллы:
    325
    В этом месте:

    for ($numof==0; $numof<size($allaa); $numof++)
    {
    select -r $allaa[$numof];
    sets -add bonez $allaa[$numof] ;
    }

    сетс оказывался пуст возможно по простой причине - у вас вместо знака присваивания стоит знак "равно". ($numof==0)
    Да и выделение "select -r $allaa[$numof]; " там по-моему совсем не нужно.

    А из первой части сообщения не очень понятны манипуляции с сетсами и зачем они делаются.
     
  3. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Ну, насколько я знаю, в циклах используется именно операторы отношения, а не операторы присвоения, т.е. "==", а не "=".
    Да, select там не нужен (остался, видимо, от предыдущих строк). Но он и не мешает.
    Манипуляции простые - в сет заносятся joints, а потом в другую переменную считывается содержимое сета. Это всё. И на этом шаге возникает перемешивание, т.е. в принимающей переменной объекты идут не в том порядке, в каком они находятся в сете.

    Как я уже писал, описанная проблема не является ПРОБЛЕМОЙ. Это сообщение, скорее, обмен опытом и некоторое предостережение от подобных "открытий" для тех, кто пишет на MEL и, во вторых, некая головоломка для спецов. Если в процессе обсуждения вдруг родится понимание того, что же произошло и что нужно сделать, чтобы этого избежать - я буду считать, что пост достиг цели.
     
  4. Решатель

    Решатель Знаток

    С нами с:
    20.04.2005
    Сообщения:
    1.413
    Симпатии:
    0
    Баллы:
    44
    Михаил прав - в for у вас вместо присваивания идёт сравнение $numof с 0. Это в if() это было бы уместно, а в for() первой идёт инициализация, т.е. присваивание переменной некоего начального значения. А у вас $numof каждый раз остаётся неинициализированной с неким значением "из космоса".

    А с сетами....так сходу сложно сказать, у меня вроде бы такого не было. По идее никакого перемешивания не должно быть.
     
  5. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Эээ.... да, точно... ошибся. Бывает, особенно когда быстро что-то пишешь....
    Попробовал присвоить так - сет заполнился. В outliner-e они перечислены в правильной последовательности. При выполнении
    $bonez=`sets -q bonez`;
    в массив попадает смесь, начиная с 148 элемента.
     
  6. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Чуть-чуть подредактировал скрипт:

    select $allaa[0];
    $joints=`sets -n bonez`;
    for ($numof=1; $numof<size($allaa); $numof++)
    {
    sets -add bonez $allaa[$numof] ;
    }
    $bonez=`sets -q bonez`;

    Стало немного лучше, за исключением того, что в структуру Лизина10 влез Изолейцин 12.
    LYS10N
    LYS10CA
    LYS10C
    LYS10O
    LYS10CB
    ILE12H
    LYS10CG
    LYS10CD
    LYS10CE
    LYS10NZ
    LYS10H
    LYS10HA
    Естественно, после этой чёртовой 148-й записи всё съезжает.
    В outliner-e все в нужном порядке.
     
  7. Решатель

    Решатель Знаток

    С нами с:
    20.04.2005
    Сообщения:
    1.413
    Симпатии:
    0
    Баллы:
    44
    Шайтан...надо тестировать.
    В принципе вместо сета пока что можно обойтись созданием экспрешна с конструкцией типа:
    global string $ARR[];
    $ARR = {"LYS10N", "LYS10CA"...};

    - чтобы в первом кадре, скажем массив инициализировался и потом делать выборку из него в любой функции...костыль конечно, но всё же...
     
  8. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Ну, проблему эту я объехал простым $bonez=$allaa вместо $bonez=`sets -q bonez`. Но просто нужно учитывать, что иногда по не выясненной причине сет опрашивается не по порядку.
     
  9. Миша Ершов

    Миша Ершов Мастер

    С нами с:
    02.11.2003
    Сообщения:
    1.415
    Симпатии:
    2
    Баллы:
    325
    Юрий, а вы пробовали распечатать сет bonez и посмотреть его порядок при печати, а не в outliner'е?
    Если там всё в порядке, то шут его знает :)
    Самое простое объяснение - очередной загадочный глюк maya.
     
  10. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Нет, не пробовал. Командой sets -q bonez? Если так, то в окне script editor-a получаю перемешанные элементы. Которые затем, вполне закономерно, в таком "порядке" и попадают в переменную.
    Сейчас сформирую текстовый файл со всеми своими аминокислотами и напишу скрипт, строящий цепь joints c этими именами. Смущает только то, что она будет линейная, в то время, как в основном скрипте эта цепь ветвится, т.е. эесперимент не совсем корректен.
     
  11. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Хм, Михаил! Т.е. из Вашего поста и моей "распечатки" следует, что joints уже попадают в сет с перемешиванием, начиная от 148-го элемента. Тип присвоения joints сету влияет на характер этого смешения.

    Во как интересно-то, а!
     
  12. Миша Ершов

    Миша Ершов Мастер

    С нами с:
    02.11.2003
    Сообщения:
    1.415
    Симпатии:
    2
    Баллы:
    325
    Вот-вот.
    А Вы не думали, может быть с помощью нескольких условных операторов удастся отсортировать сет в массив по значению первых двух-трёх названий joint'а?
    На пример сначала прогоняете весь перемешанный массив, и оттуда в другой массив выбираете всё, что начинается с "LYS", потом ёще раз прогоняете и берёте с названием "SER" и т.д.
    Думаю может получиться. Конечно если перемешавание носит не турбулентный характер. :)
     
  13. Юрий.

    Юрий. Активный участник

    С нами с:
    27.03.2006
    Сообщения:
    44
    Симпатии:
    0
    Баллы:
    5
    Дело в том, что в белке сами аминокислоты (а их 20 штук) перемешаны. У меня всё происходит так: считывается строка из файла белка. Первым в любой аминокислоте всегда идёт азот. Формируется joint для него и эмитируется частица с нужным цветом и диаметром. Задаются другие свойства. Затем считывается следующая строка этой аминокислоты - это всегда углерод-альфа. Затем идёт углерод, а после него цепь ветвится, потому что пошло считывание так называемых sidechain. Когда данная аминокислота заканчивается - всё повторяется снова. Атомов в разных аминокислотах навешано по-разному. Двух одинаковых аминокислот (по строению) нет. Была идея создать библиотеку, но она пока отложена - цепь формируется на лету в основном скрипте и модуле. Далее идёт анимация цепи. И для этого необходим порядок, потому что количество joints соответствует количеству частиц и "рождались" отдовременно. На данный момент, поскольку $bonez=`sets -q bonez` работает не всегда корректно, я при создании очередного joint-a заношу просто его в массив как следующий элемент. И в этом случае любой atom[$i] всегда соответствует _particle_Shape.pt[$i]
     
  14. Миша Ершов

    Миша Ершов Мастер

    С нами с:
    02.11.2003
    Сообщения:
    1.415
    Симпатии:
    2
    Баллы:
    325
    Теперь мне понятна Ваша цель и задача, как и то, что я плохо ориентируюсь в химии.
     
Модераторы: Dark™, Skif

Поделиться этой страницей