1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23   
 24  """Module for handling the molecule, residue, and spin sequence.""" 
 25   
 26   
 27  from types import IntType, NoneType 
 28   
 29   
 30  from generic_fns.mol_res_spin import count_molecules, count_residues, count_spins, exists_mol_res_spin_data, generate_spin_id, return_molecule, return_residue, return_spin, spin_id_to_data_list, spin_loop 
 31  import pipes 
 32  from relax_errors import RelaxError, RelaxDiffMolNumError, RelaxDiffResNumError, RelaxDiffSeqError, RelaxDiffSpinNumError, RelaxFileEmptyError, RelaxInvalidSeqError, RelaxNoSequenceError, RelaxSequenceError 
 33  from relax_io import open_write_file, read_spin_data, write_spin_data 
 34  import sys 
 35   
 36   
 37   
 38 -def copy(pipe_from=None, pipe_to=None, preserve_select=False, verbose=True): 
  39      """Copy the molecule, residue, and spin sequence data from one data pipe to another. 
 40   
 41      @keyword pipe_from:         The data pipe to copy the sequence data from.  This defaults to the 
 42                                  current data pipe. 
 43      @type pipe_from:            str 
 44      @keyword pipe_to:           The data pipe to copy the sequence data to.  This defaults to the 
 45                                  current data pipe. 
 46      @type pipe_to:              str 
 47      @keyword preserve_select:   A flag which if True will cause spin selections to be preserved. 
 48      @type preserve_select:      bool 
 49      @keyword verbose:           A flag which if True will cause info about each spin to be printed 
 50                                  out as the sequence is generated. 
 51      @type verbose:              bool 
 52      """ 
 53   
 54       
 55      if pipe_from == None and pipe_to == None: 
 56          raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.") 
 57      elif pipe_from == None: 
 58          pipe_from = pipes.cdp_name() 
 59      elif pipe_to == None: 
 60          pipe_to = pipes.cdp_name() 
 61   
 62       
 63      pipes.test(pipe_from) 
 64      pipes.test(pipe_to) 
 65   
 66       
 67      if not exists_mol_res_spin_data(pipe_from): 
 68          raise RelaxNoSequenceError 
 69   
 70       
 71      if exists_mol_res_spin_data(pipe_to): 
 72          raise RelaxSequenceError 
 73   
 74       
 75      for spin, mol_name, res_num, res_name in spin_loop(pipe=pipe_from, full_info=True): 
 76           
 77          if preserve_select: 
 78              select = spin.select 
 79          else: 
 80              select = True 
 81   
 82           
 83          generate(mol_name, res_num, res_name, spin.num, spin.name, pipe_to, select=select, verbose=verbose) 
  84   
 85   
 87      """Compare the sequence in two data pipes. 
 88   
 89      @keyword pipe1:     The name of the first data pipe. 
 90      @type pipe1:        str 
 91      @keyword pipe2:     The name of the second data pipe. 
 92      @type pipe2:        str 
 93      @keyword fail:      A flag which if True causes a RelaxError to be raised. 
 94      @type fail:         bool 
 95      @return:            1 if the sequence is the same, 0 if different. 
 96      @rtype:             int 
 97      @raises RelaxError: If the sequence is different and the fail flag is True. 
 98      """ 
 99   
100       
101      status = 1 
102   
103       
104      if count_molecules(pipe=pipe1) != count_molecules(pipe=pipe2): 
105          status = 0 
106          if fail: 
107              raise RelaxDiffMolNumError(pipe1, pipe2) 
108   
109       
110      if count_residues(pipe=pipe1) != count_residues(pipe=pipe2): 
111          status = 0 
112          if fail: 
113              raise RelaxDiffResNumError(pipe1, pipe2) 
114   
115       
116      if count_spins(pipe=pipe1) != count_spins(pipe=pipe2): 
117          status = 0 
118          if fail: 
119              raise RelaxDiffSpinNumError(pipe1, pipe2) 
120   
121       
122      seq1 = '' 
123      seq2 = '' 
124      for spin, spin_id in spin_loop(return_id=True, pipe=pipe1): 
125          seq1 = seq1 + spin_id + '\n' 
126      for spin, spin_id in spin_loop(return_id=True, pipe=pipe2): 
127          seq2 = seq2 + spin_id + '\n' 
128   
129       
130      if seq1 != seq2: 
131          status = 0 
132          if fail: 
133              raise RelaxDiffSeqError(pipe1, pipe2) 
134   
135       
136      return status 
 137   
