1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """
25 simply - everyday tools
26 """
27
28 import sys, string
29 import os.path as osp
30 import shutil
31 import operator
32 import os, cPickle
33 import tempfile
34 import traceback
35 from inspect import getframeinfo
36 from time import localtime
37 import Numeric
38 import types
39 import glob
40 import subprocess
41
43 pass
44
46 pass
47
49 """
50 print s to standard error with line feed.
51
52 @param s: string
53 @type s: str
54 """
55 sys.stderr.write(s+'\n')
56 sys.stderr.flush()
57
58
60 """
61 print s to standard error.
62
63 @param s: string
64 @type s: str
65 """
66 sys.stderr.write(s)
67 sys.stderr.flush()
68
69
71 """
72 print s without line break and flush standard out.
73
74 @param s: string
75 @type s: str
76 """
77 sys.stdout.write(s)
78 sys.stdout.flush()
79
80
82 """
83 Collect type and line of last exception.
84
85 @return: '<ExceptionType> in line <lineNumber>:<Exception arguments>'
86 @rtype: String
87 """
88 try:
89 trace = sys.exc_info()[2]
90 why = sys.exc_info()[1]
91 try:
92 why = sys.exc_info()[1].args
93 except:
94 pass
95 file = getframeinfo( trace.tb_frame )[0]
96
97 result = "%s in %s line %i:\n\t%s." % ( str(sys.exc_type),
98 file, trace.tb_lineno, str(why) )
99
100 finally:
101 trace = None
102
103 return result
104
105
107 tb = sys.exc_info()[2]
108
109 lines = traceback.extract_tb( tb, None )
110
111 result = ''
112 for l in lines:
113 pyFile = stripFilename( l[0] )
114 result += '%s: %i (%s) %s\n' % (pyFile, l[1],l[2],l[3])
115
116 return result
117
118
120 """
121 Add value to dic, create list, if dic has already value in key.
122
123 @param key: dictionary key
124 @type key: str
125 @param value: value
126 @type value: any
127 """
128 if key in dic:
129 old = dic[key]
130
131 if type( old ) != list and value != old:
132 dic[ key ] = [ old ] + [ value ]
133 else:
134 if type( old ) == list and value not in old:
135 dic[ key ] = old + [ value ]
136
137 else:
138 dic[key] = value
139
140
141 -def absfile( filename, resolveLinks=1 ):
142 """
143 Get absolute file path::
144 - expand ~ to user home, change
145 - expand ../../ to absolute path
146 - resolve links
147 - add working directory to unbound files ('ab.txt'->'/home/raik/ab.txt')
148
149 @param filename: name of file
150 @type filename: str
151 @param resolveLinks: eliminate any symbolic links (default: 1)
152 @type resolveLinks: 1|0
153
154 @return: absolute path or filename
155 @rtype: string
156
157 @raise ToolsError: if a ~user part does not translate to an existing path
158 """
159 if not filename:
160 return filename
161 r = osp.abspath( osp.expanduser( filename ) )
162
163 if '~' in r:
164 raise ToolsError, 'Could not expand user home in %s' % filename
165
166 if resolveLinks:
167 r = osp.realpath( r )
168 r = osp.normpath(r)
169 return r
170
171
172 -def homefile( filename, otherUser=1, ownCopy=1 ):
173 """
174 Relativize a file name to ~ or, if it is in another user's home,
175 to ~otheruser or, if it is in nobody's home, to / .
176
177 L{splithome()} is used to also guess home directories of other users.
178
179 @param filename: name of file
180 @type filename: str
181 @param otherUser: look also in other user's home directories (default 1)
182 @type otherUser: 1|0
183 @param ownCopy: replace alien path by path into own home directory if
184 possible, e.g. ~other/data/x is replaced
185 by ~/data/x if there is such a file. (default 1) Careful!
186 @type ownCopy: 1|0
187
188 @return: path or filename
189 @rtype: str
190 """
191 f = absfile( filename )
192 my_home = osp.expanduser('~')
193 user_home, rest = splithome( f )
194
195 if user_home == my_home:
196 return f.replace( user_home, '~', 1 )
197
198 if otherUser and user_home != '':
199
200 if ownCopy:
201 my_path = os.path.join( my_home, rest )
202 if osp.exists( my_path ):
203 return my_path
204
205 user = osp.split( user_home )[-1]
206 return f.replace( user_home+'/', '~' + user + '/', 1 )
207
208 return f
209
210
212 """
213 Split path into home directory and remaining path. Valid home directories
214 are folders belonging to the same folder as the current user's home. I.e.
215 the method tries also to guess home directories of other users.
216
217 @param filename: name of file
218 @type filename: str
219
220 @return: home folder of some user, remaining path relative to home
221 @rtype: (str, str)
222 """
223 home = osp.expanduser( '~' )
224 home_base = osp.split( home )[0]
225
226 if filename.find( home_base ) != 0:
227 return '', filename
228
229 f = filename.replace( home_base + '/', '', 1 )
230 user = f.split( '/' )[0]
231
232 user_home = os.path.join( home_base, user )
233 rest = f.replace( user + '/', '', 1 )
234
235 return user_home, rest
236
237
239 """
240 Return file name without ending.
241
242 @param filename: name of file
243 @type filename: str
244
245 @return: filename or path without suffix
246 @rtype: str
247 """
248 try:
249 if filename.find('.') <> -1:
250 filename = filename[: filename.rfind('.') ]
251 except:
252 pass
253
254 return filename
255
256
258 """
259 Return filename without path and without ending.
260
261 @param filename: name of file
262 @type filename: str
263
264 @return: base filename
265 @rtype: str
266 """
267 name = osp.basename( filename )
268 try:
269 if name.find('.') <> -1:
270 name = name[: name.rfind('.') ]
271 except:
272 pass
273
274 return name
275
276
278 """
279 Count number of lines in a file.
280
281 @param filename: name of file
282 @type filename: str
283
284 @return: number of lines
285 @rtype: int
286 """
287 p1 = subprocess.Popen( ['cat',filename], stdout=subprocess.PIPE )
288 p2 = subprocess.Popen( ["wc", "-l"], stdin=p1.stdout,
289 stdout=subprocess.PIPE )
290 return int(p2.communicate()[0])
291
292
294 """
295 Get folder for temporary files - either from environment settings
296 or '/tmp'
297
298 @return: directort for temporary files
299 @rtype: str
300 """
301 if tempfile.tempdir != None:
302 return tempfile.tempdir
303
304 return osp.dirname( tempfile.mktemp() )
305
306
308 """
309 Construct dictionary from file with key - value pairs (one per line).
310
311 @param filename: name of file
312 @type filename: str
313
314 @raise ToolsError: if file can't be parsed into dictionary
315 @raise IOError: if file can't be opened
316 """
317 try:
318 line = None
319 result = {}
320 for line in open( filename ):
321
322 if '#' in line:
323 line = line[ : line.index('#') ]
324 line = line.strip()
325
326 l = line.split()[1:]
327
328 if len( l ) == 0 and len( line ) > 0:
329 result[ line.split()[0] ] = ''
330 if len( l ) == 1:
331 result[ line.split()[0] ] = l[0]
332 if len( l ) > 1:
333 result[ line.split()[0] ] = l
334 except:
335 s = "Error parsing option file %s." % fname
336 s += '\nLine: ' + str( line )
337 s += '\n' + lastError()
338 raise ToolsError( s )
339
340 return result
341
342
344 """
345 Parse commandline options into dictionary of type C{ {<option> : <value>} }
346 Options are recognised by a leading '-'.
347 Error handling should be improved.
348
349 Option C{ -x |file_name| } is interpreted as file with additional options.
350 The key value pairs in lst_cmd replace key value pairs in the
351 -x file and in dic_default.
352
353
354 @param lst_cmd: list with the command line options::
355 e.g. ['-pdb', 'in1.pdb', 'in2.pdb', '-o', 'out.dat']
356 @type lst_cmd: [str]
357 @param dic_default: dictionary with default options::
358 e.g. {'psf':'in.psf'}
359 @type dic_default: {str : str}
360
361 @return: command dictionary::
362 ala {'pdb':['in1.pdb', 'in2.pdb'], 'psf':'in.psf', 'o':'out.dat'}
363 @rtype: {<option> : <value>}
364 """
365 dic_cmd = {}
366 try:
367
368 for cmd in lst_cmd:
369 if (cmd[0] == '-'):
370 current_option = cmd[1:]
371 dic_cmd[current_option] = ""
372
373 counter = 0
374 else:
375
376 if counter < 1:
377 dic_cmd[current_option] = cmd
378
379
380
381 else:
382 if counter == 1:
383
384 dic_cmd[current_option] = [dic_cmd[current_option]]
385
386 dic_cmd[current_option] = dic_cmd[current_option] + [cmd]
387
388 counter = counter + 1
389
390 except (KeyError, UnboundLocalError), why:
391 errWriteln("Can't resolve command line options.\n \tError:"+str(why))
392
393
394 try:
395 if dic_cmd.has_key('x'):
396 d = file2dic( dic_cmd['x'] )
397 d.update( dic_cmd )
398 dic_cmd = d
399 except IOError:
400 errWriteln( "Error opening %s."% dic_cmd['x'] )
401 except ToolsError, why:
402 errWriteln( str(why) )
403
404
405 dic_default.update( dic_cmd )
406 dic_cmd = dic_default
407
408 return dic_cmd
409
410
412 """
413 Convenience implementation of L{get_cmdDict}. Take command line options
414 from sys.argv[1:] and convert them into dictionary.
415 Example::
416 '-o out.dat -in 1.pdb 2.pdb 3.pdb -d' will be converted to
417 {'o':'out.dat', 'in': ['1.pdb', '2.pdb', '3.pdb'], 'd':'' }
418
419 Option C{ -x |file_name| } is interpreted as file with additional options.
420
421 @param defaultDic: dic with default values.
422 @type defaultDic: dic
423
424 @return: command dictionary
425 @rtype: dic
426 """
427 return get_cmdDict( sys.argv[1:], defaultDic )
428
429
430 -def Dump(this, filename, gzip = 0, mode = 'w'):
431 """
432 Dump this::
433 Dump(this, filename, gzip = 0)
434 Supports also '~' or '~user'.
435
436 @author: Wolfgang Rieping
437 @note gzip currently doesn't work.
438
439 @param this: object to dump
440 @type this: any
441 @param filename: name of file
442 @type filename: str
443 @param gzip: gzip dumped object (default 0)
444 @type gzip: 1|0
445 @param mode: file handle mode (default w)
446 @type mode: str
447 """
448 filename = osp.expanduser(filename)
449
450 if not mode in ['w', 'a']:
451 raise "mode has to be 'w' (write) or 'a' (append)"
452
453
454
455
456
457 f = open(filename, mode)
458
459 cPickle.dump(this, f, 1)
460
461 f.close()
462
463
464 -def Load(filename, gzip = 0):
465 """
466 Load dumped object from file.
467
468 @author: Wolfgang Rieping
469
470 @param filename: name of file
471 @type filename: str
472 @param gzip: unzip dumped object (default 0)
473 @type gzip: 1|0
474
475 @return: loaded object
476 @rtype: any
477
478 @raise cPickle.UnpicklingError, if the pickle format is not recognized
479 """
480 filename = osp.expanduser(filename)
481
482 try:
483 f = open(filename)
484
485 objects = []
486
487 eof = 0
488 n = 0
489
490 while not eof:
491 try:
492 this = cPickle.load(f)
493 objects.append(this)
494 n += 1
495 except EOFError:
496 eof = 1
497
498 f.close()
499
500 if n == 1:
501 return objects[0]
502 else:
503 return tuple(objects)
504
505 except ValueError, why:
506 raise PickleError, 'Python pickle %s is corrupted.' % filename
507
508
509
511 """
512 Return attr either unpickled, freshly calculated or unchanged.
513 If attr is no tuple or anything else goes wrong it is returned unchanged
514
515 @param attr: tuple of string and function::
516 attr[0] - name of existing or non-existing file or ''
517 attr[1] - function to get result if it can't be unpickled
518 @type attr: (str, function)
519 @param dumpIt: try pickling return value to attr[0](if valid file)
520 (default 1)
521 @type dumpIt: 0|1
522
523 @return: attr (unchanged or object unpickeled from file)
524 @rtype: (str, function)
525 """
526 try:
527 if type( attr ) == type( ('','') ) and type( attr[0] ) == type( '' ):
528
529 fname = attr[0]
530 function = attr[1]
531
532
533 if type(fname)==type('') and osp.exists( attr[0] ):
534 return Load( fname )
535
536
537 result = function()
538
539
540 if osp.exists( osp.dirname( fname )) and dumpIt:
541 Dump( result, fname )
542
543 return result
544
545 except:
546 print lastError()
547
548
549 return attr
550
551
553 """
554 Root of biskit project.
555
556 @return: absolute path of the root of current project::
557 i.e. '/home/Bis/raik/biskit'
558 @rtype: string
559 """
560
561 from Biskit import tools
562
563 f = absfile(tools.__file__)
564
565 f = osp.split( f )[0] + '/../'
566 return absfile( f )
567
568
570 """
571 Root of Biskit test directory.
572
573 @return: absolute path
574 @rtype: string
575 """
576 return projectRoot() + '/test'
577
578
580 """
581 Check if file is a binary.
582
583 @param f: path to existing file
584 @type f: str
585
586 @return: condition
587 @rtype: 1|0
588
589 @raise OSError: if file doesn't exist
590 """
591 st = os.stat( f )
592 mode = st[0]
593 mode = int( oct( mode & 0777 )[1] )
594
595 return ( operator.and_( mode, 1 ) == 1 )
596
597
599 """
600 Check if binary with file name f exists.
601
602 @param f: binary file name
603 @type f: str
604
605 @return: True if binary file f is found in PATH and is executable
606 @rtype: 1|0
607 """
608 if osp.exists( f ):
609 return isBinary( f )
610
611 for path in os.getenv( 'PATH' ).split(':') :
612
613 full_path = osp.join( path, f )
614
615 if osp.exists( full_path ) and isBinary( full_path ):
616 return True
617
618 return False
619
620
622 """
623 Absolute path of binary.
624
625 @param f: binary file name
626 @type f: str
627
628 @return: full path to existing binary
629 @rtype: str
630
631 @raise IOError: if an executable binary is not found in PATH
632 """
633 if osp.exists( f ) and isBinary( f ):
634 return f
635
636 for path in os.getenv( 'PATH' ).split(':') :
637
638 full_path = osp.join( path, f )
639
640 if osp.exists( full_path ) and isBinary( full_path ):
641 return full_path
642
643 raise IOError, 'binary %s not found.' % f
644
645
665
666
668 """
669 Sort the letters of a string::
670 sortString( str ) -> str with sorted letters
671
672 @param s: string to be sorted
673 @type s: str
674
675 @return: sorted string
676 @rtype: str
677 """
678 l = list(s)
679 l.sort()
680 return ''.join(l)
681
682
684 """
685 Remove forbidden character from string so that it can be used as a
686 filename.
687
688 @param s: string
689 @type s: str
690
691 @return: cleaned string
692 @rtype: str
693 """
694 forbidden = ['*', '?', '|', '/', ' ']
695 replaceme = ['-', '-', '-', '-', '_']
696 for i in range(0, len(forbidden)):
697 s = s.replace( forbidden[i], replaceme[i] )
698 return s
699
700
702 """
703 Convert single value or list of values into list of integers.
704
705 @param o: value or list
706 @type o: int or [int]
707
708 @return: list of integer
709 @rtype: [int]
710 """
711 if type( o ) != type( [] ):
712 o = [ o ]
713
714 return map( int, o )
715
716
718 """
719 Convert single value or list of values to Numeric array of int.
720
721 @param o: value or list
722 @type o: int or [int]
723
724 @return: array of integer
725 @rtype: Numeric.array('i')
726 """
727 if type( o ) == list or type( o ) == type( Numeric.array([])):
728 return Numeric.array( map( int, o ) )
729
730 return Numeric.array( [ int( o ) ] )
731
732
734 """
735 Make a list::
736 toList(o) -> [o], or o, if o is already a list
737
738 @param o: value(s)
739 @type o: any or [any]
740
741 @return: list
742 @rtype: [any]
743 """
744 if type( o ) != type( [] ):
745 return [ o ]
746 return o
747
748
750 """
751 Make a string from a list or interger.
752 Stripping of any flanking witespaces.
753
754 @param o: value(s)
755 @type o: any or [any]
756
757 @return: list
758 @rtype: [any]
759 """
760 if type( o ) == type( 1 ):
761 return str(o)
762
763 if type( o ) == type( [] ):
764 s = ''
765 for item in o:
766 s += string.strip( str(item) )
767 return s
768
769 return o
770
771
772 -def toInt( o, default=None ):
773 """
774 Convert to intereg if possible::
775 toInt(o) -> int, int(o) or default if o is impossible to convert.
776
777 @param o: value
778 @type o: any
779 @param default: value to return if conversion is impossible (default: None)
780 @type default: any
781
782 @return: integer OR None
783 @rtype: int OR None
784 """
785 if o == None or o == '':
786 return default
787 try:
788 return int( o )
789 except:
790 return default
791
792
793 -def colorSpectrum( nColors, firstColor='FF0000', lastColor='FF00FF' ):
794 """
795 Creates a list of 'nColors' colors for biggles starting at
796 'firstColor' ending at 'lastColor'
797 Examples::
798 free spectrum red FF0000 to green 00FF00
799 bound spectrum cyan 00FFFF to magenta FF00FF
800
801 @param nColors: number of colors to create
802 @type nColors: int
803 @param firstColor: first color in hex format (default: FF0000)
804 @type firstColor: str
805 @param lastColor: last color in hex format (default: FF00FF)
806 @type lastColor: str
807
808 @return: list of colors
809 @rtype: [int]
810 """
811 spec = []
812 out = os.popen( projectRoot() + '/external/spectrum.pl ' +str(nColors) +
813 ' ' + str(firstColor) + ' ' + str(lastColor) ).readlines()
814
815 for s in out:
816 spec += [ int( float( '0x' + str( string.strip( s ) ) ) ) ]
817
818 return spec
819
820
821 -def hexColors( nColors, firstColor='FF0000', lastColor='FF00FF' ):
822 """
823 Creates a list of 'nColors' colors for PyMol starting at
824 'firstColor' ending at 'lastColor'
825 Examples::
826 free spectrum red FF0000 to green 00FF00
827 bound spectrum cyan 00FFFF to magenta FF00FF
828
829 @param nColors: number of colors to create
830 @type nColors: int
831 @param firstColor: first color in hex format (default: FF0000)
832 @type firstColor: str
833 @param lastColor: last color in hex format (default: FF00FF)
834 @type lastColor: str
835
836 @return: list of hex colors
837 @rtype: [ str ]
838 """
839 spec = []
840 out = os.popen( projectRoot() + '/external/spectrum.pl ' +str(nColors) +
841 ' ' + str(firstColor) + ' ' + str(lastColor) ).readlines()
842
843 for s in out:
844 spec += [ '0x' + str( string.strip( s ) ) ]
845
846 return spec
847
848
850 """
851 convert rgb color into 8 bit hex rgb color::
852 [ 1.0, 0.0, 1.0, ] -> 'FF00FF'
853
854 @param rgbColor: RGB-color e.g. [ 1.0, 0.0, 1.0, ]
855 @type rgbColor : [float]
856
857 @return: hex colors
858 @rtype: str
859 """
860 hexRgb = ''
861 for i in range(0,3):
862 component = hex( int( rgbColor[i]*255 ) )[2:]
863
864 if len(component) == 1:
865 hexRgb += '0' + component
866 else:
867 hexRgb += component
868
869 return hexRgb
870
871
873 """
874 convert 8 bit hex rgb color into rgb color ::
875 'FF00FF' -> [ 1.0, 0.0, 1.0, ]
876
877 @param hexColor: HEX-color e.g. 'FF00FF'
878 @type hexColor: str
879 @param str: return rgb colors as a tring (i.e for PyMol)
880 @type str: 1|0
881
882 @return: rgb colors
883 @rtype: [float]
884 """
885 rgb = []
886 if hexColor[:2] == '0x':
887 hexColor = hexColor[2:]
888
889 for i in range(0,6,2):
890 rgb += [ int(hexColor[i:i+2], 16)/255.0 ]
891
892 if str:
893 rgb_str= '[ %.3f, %.3f, %.3f ]'%(rgb[0], rgb[1], rgb[2])
894
895 return rgb_str
896
897 return rgb
898
899
901 """
902 @return: DD/MM/YYYY
903 @rtype: str
904 """
905 t = localtime()
906 return '%02i/%02i/%i' % (t[2],t[1],t[0] )
907
908
910 """
911 @return: YYYY/MM/DD:hh:mm.ss.ms
912 @rtype:
913 """
914 t = localtime()
915 return "%i/%02i/%02i:%02i.%02i.%02i" % (t[0],t[1],t[2],t[3],t[4],t[5])
916
917
918 -def tryRemove(f, verbose=0, tree=0, wildcard=0 ):
919 """
920 Remove file or folder::
921 remove(f [,verbose=0, tree=0]), remove if possible, otherwise do nothing
922
923 @param f: file path
924 @type f: str
925 @param verbose: report failure (default 0)
926 @type verbose: 0|1
927 @param tree: remove whole folder (default 0)
928 @type tree: 0|1
929 @param wildcard: filename contains wildcards (default 0)
930 @type wildcard: 0|1
931
932 @return: 1 if file was removed
933 @rtype: 1|0
934 """
935 try:
936 if osp.isdir(f):
937 if tree:
938 shutil.rmtree( f, ignore_errors=1 )
939 else:
940 errWriteln('%s is directory - not removed.')
941 else:
942 if wildcard:
943 l = glob.glob( f )
944 for i in l:
945 os.remove( i )
946 else:
947 os.remove( f )
948 return 1
949 except:
950 if verbose: errWriteln( 'Warning: Cannot remove %s.' % str(f) )
951 return 0
952
953 -def backup( fname, suffix='~' ):
954 """
955 Create backup of file if it already exists.
956 @param fname: file name
957 @type fname: str
958 @param suffix: suffix to add to backup file name ['~']
959 @type suffix: str
960
961 @return: True if backup was created, False otherwise
962 @rtype: bool
963 """
964 fname = absfile( fname )
965
966 if os.path.exists( fname ):
967 os.rename( fname, fname + '~' )
968 return True
969 return False
970
971
972 -def ensure( v, t, allowed=[], forbidden=[] ):
973 """
974 Check type of a variable
975
976 @param v: variable to test
977 @type v: variable
978 @param t: required type
979 @type t: str
980 @param allowed: list of additional values allowed for v {default: []}
981 @type allowed: [str]
982
983 @raise TypeError: if invalid
984 """
985 if allowed:
986 allowed = toList( allowed )
987 if len( allowed ) > 0 and v in allowed:
988 return
989
990 if not isinstance(v, t):
991 raise TypeError, 'looked for %s but found %s' % (str(t),str(v)[:20])
992
993 if forbidden and v in forbidden:
994 raise TypeError, 'value %s is not allowed.' % (str(v)[:20])
995
996
997 -def clipStr( s, length, suffix='..', expandtabs=1 ):
998 """
999 Shorten string from end and replace the last characters with suffix::
1000 clipStr( str, length ) -> str, with len( str ) <= length
1001
1002 @param s: original string
1003 @type s: str
1004 @param length: desired length
1005 @type length: int
1006 @param suffix: suffix (default: ..)
1007 @type suffix: str
1008
1009 @return: shortend string
1010 @rtype: str
1011 """
1012 if expandtabs:
1013 s = s.expandtabs()
1014
1015 if len(s) > length:
1016 s = s[:(length - len(suffix))] + suffix
1017 return s
1018
1019
1020 -def info( item, short=1 ):
1021 """
1022 ::
1023 info( item, short=1) -> Print useful information about item.
1024
1025 @param item: query item
1026 @type item: item
1027 @param short: short version (default: 1)
1028 @type short: 1|0
1029 """
1030
1031 if hasattr(item, '__name__'):
1032 print "NAME: ", item.__name__
1033 if hasattr(item, '__class__'):
1034 print "CLASS: ", item.__class__.__name__
1035 print "ID: ", id(item)
1036 print "TYPE: ", type(item)
1037 print "VALUE: ", repr(item)
1038 print "CALLABLE:",
1039 if callable(item):
1040 print "Yes"
1041 else:
1042 print "No"
1043 if hasattr(item, '__doc__'):
1044 doc = getattr(item, '__doc__')
1045 if doc:
1046 doc = doc.strip()
1047 if short:
1048 doc = doc.split('\n')[0]
1049 print "DOC: ", '\n\t' * (not short), doc
1050
1051 print "\nMETHODS"
1052 methods = [ getattr( item, m ) for m in dir( item )
1053 if callable( getattr( item, m ) ) ]
1054
1055 for m in methods:
1056 doc = getattr(m, '__doc__', '')
1057 if doc:
1058 doc = str(doc).strip()
1059 if short:
1060 doc = str(doc).split('\n')[0]
1061 else:
1062 doc = ''
1063 s = "%-15s: " % (getattr(m,'__name__','?')) + '\n\t'*(not short) + doc
1064 if short:
1065 s = clipStr( s, 79 )
1066 print s
1067
1068 if hasattr( item, '__dict__'):
1069
1070 print "\nFIELDS"
1071 for k, v in item.__dict__.items():
1072 s = "%-15s: %s" % (k, str(v).strip() )
1073 print clipStr( s, 79 )
1074
1075
1077 """
1078 Empty class that raises an ImportError upon creation.
1079 """
1081 raise ImportError, \
1082 'Class %r is not available because of missing modules: %r' \
1083 % (cls.__name__, str(cls.error))
1084
1085 import new
1086
1087 -def tryImport( module, cls, as=None, namespace=None ):
1088 """
1089 Try to import a class from a module. If that fails, 'import' a
1090 default class of the same name that raises an exception when used.
1091
1092 @param module: name of the module
1093 @type module: str
1094 @param cls : name of the class
1095 @type cls : str
1096 @param namespace: namespace for the import [default: globals() ]
1097 @type namespace: dict
1098
1099 @return: True if import succeeded, False otherwise
1100 @rtype: bool
1101 """
1102 as = as or cls
1103 g = namespace or globals()
1104 try:
1105 exec 'from %s import %s as %s' % (module, cls, as) in g
1106 return True
1107
1108 except ImportError, e:
1109
1110 Cls = new.classobj( cls,(PseudoClass,),{'error':e} )
1111 g.update( {as: Cls} )
1112
1113 return False
1114
1116 """
1117 Try to import a class from a module. If that fails, 'import' a
1118 default class of the same name that raises an exception when used.
1119
1120 @param module: name of the module
1121 @type module: str
1122 @param namespace: namespace for the import [default: globals() ]
1123 @type namespace: dict
1124
1125 @return: True if import succeeded, False otherwise
1126 @rtype: bool
1127 """
1128 as = as or module
1129 g = namespace or globals()
1130 try:
1131 exec 'import %s as %s' % (module, as) in g
1132 return True
1133
1134 except ImportError, e:
1135
1136 m = new.module( as, doc='Pseudo module. Import of real one failed.' )
1137 m.error = str(e)
1138
1139 g.update( {as: m} )
1140
1141 return False
1142
1143
1144
1145
1146
1147
1149 """
1150 Test class
1151 """
1152
1153 - def run( self, local=0 ):
1154 """
1155 run function test
1156
1157 @param local: transfer local variables to global and perform
1158 other tasks only when run locally
1159 @type local: 1|0
1160
1161 @return: 1
1162 @rtype: int
1163 """
1164 from Biskit import PDBModel
1165
1166 m = PDBModel( testRoot()+'/rec/1A2P.pdb')
1167
1168 if local:
1169 print "\nTEST info:"
1170 info(m)
1171
1172 if local:
1173 print "\nTEST Exception:"
1174 try:
1175 i = 1/0
1176 except:
1177 print lastErrorTrace()
1178
1179 if local: print "\nTEST ensure"
1180 ensure( m, PDBModel )
1181
1182 if local:
1183 globals().update( locals() )
1184
1185 absfile('~')
1186
1187 return 1
1188
1189
1191 """
1192 Precalculated result to check for consistent performance.
1193
1194 @return: 1
1195 @rtype: int
1196 """
1197 return 1
1198
1199
1200
1201 if __name__ == '__main__':
1202
1203 test = Test()
1204
1205 assert test.run( local=1 ) == test.expected_result()
1206