51c6e6f2842abd1940f2871c7d23ffb59fd75445
mmaddren
  Mon Sep 19 16:02:14 2011 -0700
added first pass of documentation to cv and ra
diff --git python/lib/ucscgenomics/cv.py python/lib/ucscgenomics/cv.py
index 307d51c..342a40e 100644
--- python/lib/ucscgenomics/cv.py
+++ python/lib/ucscgenomics/cv.py
@@ -1,36 +1,55 @@
 import re
 import os
 from ucscgenomics import ra
 
 class CvFile(ra.RaFile):
-	"""cv.ra representation. Mainly adds CV-specific validation to the RaFile"""
+	"""
+	cv.ra representation. Mainly adds CV-specific validation to the RaFile
+	
+	To create a CvFile, the simplest way is just to call it with no params,
+	but you can specify a file path if you want to open up something other
+	than the alpha cv in your tree, specify this. The handler can almost
+	always be left blank, since that simply provides a function to handle
+	validation errors that would otherwise throw an exception. You also should
+	specify a protocolPath if you want to validate, since it will check the
+	protocol documents when you validate, to ensure that the cv matches them.
+	
+	Validation recurses over all stanzas, calling the overridden validation
+	function for the more developed stanzas. To start validation, you can 
+	simply call validate() on the cv object.
+	
+	For more information about other things not specific to the cv, but for
+	all ra files, look at the RaFile documentation.
+	"""
 
 	def __init__(self, filePath=None, handler=None, protocolPath=None):
 		"""sets up exception handling method, and optionally reads from a file"""
 		ra.RaFile.__init__(self)
 		
 		self.handler = handler
 		if handler == None:
 			self.handler = self.raiseException
 			
 		if filePath == None:
 			filePath = os.path.expanduser('~/kent/src/hg/makeDb/trackDb/') + 'cv/alpha/cv.ra'
 		
 		self.protocolPath = protocolPath
 		if protocolPath == None:
 			self.protocolPath == os.path.expanduser('~/htdocsExtras/ENCODE/')
+			if not os.path.isdir(self.protocolPath):
+				self.protocolPath = None
 		
 		self.read(filePath)
 
 	def raiseException(self, exception):
 		"""wrapper function for raising exception"""
 		raise exception
 
 	def readStanza(self, stanza):
 		"""overriden method from RaFile which makes specialized stanzas based on type"""
 		e = ra.RaStanza()
 		ek, ev = e.readStanza(stanza)
 		type = e['type']
 
 		if type == 'Antibody':
 			entry = AntibodyStanza()
@@ -225,31 +244,31 @@
 
 					if entry['type'] == key and val == entry[other]:
 						p = 1
 						break
 			if p == 0:
 				ra.handler(NonmatchKeyError(self, key, other))
 
 	def checkProtocols(self, ra, path):
 		if 'protocol' in self:
 			protocols = self['protocol'].split()
 			for protocol in protocols:
 				if ':' not in protocol:
 					ra.handler(InvalidProtocolError(self, protocol))
 				else:
 					p = protocol.split(':', 1)[1]
-					if not os.path.isfile(ra.protocolPath + path + p):
+					if ra.protocolPath != None and not os.path.isfile(ra.protocolPath + path + p):
 						ra.handler(InvalidProtocolError(self, protocol))
 				
 class CvError(Exception):
 	"""base error class for the cv."""
 	def __init__(self, stanza):
 		self.stanza = stanza
 		self.msg = ''
 		
 	def __str__(self):
 		return str('%s[%s] %s: %s' % (self.stanza.name, self.stanza['type'], self.__class__.__name__, self.msg))
 		
 class MissingKeyError(CvError):
 	"""raised if a mandatory key is missing"""
 	
 	def __init__(self, stanza, key):