138   
139 -def display(sep=None, mol_name_flag=False, res_num_flag=False, res_name_flag=False, spin_num_flag=False, spin_name_flag=False): 
 140      """Display the molecule, residue, and/or spin sequence data. 
141   
142      This calls the write() function to do most of the work. 
143   
144   
145      @keyword sep:               The column seperator which, if None, defaults to whitespace. 
146      @type sep:                  str or None 
147      @keyword mol_name_flag:     A flag which if True will cause the molecule name column to be 
148                                  written. 
149      @type mol_name_flag:        bool 
150      @keyword res_num_flag:      A flag which if True will cause the residue number column to be 
151                                  written. 
152      @type res_num_flag:         bool 
153      @keyword res_name_flag:     A flag which if True will cause the residue name column to be 
154                                  written. 
155      @type res_name_flag:        bool 
156      @keyword spin_name_flag:    A flag which if True will cause the spin name column to be written. 
157      @type spin_name_flag:       bool 
158      @keyword spin_num_flag:     A flag which if True will cause the spin number column to be 
159                                  written. 
160      @type spin_num_flag:        bool 
161      @param mol_name_flag:    The column to contain the molecule name information. 
162      """ 
163   
164       
165      if not count_spins(): 
166          raise RelaxNoSequenceError 
167   
168       
169      write(file=sys.stdout, sep=sep, mol_name_flag=mol_name_flag, res_num_flag=res_num_flag, res_name_flag=res_name_flag, spin_num_flag=spin_num_flag, spin_name_flag=spin_name_flag) 
 170   
171   
172 -def generate(mol_name=None, res_num=None, res_name=None, spin_num=None, spin_name=None, pipe=None, select=True, verbose=True): 
 173      """Generate the sequence item-by-item by adding a single molecule/residue/spin container as necessary. 
174   
175      @keyword mol_name:  The molecule name. 
176      @type mol_name:     str or None 
177      @keyword res_num:   The residue number. 
178      @type res_num:      int or None 
179      @keyword res_name:  The residue name. 
180      @type res_name:     str or None 
181      @keyword spin_num:  The spin number. 
182      @type spin_num:     int or None 
183      @keyword spin_name: The spin name. 
184      @type spin_name:    str or None 
185      @keyword pipe:      The data pipe in which to generate the sequence.  This defaults to the current data pipe. 
186      @type pipe:         str 
187      @keyword select:    The spin selection flag. 
188      @type select:       bool 
189      @keyword verbose:   A flag which if True will cause info about each spin to be printed out as the sequence is generated. 
190      @type verbose:      bool 
191      @return:            True if a new spin was created, False otherwise. 
192      @rtype:             bool 
193      """ 
194   
195       
196      if pipe == None: 
197          pipe = pipes.cdp_name() 
198   
199       
200      dp = pipes.get_pipe(pipe) 
201   
202       
203      curr_mol = return_molecule(generate_spin_id(mol_name=mol_name), pipe=pipe) 
204   
205       
206      if not curr_mol: 
207           
208          dp.mol.add_item(mol_name=mol_name) 
209          curr_mol = dp.mol[-1] 
210   
211       
212      curr_res = return_residue(generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name), pipe=pipe) 
213   
214       
215      if not curr_res: 
216           
217          curr_mol.res.add_item(res_name=res_name, res_num=res_num) 
218          curr_res = curr_mol.res[-1] 
219   
220       
221      curr_spin = return_spin(generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name), pipe=pipe) 
222   
223       
224      new_data = False 
225      if not curr_spin: 
226           
227          curr_res.spin.add_item(spin_name=spin_name, spin_num=spin_num) 
228   
229           
230          curr_spin = return_spin(generate_spin_id(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name), pipe=pipe) 
231   
232           
233          new_data = True 
234   
235       
236      curr_spin.select = select 
237   
238       
239      return new_data 
 240   
