On 30 April 2010 21:21, Pavel Kaderavek <pavel.kaderavek@xxxxxxxxx> wrote:
Hi, I tried to do the changes in the __init__ function of Mf class in the file maths_fns/mf.py. I am not sure about the way of initialization you described in the previous mail. I understand that it is necessary to initialize the lists between the loops, but I would do it in this way: self.data[i].interactions = zeros(self.num_interactions[i], float64)
Hi, It would be best to do this differently. The interactions will be part of self.data. This structure can be turned into a 2D list of lists - i.e. like a matrix where each row corresponds to one interaction and each column corresponds to an isolated spin system. You do this by replacing: # Create the data array used to store data. self.data = [] for i in xrange(self.num_spins): # Total number of ri. self.total_num_ri = self.total_num_ri + num_ri[i] # The ratio of gyromagnetic ratios. g_ratio = gh[i] / gx[i] # Append the class instance Data to the data array. self.data.append(Data()) ... with: # Create the data list of lists used to store the interaction and spin specific data. self.data = [] for int_index in xrange(self.num_interactions): # Add an empty list for the interaction. self.data.append([]) # Loop over the spins. for spin_index in xrange(self.num_spins): # Total number of ri (only sum for the first interaction). if int_index == 0: self.total_num_ri = self.total_num_ri + num_ri[spin_index] # The ratio of gyromagnetic ratios. g_ratio = gh[int_index][spin_index] / gx[int_index][spin_index] # Append the class instance Data to the interaction list for this spin. self.data[int_index].append(Data()) This will set up the correct data structure.
I think I can avoid procedure inside the second loop where you suggest to a new data container initialise and append to the list. Now I can just fill the list: for j in xrange(self.num_interactions[i]): self.data[i].interactions[j]=interactions[i][j] Am I wrong? Did I misunderstand something?
This would work, but the interactions structure is not necessary - it can be directly part of self.data. The interaction can be considered higher level than the spin, so you can collapse this to: self.data[interaction_index][spin_index] This list of lists is much simpler and easier to maintain in the future.
Moreover, I found that in the __init__ function is necessary to extend the dimension of frequencies per field strength. They will be different between (for example) CC and CH interactions. So, what do you think about this: self.data[i].frq_list = zeros((self.num_interactions[i], num_frq[i], 5), float64) for j in xrange(num_frq[i]): frqH = 2.0 * pi * frq[i][j] frqX = frqH / g_ratio for k in xrange(self.num_interactions[i]): frqY = frqH * self.data[i].gratio_ext[k] / gh[i] self.data[i].frq_list[k, j, 1] = frqX self.data[i].frq_list[k, j, 2] = frqY - frqX
The CC and CH interaction would be in different Data containers, so this is not necessary. They would be in: self.data[CC_index][spin_index] self.data[CH_index][spin_index] Each interaction and each spin has it's own data container in self.data[x][y], therefore almost all the rest of the code in math_fns remains identical and untouched.
Small question at the end: Can it be included in the same patch - both changes belongs to changes in one function or is it too large step?
It would be best to have separate patches. That way they can be individually checked and optimised. In programing in a group environment, it is recommended that each patch/commit should contain only one concept. If there are two unrelated changes in a patch, it is standard practice that the patch creator is asked to split it up and resend it. If it was directly committed, that commit will be reverted. And small patches are much easier to have accepted. One thing I would highly recommend for the start is to have a test RNA data set. This should be of 2 or 3 spins, and where you know what the result is. Normally synthetic data is best, but otherwise results published from a reliable source can be used. A script performing model-free analysis is then written. The aim is to have a data set and script that will be used to check if the code is working. We then add it to the test suite as a system test. This should be done before anything else. This test will then, from now until the death of relax, enforce that this analysis always works for all users. In the test suite system we can exactly and easily check the optimisation results. This is a very useful way of coding because once the test passes - then you know that the code is complete! Cheers, Edward