Render.ru

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

Юрий.

Активный участник
Рейтинг
5
#1
Добрый всем день.
Хочу поделиться одним наблюдением и, может быть, разобраться, что же это такое - баг или фича. Сразу оговорюсь, что проблема была мной исследована, её признаки определены. Но решение этой проблемы найдено не было. А посему, за неимением времени на исследования и опыты, было решено обойти эту проблему дополнительными парой срок кода 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. Вся эта штука - скелет. Скелет очень ветвистый. Но ветвиться он начинает задолго до десятого Лизина.
 

Миша Ершов

Модератор форума
Рейтинг
314
#2
В этом месте:

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

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

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

Юрий.

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

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

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

Юрий.

Активный участник
Рейтинг
5
#5
Эээ.... да, точно... ошибся. Бывает, особенно когда быстро что-то пишешь....
Попробовал присвоить так - сет заполнился. В outliner-e они перечислены в правильной последовательности. При выполнении
$bonez=`sets -q bonez`;
в массив попадает смесь, начиная с 148 элемента.
 

Юрий.

Активный участник
Рейтинг
5
#6
Чуть-чуть подредактировал скрипт:

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 все в нужном порядке.
 
Рейтинг
34
#7
Шайтан...надо тестировать.
В принципе вместо сета пока что можно обойтись созданием экспрешна с конструкцией типа:
global string $ARR[];
$ARR = {"LYS10N", "LYS10CA"...};

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

Юрий.

Активный участник
Рейтинг
5
#8
Ну, проблему эту я объехал простым $bonez=$allaa вместо $bonez=`sets -q bonez`. Но просто нужно учитывать, что иногда по не выясненной причине сет опрашивается не по порядку.
 

Миша Ершов

Модератор форума
Рейтинг
314
#9
Юрий, а вы пробовали распечатать сет bonez и посмотреть его порядок при печати, а не в outliner'е?
Если там всё в порядке, то шут его знает :)
Самое простое объяснение - очередной загадочный глюк maya.
 

Юрий.

Активный участник
Рейтинг
5
#10
Нет, не пробовал. Командой sets -q bonez? Если так, то в окне script editor-a получаю перемешанные элементы. Которые затем, вполне закономерно, в таком "порядке" и попадают в переменную.
Сейчас сформирую текстовый файл со всеми своими аминокислотами и напишу скрипт, строящий цепь joints c этими именами. Смущает только то, что она будет линейная, в то время, как в основном скрипте эта цепь ветвится, т.е. эесперимент не совсем корректен.
 

Юрий.

Активный участник
Рейтинг
5
#11
Хм, Михаил! Т.е. из Вашего поста и моей "распечатки" следует, что joints уже попадают в сет с перемешиванием, начиная от 148-го элемента. Тип присвоения joints сету влияет на характер этого смешения.

Во как интересно-то, а!
 

Миша Ершов

Модератор форума
Рейтинг
314
#12
Вот-вот.
А Вы не думали, может быть с помощью нескольких условных операторов удастся отсортировать сет в массив по значению первых двух-трёх названий joint'а?
На пример сначала прогоняете весь перемешанный массив, и оттуда в другой массив выбираете всё, что начинается с "LYS", потом ёще раз прогоняете и берёте с названием "SER" и т.д.
Думаю может получиться. Конечно если перемешавание носит не турбулентный характер. :)
 

Юрий.

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