241   
242 -def read(file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, sep=None, spin_id=None): 
 243      """Read the molecule, residue, and/or spin sequence data from file. 
244   
245      @param file:            The name of the file to open. 
246      @type file:             str 
247      @param dir:             The directory containing the file (defaults to the current directory if 
248                              None). 
249      @type dir:              str or None 
250      @keyword file_data:     An alternative to opening a file, if the data already exists in the 
251                              correct format.  The format is a list of lists where the first index 
252                              corresponds to the row and the second the column. 
253      @type file_data:        list of lists 
254      @keyword spin_id_col:   The column containing the spin ID strings.  If supplied, the 
255                              mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col 
256                              arguments must be none. 
257      @type spin_id_col:      int or None 
258      @keyword mol_name_col:  The column containing the molecule name information.  If supplied, 
259                              spin_id_col must be None. 
260      @type mol_name_col:     int or None 
261      @keyword res_name_col:  The column containing the residue name information.  If supplied, 
262                              spin_id_col must be None. 
263      @type res_name_col:     int or None 
264      @keyword res_num_col:   The column containing the residue number information.  If supplied, 
265                              spin_id_col must be None. 
266      @type res_num_col:      int or None 
267      @keyword spin_name_col: The column containing the spin name information.  If supplied, 
268                              spin_id_col must be None. 
269      @type spin_name_col:    int or None 
270      @keyword spin_num_col:  The column containing the spin number information.  If supplied, 
271                              spin_id_col must be None. 
272      @type spin_num_col:     int or None 
273      @keyword sep:           The column separator which, if None, defaults to whitespace. 
274      @type sep:              str or None 
275      @keyword spin_id:       The spin ID string used to restrict data loading to a subset of all 
276                              spins. 
277      @type spin_id:          None or str 
278      """ 
279   
280       
281      pipes.test() 
282   
283       
284      if exists_mol_res_spin_data(): 
285          raise RelaxSequenceError 
286   
287       
288      mol_names = [] 
289      res_nums = [] 
290      res_names = [] 
291      spin_nums = [] 
292      spin_names = [] 
293   
294       
295      for mol_name, res_num, res_name, spin_num, spin_name in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, sep=sep, spin_id=spin_id): 
296           
297          new_spin = generate(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) 
298   
299           
300          if new_spin: 
301              mol_names.append(mol_name) 
302              res_nums.append(res_num) 
303              res_names.append(res_name) 
304              spin_nums.append(spin_num) 
305              spin_names.append(spin_name) 
306   
307       
308      write_spin_data(sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names) 
 309   
310   
311 -def validate_sequence(data, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, data_col=None, error_col=None): 
 312      """Test if the sequence data is valid. 
313   
314      The only function this performs is to raise a RelaxError if the data is invalid. 
315   
316   
317      @param data:            The sequence data. 
318      @type data:             list of lists. 
319      @keyword spin_id_col:   The column containing the spin ID strings. 
320      @type spin_id_col:      int or None 
321      @param mol_name_col:    The column containing the molecule name information. 
322      @type mol_name_col:     int or None 
323      @param res_name_col:    The column containing the residue name information. 
324      @type res_name_col:     int or None 
325      @param res_num_col:     The column containing the residue number information. 
326      @type res_num_col:      int or None 
327      @param spin_name_col:   The column containing the spin name information. 
328      @type spin_name_col:    int or None 
329      @param spin_num_col:    The column containing the spin number information. 
330      @type spin_num_col:     int or None 
331      """ 
332   
333       
334      if spin_id_col: 
335          if len(data) < spin_id_col: 
336              raise RelaxInvalidSeqError(data, "the Spin ID data is missing") 
337   
338       
339      if mol_name_col: 
340          if len(data) < mol_name_col: 
341              raise RelaxInvalidSeqError(data, "the molecule name data is missing") 
342   
343       
344      if res_num_col: 
345           
346          if len(data) < res_num_col: 
347              raise RelaxInvalidSeqError(data, "the residue number data is missing") 
348   
349           
350          try: 
351              res_num = eval(data[res_num_col-1]) 
352              if not (isinstance(res_num, NoneType) or isinstance(res_num, IntType)): 
353                  raise ValueError 
354          except: 
355              raise RelaxInvalidSeqError(data, "the residue number data '%s' is invalid" % data[res_num_col-1]) 
356   
357       
358      if res_name_col: 
359          if len(data) < res_name_col: 
360              raise RelaxInvalidSeqError(data, "the residue name data is missing") 
361   
362       
363      if spin_num_col: 
364           
365          if len(data) < spin_num_col: 
366              raise RelaxInvalidSeqError(data, "the spin number data is missing") 
367   
368           
369          try: 
370              res_num = eval(data[res_num_col-1]) 
371              if not (isinstance(res_num, NoneType) or isinstance(res_num, IntType)): 
372                  raise ValueError 
373          except: 
374              raise RelaxInvalidSeqError(data, "the spin number data '%s' is invalid" % data[res_num_col-1]) 
375   
376       
377      if spin_name_col: 
378          if len(data) < spin_name_col: 
379              raise RelaxInvalidSeqError(data, "the spin name data is missing") 
380   
381       
382      if data_col: 
383          if len(data) < data_col: 
384              raise RelaxInvalidSeqError(data, "the data is missing") 
385   
386       
387      if error_col: 
388          if len(data) < error_col: 
389              raise RelaxInvalidSeqError(data, "the error data is missing") 
 390   
391   
392 -def write(file, dir=None, sep=None, mol_name_flag=True, res_num_flag=True, res_name_flag=True, spin_num_flag=True, spin_name_flag=True, force=False): 
 393      """Write the molecule, residue, and/or sequence data. 
394   
395      This calls the relax_io.write_spin_data() function to do most of the work. 
396   
397   
398      @param file:                The name of the file to write the data to. 
399      @type file:                 str 
400      @keyword dir:               The directory to contain the file (defaults to the current directory if None). 
401      @type dir:                  str or None 
402      @keyword sep:               The column seperator which, if None, defaults to whitespace. 
403      @type sep:                  str or None 
404      @keyword mol_name_flag:     A flag which if True will cause the molecule name column to be written. 
405      @type mol_name_flag:        bool 
406      @keyword res_num_flag:      A flag which if True will cause the residue number column to be written. 
407      @type res_num_flag:         bool 
408      @keyword res_name_flag:     A flag which if True will cause the residue name column to be written. 
409      @type res_name_flag:        bool 
410      @keyword spin_name_flag:    A flag which if True will cause the spin name column to be written. 
411      @type spin_name_flag:       bool 
412      @keyword spin_num_flag:     A flag which if True will cause the spin number column to be written. 
413      @keyword force:             A flag which if True will cause an existing file to be overwritten. 
414      @type force:                bin 
415      """ 
416   
417       
418      if not count_spins(): 
419          raise RelaxNoSequenceError 
420   
421       
422      mol_names = [] 
423      res_nums = [] 
424      res_names = [] 
425      spin_nums = [] 
426      spin_names = [] 
427   
428       
429      for spin, mol_name, res_num, res_name in spin_loop(full_info=True): 
430          mol_names.append(mol_name) 
431          res_nums.append(res_num) 
432          res_names.append(res_name) 
433          spin_nums.append(spin.num) 
434          spin_names.append(spin.name) 
435   
436       
437      if not mol_name_flag: 
438          mol_names = None 
439      if not res_num_flag: 
440          res_nums = None 
441      if not res_name_flag: 
442          res_names = None 
443      if not spin_num_flag: 
444          spin_nums = None 
445      if not spin_name_flag: 
446          spin_names = None 
447   
448       
449      write_spin_data(file=file, dir=dir, sep=sep, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, force=force) 
 450