signature:
def create_organization_course ( organization , course_key ) :
    """Inserts a new organization - course relationship into app / local state
 No response currently defined for this operation"""

implementation:
organization_obj = serializers . deserialize_organization ( organization )
try :
    relationship = internal . OrganizationCourse . objects . get ( organization = organization_obj , course_id = text_type ( course_key ) )
    # If the relationship exists , but was inactivated , we can simply turn it back on
    if not relationship . active :
        _activate_organization_course_relationship ( relationship )
except internal . OrganizationCourse . DoesNotExist :
    relationship = internal . OrganizationCourse . objects . create ( organization = organization_obj , course_id = text_type ( course_key ) , active = True )


signature:
def delete_organization_course ( organization , course_key ) :
    """Removes an existing organization - course relationship from app / local state
 No response currently defined for this operation"""

implementation:
try :
    relationship = internal . OrganizationCourse . objects . get ( organization = organization [ 'id' ] , course_id = text_type ( course_key ) , active = True , )
    _inactivate_organization_course_relationship ( relationship )
except internal . OrganizationCourse . DoesNotExist : # If we ' re being asked to delete an organization - course link
# that does not exist in the database then our work is done
    pass


signature:
def fetch_organization_courses ( organization ) :
    """Retrieves the set of courses currently linked to the specified organization"""

implementation:
organization_obj = serializers . deserialize_organization ( organization )
queryset = internal . OrganizationCourse . objects . filter ( organization = organization_obj , active = True ) . select_related ( 'organization' )
return [ serializers . serialize_organization_with_course ( organization ) for organization in queryset ]


signature:
def fetch_course_organizations ( course_key ) :
    """Retrieves the organizations linked to the specified course"""

implementation:
queryset = internal . OrganizationCourse . objects . filter ( course_id = text_type ( course_key ) , active = True ) . select_related ( 'organization' )
return [ serializers . serialize_organization_with_course ( organization ) for organization in queryset ]


signature:
def delete_course_references ( course_key ) :
    """Inactivates references to course keys within this app ( ref : receivers . py and api . py )"""

implementation: [ _inactivate_record ( record ) for record in internal . OrganizationCourse . objects . filter ( course_id = text_type ( course_key ) , active = True ) ]


signature:
def serialize_organization ( organization ) :
    """Organization object - to - dict serialization"""

implementation: return { 'id' : organization . id , 'name' : organization . name , 'short_name' : organization . short_name , 'description' : organization . description , 'logo' : organization . logo }


signature:
def serialize_organization_with_course ( organization_course ) :
    """OrganizationCourse serialization ( composite object )"""

implementation: return { 'id' : organization_course . organization . id , 'name' : organization_course . organization . name , 'short_name' : organization_course . organization . short_name , 'description' : organization_course . organization . description , 'logo' : organization_course . organization . logo , 'course_id' : organization_course . course_id }


signature:
def deserialize_organization ( organization_dict ) :
    """Organization dict - to - object serialization"""

implementation: return models . Organization ( id = organization_dict . get ( 'id' ) , name = organization_dict . get ( 'name' , '' ) , short_name = organization_dict . get ( 'short_name' , '' ) , description = organization_dict . get ( 'description' , '' ) , logo = organization_dict . get ( 'logo' , '' ) )


signature:
def check_large_images ( self , node , parent_depth_level , sibling_depth_level ) :
    """although slow the best way to determine the best image is to download
 them and check the actual dimensions of the image when on disk
 so we ' ll go through a phased approach . . .
 1 . get a list of ALL images from the parent node
 2 . filter out any bad image names that we know of ( gifs , ads , etc . . )
 3 . do a head request on each file to make sure it meets
 our bare requirements
 4 . any images left over let ' s do a full GET request ,
 download em to disk and check their dimensions
 5 . Score images based on different factors like height / width
 and possibly things like color density"""

implementation:
good_images = self . get_image_candidates ( node )
if good_images :
    scored_images = self . fetch_images ( good_images , parent_depth_level )
    if scored_images :
        highscore_image = sorted ( list ( scored_images . items ( ) ) , key = lambda x : x [ 1 ] , reverse = True ) [ 0 ] [ 0 ]
        main_image = Image ( )
        main_image . _src = highscore_image . src
        main_image . _width = highscore_image . width
        main_image . _height = highscore_image . height
        main_image . _extraction_type = "bigimage"
        score_len = len ( scored_images )
        main_image . _confidence_score = 100 / score_len if score_len > 0 else 0
        return main_image
depth_obj = self . get_depth_level ( node , parent_depth_level , sibling_depth_level )
if depth_obj :
    return self . check_large_images ( depth_obj . node , depth_obj . parent_depth , depth_obj . sibling_depth )
return None


signature:
def is_banner_dimensions ( width , height ) :
    """returns true if we think this is kind of a bannery dimension
 like 600 / 100 = 6 may be a fishy dimension for a good image"""

implementation:
if width == height :
    return False
if width > height :
    diff = float ( width / height )
    if diff > 5 :
        return True
if height > width :
    diff = float ( height / width )
    if diff > 5 :
        return True
return False


signature:
def is_valid_filename ( self , image_node ) :
    """will check the image src against a list
 of bad image files we know of like buttons , etc . . ."""

implementation:
src = self . parser . getAttribute ( image_node , attr = 'src' )
if not src :
    return False
if self . badimages_names_re . search ( src ) :
    return False
return True


signature:
def get_images_bytesize_match ( self , images ) :
    """loop through all the images and find the ones
 that have the best bytez to even make them a candidate"""

implementation:
cnt = 0
max_bytes_size = 15728640
good_images = [ ]
for image in images :
    if cnt > 30 :
        return good_images
    src = self . parser . getAttribute ( image , attr = 'src' )
    src = self . build_image_path ( src )
    src = self . add_schema_if_none ( src )
    local_image = self . get_local_image ( src )
    if local_image :
        filesize = local_image . bytes
        if ( filesize == 0 or filesize > self . images_min_bytes ) and filesize < max_bytes_size :
            good_images . append ( image )
        else :
            images . remove ( image )
    cnt += 1
return good_images if len ( good_images ) > 0 else None


signature:
def check_link_tag ( self ) :
    """checks to see if we were able to
 find open link _ src on this page"""

implementation:
node = self . article . raw_doc
meta = self . parser . getElementsByTag ( node , tag = 'link' , attr = 'rel' , value = 'image_src' )
for item in meta :
    src = self . parser . getAttribute ( item , attr = 'href' )
    if src :
        return self . get_image ( src , extraction_type = 'linktag' )
return None


signature:
def check_known_schemas ( self ) :
    """checks to see if we were able to find the image via known schemas :
 Supported Schemas
 - Open Graph
 - schema . org"""

implementation:
if 'image' in self . article . opengraph :
    return self . get_image ( self . article . opengraph [ "image" ] , extraction_type = 'opengraph' )
elif ( self . article . schema and 'image' in self . article . schema and "url" in self . article . schema [ "image" ] ) :
    return self . get_image ( self . article . schema [ "image" ] [ "url" ] , extraction_type = 'schema.org' )
return None


signature:
def get_local_image ( self , src ) :
    """returns the bytes of the image file on disk"""

implementation: return ImageUtils . store_image ( self . fetcher , self . article . link_hash , src , self . config )


signature:
def build_image_path ( self , src ) :
    """This method will take an image path and build
 out the absolute path to that image
 * using the initial url we crawled
 so we can find a link to the image
 if they use relative urls like . . / myimage . jpg"""

implementation:
o = urlparse ( src )
# we have a full url
if o . netloc != '' :
    return o . geturl ( )
# we have a relative url
return urljoin ( self . article . final_url , src )


signature:
def get_video ( self , node ) :
    """Create a video object from a video embed"""

implementation:
video = Video ( )
video . _embed_code = self . get_embed_code ( node )
video . _embed_type = self . get_embed_type ( node )
video . _width = self . get_width ( node )
video . _height = self . get_height ( node )
video . _src = self . get_src ( node )
video . _provider = self . get_provider ( video . src )
return video


signature:
def get_encodings_from_content ( content ) :
    """Code from :
 https : / / github . com / sigmavirus24 / requests - toolbelt / blob / master / requests _ toolbelt / utils / deprecated . py
 Return encodings from given content string .
 : param content : string to extract encodings from ."""

implementation:
if isinstance ( content , bytes ) :
    find_charset = re . compile ( br'<meta.*?charset=["\']*([a-z0-9\-_]+?) *?["\'>]' , flags = re . I ) . findall
    find_xml = re . compile ( br'^<\?xml.*?encoding=["\']*([a-z0-9\-_]+?) *?["\'>]' ) . findall
    return [ encoding . decode ( 'utf-8' ) for encoding in find_charset ( content ) + find_xml ( content ) ]
else :
    find_charset = re . compile ( r'<meta.*?charset=["\']*([a-z0-9\-_]+?) *?["\'>]' , flags = re . I ) . findall
    find_xml = re . compile ( r'^<\?xml.*?encoding=["\']*([a-z0-9\-_]+?) *?["\'>]' ) . findall
    return find_charset ( content ) + find_xml ( content )


signature:
def store_image ( cls , http_client , link_hash , src , config ) :
    """Writes an image src http string to disk as a temporary file
 and returns the LocallyStoredImage object
 that has the info you should need on the image"""

implementation:
# check for a cache hit already on disk
image = cls . read_localfile ( link_hash , src , config )
if image :
    return image
# no cache found ; do something else
# parse base64 image
if src . startswith ( 'data:image' ) :
    image = cls . write_localfile_base64 ( link_hash , src , config )
    return image
# download the image
data = http_client . fetch ( src )
if data :
    image = cls . write_localfile ( data , link_hash , src , config )
    if image :
        return image
return None


signature:
def get_siblings_content ( self , current_sibling , baselinescore_siblings_para ) :
    """adds any siblings that may have a decent score to this node"""

implementation:
if current_sibling . tag == 'p' and self . parser . getText ( current_sibling ) :
    tmp = current_sibling
    if tmp . tail :
        tmp = deepcopy ( tmp )
        tmp . tail = ''
    return [ tmp ]
else :
    potential_paragraphs = self . parser . getElementsByTag ( current_sibling , tag = 'p' )
    if potential_paragraphs is None :
        return None
    paragraphs = list ( )
    for first_paragraph in potential_paragraphs :
        text = self . parser . getText ( first_paragraph )
        if text : # no len ( text ) > 0
            word_stats = self . stopwords_class ( language = self . get_language ( ) ) . get_stopword_count ( text )
            paragraph_score = word_stats . get_stopword_count ( )
            sibling_baseline_score = float ( .30 )
            high_link_density = self . is_highlink_density ( first_paragraph )
            score = float ( baselinescore_siblings_para * sibling_baseline_score )
            if score < paragraph_score and not high_link_density :
                para = self . parser . createElement ( tag = 'p' , text = text , tail = None )
                paragraphs . append ( para )
    return paragraphs


signature:
def is_highlink_density ( self , element ) :
    """checks the density of links within a node ,
 is there not much text and most of it contains linky shit ?
 if so it ' s no good"""

implementation:
links = self . parser . getElementsByTag ( element , tag = 'a' )
if not links :
    return False
text = self . parser . getText ( element )
words = text . split ( ' ' )
words_number = float ( len ( words ) )
link_text_parts = [ ]
for link in links :
    link_text_parts . append ( self . parser . getText ( link ) )
link_text = '' . join ( link_text_parts )
link_words = link_text . split ( ' ' )
number_of_link_words = float ( len ( link_words ) )
number_of_links = float ( len ( links ) )
link_divisor = float ( number_of_link_words / words_number )
score = float ( link_divisor * number_of_links )
if score >= 1.0 :
    return True
return False


signature:
def nodes_to_check ( self , docs ) :
    """returns a list of nodes we want to search
 on like paragraphs and tables"""

implementation:
nodes_to_check = [ ]
for doc in docs :
    for tag in [ 'p' , 'pre' , 'td' ] :
        items = self . parser . getElementsByTag ( doc , tag = tag )
        nodes_to_check += items
return nodes_to_check


signature:
def post_cleanup ( self ) :
    """remove any divs that looks like non - content ,
 clusters of links , or paras with no gusto"""

implementation:
parse_tags = [ 'p' ]
if self . config . parse_lists :
    parse_tags . extend ( [ 'ul' , 'ol' ] )
if self . config . parse_headers :
    parse_tags . extend ( [ 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' ] )
target_node = self . article . top_node
node = self . add_siblings ( target_node )
for elm in self . parser . getChildren ( node ) :
    e_tag = self . parser . getTag ( elm )
    if e_tag not in parse_tags :
        if ( self . is_highlink_density ( elm ) or self . is_table_and_no_para_exist ( elm ) or not self . is_nodescore_threshold_met ( node , elm ) ) :
            self . parser . remove ( elm )
return node


signature:
def infos ( self ) :
    '''dict : The summation of all data available about the extracted article
 Note :
 Read only'''

implementation:
data = { "meta" : { "description" : self . meta_description , "lang" : self . meta_lang , "keywords" : self . meta_keywords , "favicon" : self . meta_favicon , "canonical" : self . canonical_link , "encoding" : self . meta_encoding } , "image" : None , "domain" : self . domain , "title" : self . title , "cleaned_text" : self . cleaned_text , "opengraph" : self . opengraph , "tags" : self . tags , "tweets" : self . tweets , "movies" : [ ] , "links" : self . links , "authors" : self . authors , "publish_date" : self . publish_date }
# image
if self . top_image is not None :
    data [ 'image' ] = { 'url' : self . top_image . src , 'width' : self . top_image . width , 'height' : self . top_image . height , 'type' : 'image' }
# movies
for movie in self . movies :
    data [ 'movies' ] . append ( { 'embed_type' : movie . embed_type , 'provider' : movie . provider , 'width' : movie . width , 'height' : movie . height , 'embed_code' : movie . embed_code , 'src' : movie . src , } )
return data


signature:
def clean_title ( self , title ) :
    """Clean title with the use of og : site _ name
 in this case try to get rid of site name
 and use TITLE _ SPLITTERS to reformat title"""

implementation:
# check if we have the site name in opengraph data
if "site_name" in list ( self . article . opengraph . keys ( ) ) :
    site_name = self . article . opengraph [ 'site_name' ]
    # remove the site name from title
    title = title . replace ( site_name , '' ) . strip ( )
elif ( self . article . schema and "publisher" in self . article . schema and "name" in self . article . schema [ "publisher" ] ) :
    site_name = self . article . schema [ "publisher" ] [ "name" ]
    # remove the site name from title
    title = title . replace ( site_name , '' ) . strip ( )
# try to remove the domain from url
if self . article . domain :
    pattern = re . compile ( self . article . domain , re . IGNORECASE )
    title = pattern . sub ( "" , title ) . strip ( )
# split the title in words
# TechCrunch | my wonderfull article
# my wonderfull article | TechCrunch
title_words = title . split ( )
# check if first letter is in TITLE _ SPLITTERS
# if so remove it
if title_words and title_words [ 0 ] in TITLE_SPLITTERS :
    title_words . pop ( 0 )
# check for a title that is empty or consists of only a
# title splitter to avoid a IndexError below
if not title_words :
    return ""
# check if last letter is in TITLE _ SPLITTERS
# if so remove it
if title_words [ - 1 ] in TITLE_SPLITTERS :
    title_words . pop ( - 1 )
# rebuild the title
title = " " . join ( title_words ) . strip ( )
return title


signature:
def get_title ( self ) :
    """Fetch the article title and analyze it"""

implementation:
title = ''
# rely on opengraph in case we have the data
if "title" in list ( self . article . opengraph . keys ( ) ) :
    return self . clean_title ( self . article . opengraph [ 'title' ] )
elif self . article . schema and "headline" in self . article . schema :
    return self . clean_title ( self . article . schema [ 'headline' ] )
# try to fetch the meta headline
meta_headline = self . parser . getElementsByTag ( self . article . doc , tag = "meta" , attr = "name" , value = "headline" )
if meta_headline is not None and len ( meta_headline ) > 0 :
    title = self . parser . getAttribute ( meta_headline [ 0 ] , 'content' )
    return self . clean_title ( title )
# otherwise use the title meta
title_element = self . parser . getElementsByTag ( self . article . doc , tag = 'title' )
if title_element is not None and len ( title_element ) > 0 :
    title = self . parser . getText ( title_element [ 0 ] )
    return self . clean_title ( title )
return title


signature:
def get_canonical_link ( self ) :
    """if the article has meta canonical link set in the url"""

implementation:
if self . article . final_url :
    kwargs = { 'tag' : 'link' , 'attr' : 'rel' , 'value' : 'canonical' }
    meta = self . parser . getElementsByTag ( self . article . doc , ** kwargs )
    if meta is not None and len ( meta ) > 0 :
        href = self . parser . getAttribute ( meta [ 0 ] , 'href' )
        if href :
            href = href . strip ( )
            o = urlparse ( href )
            if not o . hostname :
                tmp = urlparse ( self . article . final_url )
                domain = '%s://%s' % ( tmp . scheme , tmp . hostname )
                href = urljoin ( domain , href )
            return href
return self . article . final_url


signature:
def make_list_elms_pretty ( self ) :
    """make any list element read like a list"""

implementation:
for elm in self . parser . getElementsByTag ( self . top_node , tag = 'li' ) :
    elm . text = r'• {}' . format ( elm . text )


signature:
def close ( self ) :
    '''Close the network connection and perform any other required cleanup
 Note :
 Auto closed when using goose as a context manager or when garbage collected'''

implementation:
if self . fetcher is not None :
    self . shutdown_network ( )
self . finalizer . atexit = False


signature:
def extract ( self , url = None , raw_html = None ) :
    '''Extract the most likely article content from the html page
 Args :
 url ( str ) : URL to pull and parse
 raw _ html ( str ) : String representation of the HTML page
 Returns :
 Article : Representation of the article contents including other parsed and extracted metadata'''

implementation:
crawl_candidate = CrawlCandidate ( self . config , url , raw_html )
return self . __crawl ( crawl_candidate )


signature:
def __crawl ( self , crawl_candidate ) :
    '''wrap the crawling functionality'''

implementation:
def crawler_wrapper ( parser , parsers_lst , crawl_candidate ) :
    try :
        crawler = Crawler ( self . config , self . fetcher )
        article = crawler . crawl ( crawl_candidate )
    except ( UnicodeDecodeError , ValueError ) as ex :
        if parsers_lst :
            parser = parsers_lst . pop ( 0 )
            # remove it also !
            return crawler_wrapper ( parser , parsers_lst , crawl_candidate )
        else :
            raise ex
    return article
# use the wrapper
parsers = list ( self . config . available_parsers )
parsers . remove ( self . config . parser_class )
return crawler_wrapper ( self . config . parser_class , parsers , crawl_candidate )


signature:
def smart_unicode ( string , encoding = 'utf-8' , strings_only = False , errors = 'strict' ) :
    """Returns a unicode object representing ' s ' . Treats bytestrings using the
 ' encoding ' codec .
 If strings _ only is True , don ' t convert ( some ) non - string - like objects ."""

implementation:
# if isinstance ( s , Promise ) :
# # The input is the result of a gettext _ lazy ( ) call .
# return s
return force_unicode ( string , encoding , strings_only , errors )


signature:
def force_unicode ( string , encoding = 'utf-8' , strings_only = False , errors = 'strict' ) :
    """Similar to smart _ unicode , except that lazy instances are resolved to
 strings , rather than kept as lazy objects .
 If strings _ only is True , don ' t convert ( some ) non - string - like objects ."""

implementation:
# Handle the common case first , saves 30-40 % in performance when s
# is an instance of unicode . This function gets called often in that
# setting .
if isinstance ( string , str ) :
    return string
if strings_only and is_protected_type ( string ) :
    return string
try :
    if not isinstance ( string , str ) :
        if hasattr ( string , '__unicode__' ) :
            string = string . __unicode__ ( )
        else :
            try :
                string = str ( string , encoding , errors )
            except UnicodeEncodeError :
                if not isinstance ( string , Exception ) :
                    raise
                # If we get to here , the caller has passed in an Exception
                # subclass populated with non - ASCII data without special
                # handling to display as a string . We need to handle this
                # without raising a further exception . We do an
                # approximation to what the Exception ' s standard str ( )
                # output should be .
                string = ' ' . join ( [ force_unicode ( arg , encoding , strings_only , errors ) for arg in string ] )
    elif not isinstance ( string , str ) : # Note : We use . decode ( ) here , instead of unicode ( s , encoding ,
    # errors ) , so that if s is a SafeString , it ends up being a
    # SafeUnicode at the end .
        string = string . decode ( encoding , errors )
except UnicodeDecodeError as ex :
    if not isinstance ( string , Exception ) :
        raise DjangoUnicodeDecodeError ( string , * ex . args )
    else : # If we get to here , the caller has passed in an Exception
    # subclass populated with non - ASCII bytestring data without a
    # working unicode method . Try to handle this without raising a
    # further exception by individually forcing the exception args
    # to unicode .
        string = ' ' . join ( [ force_unicode ( arg , encoding , strings_only , errors ) for arg in string ] )
return string


signature:
def smart_str ( string , encoding = 'utf-8' , strings_only = False , errors = 'strict' ) :
    """Returns a bytestring version of ' s ' , encoded as specified in ' encoding ' .
 If strings _ only is True , don ' t convert ( some ) non - string - like objects ."""

implementation:
if strings_only and isinstance ( string , ( type ( None ) , int ) ) :
    return string
# if isinstance ( s , Promise ) :
# return unicode ( s ) . encode ( encoding , errors )
if isinstance ( string , str ) :
    try :
        return string . encode ( encoding , errors )
    except UnicodeEncodeError :
        return string . encode ( 'utf-8' , errors )
elif not isinstance ( string , bytes ) :
    try :
        return str ( string ) . encode ( encoding , errors )
    except UnicodeEncodeError :
        if isinstance ( string , Exception ) : # An Exception subclass containing non - ASCII data that doesn ' t
        # know how to print itself properly . We shouldn ' t raise a
        # further exception .
            return ' ' . join ( [ smart_str ( arg , encoding , strings_only , errors ) for arg in string ] )
        return str ( string ) . encode ( encoding , errors )
else :
    return string


signature:
def get_urls ( self ) :
    """Add URLs needed to handle image uploads ."""

implementation:
urls = patterns ( '' , url ( r'^upload/$' , self . admin_site . admin_view ( self . handle_upload ) , name = 'quill-file-upload' ) , )
return urls + super ( QuillAdmin , self ) . get_urls ( )


signature:
def handle_upload ( self , request ) :
    """Handle file uploads from WYSIWYG ."""

implementation:
if request . method != 'POST' :
    raise Http404
if request . is_ajax ( ) :
    try :
        filename = request . GET [ 'quillUploadFile' ]
        data = request
        is_raw = True
    except KeyError :
        return HttpResponseBadRequest ( "Invalid file upload." )
else :
    if len ( request . FILES ) != 1 :
        return HttpResponseBadRequest ( "Can only upload 1 file at a time." )
    try :
        data = request . FILES [ 'quillUploadFile' ]
        filename = data . name
        is_raw = False
    except KeyError :
        return HttpResponseBadRequest ( 'Missing image `quillUploadFile`.' )
url = save_file ( data , filename , is_raw , default_storage )
response_data = { }
response_data [ 'url' ] = url
# Response content type needs to be text / html here or else
# IE will try to download the file .
return HttpResponse ( json . dumps ( response_data ) , content_type = "text/html; charset=utf-8" )


signature:
def render ( self , name , value , attrs = { } ) :
    """Render the Quill WYSIWYG ."""

implementation:
if value is None :
    value = ''
final_attrs = self . build_attrs ( attrs , name = name )
quill_app = apps . get_app_config ( 'quill' )
quill_config = getattr ( quill_app , self . config )
return mark_safe ( render_to_string ( quill_config [ 'template' ] , { 'final_attrs' : flatatt ( final_attrs ) , 'value' : value , 'id' : final_attrs [ 'id' ] , 'config' : self . config , } ) )


signature:
def formfield ( self , ** kwargs ) :
    """Get the form for field ."""

implementation:
defaults = { 'form_class' : RichTextFormField , 'config' : self . config , }
defaults . update ( kwargs )
return super ( RichTextField , self ) . formfield ( ** defaults )


signature:
def render_toolbar ( context , config ) :
    """Render the toolbar for the given config ."""

implementation:
quill_config = getattr ( quill_app , config )
t = template . loader . get_template ( quill_config [ 'toolbar_template' ] )
return t . render ( context )


signature:
def get_meta_image_url ( request , image ) :
    """Resize an image for metadata tags , and return an absolute URL to it ."""

implementation:
rendition = image . get_rendition ( filter = 'original' )
return request . build_absolute_uri ( rendition . url )


signature:
def read ( self , filename = None ) :
    """Read and parse mdp file * filename * ."""

implementation:
self . _init_filename ( filename )
def BLANK ( i ) :
    return "B{0:04d}" . format ( i )
def COMMENT ( i ) :
    return "C{0:04d}" . format ( i )
data = odict ( )
iblank = icomment = 0
with open ( self . real_filename ) as mdp :
    for line in mdp :
        line = line . strip ( )
        if len ( line ) == 0 :
            iblank += 1
            data [ BLANK ( iblank ) ] = ''
            continue
        m = self . COMMENT . match ( line )
        if m :
            icomment += 1
            data [ COMMENT ( icomment ) ] = m . group ( 'value' )
            continue
        # parameter
        m = self . PARAMETER . match ( line )
        if m : # check for comments after parameter ? ? - - currently discarded
            parameter = m . group ( 'parameter' )
            value = self . _transform ( m . group ( 'value' ) )
            data [ parameter ] = value
        else :
            errmsg = '{filename!r}: unknown line in mdp file, {line!r}' . format ( ** vars ( ) )
            self . logger . error ( errmsg )
            raise ParseError ( errmsg )
super ( MDP , self ) . update ( data )


signature:
def write ( self , filename = None , skipempty = False ) :
    """Write mdp file to * filename * .
 : Keywords :
 * filename *
 output mdp file ; default is the filename the mdp
 was read from
 * skipempty * : boolean
 ` ` True ` ` removes any parameter lines from output that
 contain empty values [ ` ` False ` ` ]
 . . Note : : Overwrites the file that the mdp was read from if no
 * filename * supplied ."""

implementation:
with open ( self . filename ( filename , ext = 'mdp' ) , 'w' ) as mdp :
    for k , v in self . items ( ) :
        if k [ 0 ] == 'B' : # blank line
            mdp . write ( "\n" )
        elif k [ 0 ] == 'C' : # comment
            mdp . write ( "; {v!s}\n" . format ( ** vars ( ) ) )
        else : # parameter = value
            if skipempty and ( v == '' or v is None ) :
                continue
            if isinstance ( v , six . string_types ) or not hasattr ( v , '__iter__' ) :
                mdp . write ( "{k!s} = {v!s}\n" . format ( ** vars ( ) ) )
            else :
                mdp . write ( "{} = {}\n" . format ( k , ' ' . join ( map ( str , v ) ) ) )


signature:
def find_gromacs_command ( commands ) :
    """Return * driver * and * name * of the first command that can be found on : envvar : ` PATH `"""

implementation:
# We could try executing ' name ' or ' driver name ' but to keep things lean we
# just check if the executables can be found and then hope for the best .
commands = utilities . asiterable ( commands )
for command in commands :
    try :
        driver , name = command . split ( )
    except ValueError :
        driver , name = None , command
    executable = driver if driver else name
    if utilities . which ( executable ) :
        break
else :
    raise OSError ( errno . ENOENT , "No Gromacs executable found in" , ", " . join ( commands ) )
return driver , name


signature:
def check_mdrun_success ( logfile ) :
    """Check if ` ` mdrun ` ` finished successfully .
 Analyses the output from ` ` mdrun ` ` in * logfile * . Right now we are
 simply looking for the line " Finished mdrun on node " in the last 1kb of
 the file . ( The file must be seeakable . )
 : Arguments :
 * logfile * : filename
 Logfile produced by ` ` mdrun ` ` .
 : Returns : ` ` True ` ` if all ok , ` ` False ` ` if not finished , and
 ` ` None ` ` if the * logfile * cannot be opened"""

implementation:
if not os . path . exists ( logfile ) :
    return None
with open ( logfile , 'rb' ) as log :
    log . seek ( - 1024 , 2 )
    for line in log :
        line = line . decode ( 'ASCII' )
        if line . startswith ( "Finished mdrun on" ) :
            return True
return False


signature:
def get_double_or_single_prec_mdrun ( ) :
    """Return double precision ` ` mdrun ` ` or fall back to single precision .
 This convenience function tries : func : ` gromacs . mdrun _ d ` first and
 if it cannot run it , falls back to : func : ` gromacs . mdrun ` ( without
 further checking ) .
 . . versionadded : : 0.5.1"""

implementation:
try :
    gromacs . mdrun_d ( h = True , stdout = False , stderr = False )
    logger . debug ( "using double precision gromacs.mdrun_d" )
    return gromacs . mdrun_d
except ( AttributeError , GromacsError , OSError ) : # fall back to mdrun if no double precision binary
    wmsg = "No 'mdrun_d' binary found so trying 'mdrun' instead.\n" "(Note that energy minimization runs better with mdrun_d.)"
    logger . warn ( wmsg )
    warnings . warn ( wmsg , category = AutoCorrectionWarning )
    return gromacs . mdrun


signature:
def commandline ( self , ** mpiargs ) :
    """Returns simple command line to invoke mdrun .
 If : attr : ` mpiexec ` is set then : meth : ` mpicommand ` provides the mpi
 launcher command that prefixes the actual ` ` mdrun ` ` invocation :
 : attr : ` mpiexec ` [ * mpiargs * ] : attr : ` mdrun ` [ * mdrun - args * ]
 The * mdrun - args * are set on initializing the class . Override
 : meth : ` mpicommand ` to fit your system if the simple default
 OpenMP launcher is not appropriate ."""

implementation:
cmd = self . MDRUN . commandline ( )
if self . mpiexec :
    cmd = self . mpicommand ( ** mpiargs ) + cmd
return cmd


signature:
def mpicommand ( self , * args , ** kwargs ) :
    """Return a list of the mpi command portion of the commandline .
 Only allows primitive mpi at the moment :
 * mpiexec * - n * ncores * * mdrun * * mdrun - args *
 ( This is a primitive example for OpenMP . Override it for more
 complicated cases . )"""

implementation:
if self . mpiexec is None :
    raise NotImplementedError ( "Override mpiexec to enable the simple OpenMP launcher" )
# example implementation
ncores = kwargs . pop ( 'ncores' , 8 )
return [ self . mpiexec , '-n' , str ( ncores ) ]


signature:
def run ( self , pre = None , post = None , mdrunargs = None , ** mpiargs ) :
    """Execute the mdrun command ( possibly as a MPI command ) and run the simulation .
 : Keywords :
 * pre *
 a dictionary containing keyword arguments for the : meth : ` prehook `
 * post *
 a dictionary containing keyword arguments for the : meth : ` posthook `
 * mdrunargs *
 a dictionary with keyword arguments for : program : ` mdrun ` which supersede
 * * and update * * the defaults given to the class constructor
 * mpiargs *
 all other keyword arguments that are processed by : meth : ` mpicommand `"""

implementation:
if pre is None :
    pre = { }
if post is None :
    post = { }
if mdrunargs is not None :
    try :
        self . MDRUN . gmxargs . update ( mdrunargs )
    except ( ValueError , TypeError ) :
        msg = "mdrunargs must be a dict of mdrun options, not {0}" . format ( mdrunargs )
        logger . error ( msg )
        raise
cmd = self . commandline ( ** mpiargs )
with utilities . in_dir ( self . dirname , create = False ) :
    try :
        self . prehook ( ** pre )
        logger . info ( " " . join ( cmd ) )
        rc = subprocess . call ( cmd )
    except :
        logger . exception ( "Failed MD run for unknown reasons." )
        raise
    finally :
        self . posthook ( ** post )
if rc == 0 :
    logger . info ( "MDrun completed ok, returncode = {0:d}" . format ( rc ) )
else :
    logger . critical ( "Failure in MDrun, returncode = {0:d}" . format ( rc ) )
return rc


signature:
def run_check ( self , ** kwargs ) :
    """Run : program : ` mdrun ` and check if run completed when it finishes .
 This works by looking at the mdrun log file for ' Finished
 mdrun on node ' . It is useful to implement robust simulation
 techniques .
 : Arguments :
 * kwargs * are keyword arguments that are passed on to
 : meth : ` run ` ( typically used for mpi things )
 : Returns :
 - ` ` True ` ` if run completed successfully
 - ` ` False ` ` otherwise"""

implementation:
rc = None
# set to something in case we ever want to look at it later ( and bomb in the try block )
try :
    rc = self . run ( ** kwargs )
except :
    logger . exception ( "run_check: caught exception" )
status = self . check_success ( )
if status :
    logger . info ( "run_check: Hooray! mdrun finished successfully" )
else :
    logger . error ( "run_check: mdrun failed to complete run" )
return status


signature:
def prehook ( self , ** kwargs ) :
    """Launch local smpd ."""

implementation:
cmd = [ 'smpd' , '-s' ]
logger . info ( "Starting smpd: " + " " . join ( cmd ) )
rc = subprocess . call ( cmd )
return rc


signature:
def _define_canned_commands ( ) :
    """Define functions for the top level name space .
 Definitions are collected here so that they can all be wrapped in
 a try - except block that avoids code failing when the Gromacs tools
 are not available - - - in some cases they are not necessary to use
 parts of GromacsWrapper .
 . . Note : : Any function defined here * * must be listed in ` ` global ` ` * * !"""

implementation:
global trj_compact , rmsd_backbone , trj_fitted , trj_xyfitted
trj_compact = tools . Trjconv ( ur = 'compact' , center = True , boxcenter = 'tric' , pbc = 'mol' , input = ( 'protein' , 'system' ) , doc = """
Writes a compact representation of the system centered on the protein""" )
rmsd_backbone = tools . G_rms ( what = 'rmsd' , fit = 'rot+trans' , input = ( 'Backbone' , 'Backbone' ) , doc = """
Computes RMSD of backbone after fitting to the backbone.""" )
trj_fitted = tools . Trjconv ( fit = 'rot+trans' , input = ( 'backbone' , 'system' ) , doc = """
Writes a trajectory fitted to the protein backbone.

Note that this does *not* center; if center is required, the *input*
selection should have the group to be centered on in second position,
e.g. ``input = ('backbone', 'Protein', System')``.
""" )
# Gromacs 4 . x
trj_xyfitted = tools . Trjconv ( fit = 'rotxy+transxy' , input = ( 'backbone' , 'protein' , 'system' ) , doc = """
Writes a trajectory fitted to the protein in the XY-plane only.

This is useful for membrane proteins. The system *must* be oriented so
that the membrane is in the XY plane. The protein backbone is used
for the least square fit, centering is done for the whole protein.

Note that centering together with fitting does not always work well
and that one sometimes need two runs of trjconv: one to center and
one to fit.

.. Note:: Gromacs 4.x only""" )


signature:
def trj_fitandcenter ( xy = False , ** kwargs ) :
    """Center everything and make a compact representation ( pass 1 ) and fit the system to a reference ( pass 2 ) .
 : Keywords :
 input structure file ( tpr file required to make molecule whole ) ;
 if a list or tuple is provided then s [ 0 ] is used for pass 1 ( should be a tpr )
 and s [ 1 ] is used for the fitting step ( can be a pdb of the whole system )
 If a second structure is supplied then it is assumed that the fitted
 trajectory should * not * be centered .
 input trajectory
 output trajectory
 * input *
 A list with three groups . The default is
 [ ' backbone ' , ' protein ' , ' system ' ]
 The fit command uses all three ( 1st for least square fit ,
 2nd for centering , 3rd for output ) , the centered / make - whole stage use
 2nd for centering and 3rd for output .
 * input1*
 If * input1 * is supplied then * input * is used exclusively
 for the fitting stage ( pass 2 ) and * input1 * for the centering ( pass 1 ) .
 Index file used for pass 1 and pass 2.
 * n1*
 If * n1 * is supplied then index * n1 * is only used for pass 1
 ( centering ) and * n * for pass 2 ( fitting ) .
 * xy * : boolean
 If ` ` True ` ` then only do a rot + trans fit in the xy plane
 ( good for membrane simulations ) ; default is ` ` False ` ` .
 * kwargs *
 All other arguments are passed to : class : ` ~ gromacs . tools . Trjconv ` .
 Note that here we first center the protein and create a compact box , using
 ` ` - pbc mol - ur compact - center - boxcenter tric ` ` and write an intermediate
 xtc . Then in a second pass we perform a rotation + translation fit ( or
 restricted to the xy plane if * xy * = ` ` True ` ` is set ) on the intermediate
 xtc to produce the final trajectory . Doing it in this order has the
 disadvantage that the solvent box is rotating around the protein but the
 opposite order ( with center / compact second ) produces strange artifacts
 where columns of solvent appear cut out from the box - - - it probably means
 that after rotation the information for the periodic boundaries is not
 correct any more .
 Most kwargs are passed to both invocations of
 : class : ` gromacs . tools . Trjconv ` so it does not really make sense to use eg
 * skip * ; in this case do things manually .
 By default the * input * to the fit command is ( ' backbone ' ,
 ' protein ' , ' system ' ) ; the compact command always uses the second and third
 group for its purposes or if this fails , prompts the user .
 Both steps cannot performed in one pass ; this is a known limitation of
 ` ` trjconv ` ` . An intermediate temporary XTC files is generated which should
 be automatically cleaned up unless bad things happened .
 The function tries to honour the input / output formats . For instance , if you
 want trr output you need to supply a trr file as input and explicitly give
 the output file also a trr suffix .
 . . Note : : For big trajectories it can * * take a very long time * *
 and consume a * * large amount of temporary diskspace * * .
 We follow the ` g _ spatial documentation ` _ in preparing the trajectories : :
 trjconv - s a . tpr - f a . xtc - o b . xtc - center - boxcenter tric - ur compact - pbc mol
 trjconv - s a . tpr - f b . xtc - o c . xtc - fit rot + trans
 . . _ ` g _ spatial documentation ` : http : / / www . gromacs . org / Documentation / Gromacs _ Utilities / g _ spatial"""

implementation:
if xy :
    fitmode = 'rotxy+transxy'
    kwargs . pop ( 'fit' , None )
else :
    fitmode = kwargs . pop ( 'fit' , 'rot+trans' )
# user can use progressive , too
intrj = kwargs . pop ( 'f' , None )
# get the correct suffix for the intermediate step : only trr will
# keep velocities / forces !
suffix = os . path . splitext ( intrj ) [ 1 ]
if not suffix in ( 'xtc' , 'trr' ) :
    suffix = '.xtc'
outtrj = kwargs . pop ( 'o' , None )
ndx = kwargs . pop ( 'n' , None )
ndxcompact = kwargs . pop ( 'n1' , ndx )
structures = kwargs . pop ( 's' , None )
if type ( structures ) in ( tuple , list ) :
    try :
        compact_structure , fit_structure = structures
    except :
        raise ValueError ( "argument s must be a pair of tpr/pdb files or a single structure file" )
else :
    compact_structure = fit_structure = structures
inpfit = kwargs . pop ( 'input' , ( 'backbone' , 'protein' , 'system' ) )
try :
    _inpcompact = inpfit [ 1 : ]
    # use 2nd and 3rd group for compact
except TypeError :
    _inpcompact = None
inpcompact = kwargs . pop ( 'input1' , _inpcompact )
# . . . or the user supplied ones
fd , tmptrj = tempfile . mkstemp ( suffix = suffix , prefix = 'pbc_compact_' )
logger . info ( "Input structure for PBC:  {compact_structure!r}" . format ( ** vars ( ) ) )
logger . info ( "Input structure for fit:  {fit_structure!r}" . format ( ** vars ( ) ) )
logger . info ( "Input trajectory:  {intrj!r}" . format ( ** vars ( ) ) )
logger . info ( "Output trajectory: {outtrj!r}" . format ( ** vars ( ) ) )
logger . debug ( "Writing temporary trajectory {tmptrj!r} (will be auto-cleaned)." . format ( ** vars ( ) ) )
sys . stdout . flush ( )
try :
    gromacs . trjconv ( s = compact_structure , f = intrj , o = tmptrj , n = ndxcompact , ur = 'compact' , center = True , boxcenter = 'tric' , pbc = 'mol' , input = inpcompact , ** kwargs )
    # explicitly set pbc = " none " for the fitting stage ( anything else will produce rubbish and / or
    # complaints from Gromacs )
    kwargs [ 'pbc' ] = "none"
    if compact_structure == fit_structure : # fit as ususal , including centering
    # ( Is center = True really necessary ? - - note , if I remove center = True then
    # I MUST fiddle inpfit as below ! ! )
        gromacs . trjconv ( s = fit_structure , f = tmptrj , o = outtrj , n = ndx , fit = fitmode , center = True , input = inpfit , ** kwargs )
    else : # make sure that we fit EXACTLY as the user wants
        inpfit = [ inpfit [ 0 ] , inpfit [ - 1 ] ]
        gromacs . trjconv ( s = fit_structure , f = tmptrj , o = outtrj , n = ndx , fit = fitmode , input = inpfit , ** kwargs )
finally :
    utilities . unlink_gmx ( tmptrj )


signature:
def cat ( prefix = "md" , dirname = os . path . curdir , partsdir = "parts" , fulldir = "full" , resolve_multi = "pass" ) :
    """Concatenate all parts of a simulation .
 The xtc , trr , and edr files in * dirname * such as prefix . xtc ,
 prefix . part0002 . xtc , prefix . part0003 . xtc , . . . are
 1 ) moved to the * partsdir * ( under * dirname * )
 2 ) concatenated with the Gromacs tools to yield prefix . xtc , prefix . trr ,
 prefix . edr , prefix . gro ( or prefix . md ) in * dirname *
 3 ) Store these trajectories in * fulldir *
 . . Note : : Trajectory files are * never * deleted by this function to avoid
 data loss in case of bugs . You will have to clean up yourself
 by deleting * dirname * / * partsdir * .
 Symlinks for the trajectories are * not * handled well and
 break the function . Use hard links instead .
 . . Warning : : If an exception occurs when running this function then make
 doubly and triply sure where your files are before running
 this function again ; otherwise you might * * overwrite data * * .
 Possibly you will need to manually move the files from * partsdir *
 back into the working directory * dirname * ; this should onlu overwrite
 generated files so far but * check carefully * !
 : Keywords :
 * prefix *
 deffnm of the trajectories [ md ]
 * resolve _ multi "
 how to deal with multiple " final " gro or pdb files : normally there should
 only be one but in case of restarting from the checkpoint of a finished
 simulation one can end up with multiple identical ones .
 - " pass " : do nothing and log a warning
 - " guess " : take prefix . pdb or prefix . gro if it exists , otherwise the one of
 prefix . partNNNN . gro | pdb with the highes NNNN
 * dirname *
 change to * dirname * and assume all tarjectories are located there [ . ]
 * partsdir *
 directory where to store the input files ( they are moved out of the way ) ;
 * partsdir * must be manually deleted [ parts ]
 * fulldir *
 directory where to store the final results [ full ]"""

implementation:
gmxcat = { 'xtc' : gromacs . trjcat , 'trr' : gromacs . trjcat , 'edr' : gromacs . eneconv , 'log' : utilities . cat , }
def _cat ( prefix , ext , partsdir = partsdir , fulldir = fulldir ) :
    filenames = glob_parts ( prefix , ext )
    if ext . startswith ( '.' ) :
        ext = ext [ 1 : ]
    outfile = os . path . join ( fulldir , prefix + '.' + ext )
    if not filenames :
        return None
    nonempty_files = [ ]
    for f in filenames :
        if os . stat ( f ) . st_size == 0 :
            logger . warn ( "File {f!r} is empty, skipping" . format ( ** vars ( ) ) )
            continue
        if os . path . islink ( f ) : # TODO : re - write the symlink to point to the original file
            errmsg = "Symbolic links do not work (file %(f)r), sorry. " "CHECK LOCATION OF FILES MANUALLY BEFORE RUNNING gromacs.cbook.cat() AGAIN!" % vars ( )
            logger . exception ( errmsg )
            raise NotImplementedError ( errmsg )
        shutil . move ( f , partsdir )
        nonempty_files . append ( f )
    filepaths = [ os . path . join ( partsdir , f ) for f in nonempty_files ]
    gmxcat [ ext ] ( f = filepaths , o = outfile )
    return outfile
_resolve_options = ( "pass" , "guess" )
if not resolve_multi in _resolve_options :
    raise ValueError ( "resolve_multi must be one of %(_resolve_options)r, " "not %(resolve_multi)r" % vars ( ) )
if fulldir == os . path . curdir :
    wmsg = "Using the current directory as fulldir can potentially lead to data loss if you run this function multiple times."
    logger . warning ( wmsg )
    warnings . warn ( wmsg , category = BadParameterWarning )
with utilities . in_dir ( dirname , create = False ) :
    utilities . mkdir_p ( partsdir )
    utilities . mkdir_p ( fulldir )
    for ext in ( 'log' , 'edr' , 'trr' , 'xtc' ) :
        logger . info ( "[%(dirname)s] concatenating %(ext)s files..." , vars ( ) )
        outfile = _cat ( prefix , ext , partsdir )
        logger . info ( "[%(dirname)s] created %(outfile)r" , vars ( ) )
    for ext in ( 'gro' , 'pdb' ) : # XXX : ugly , make method out of parts ?
        filenames = glob_parts ( prefix , ext )
        if len ( filenames ) == 0 :
            continue
            # goto next ext
        elif len ( filenames ) == 1 :
            pick = filenames [ 0 ]
        else :
            if resolve_multi == "pass" :
                logger . warning ( "[%(dirname)s] too many output structures %(filenames)r, " "cannot decide which one --- resolve manually!" , vars ( ) )
                for f in filenames :
                    shutil . move ( f , partsdir )
                continue
                # goto next ext
            elif resolve_multi == "guess" :
                pick = prefix + '.' + ext
                if not pick in filenames :
                    pick = filenames [ - 1 ]
                    # filenames are ordered with highest parts at end
        final = os . path . join ( fulldir , prefix + '.' + ext )
        shutil . copy ( pick , final )
        # copy2 fails on nfs with Darwin at least
        for f in filenames :
            shutil . move ( f , partsdir )
        logger . info ( "[%(dirname)s] collected final structure %(final)r " "(from %(pick)r)" , vars ( ) )
partsdirpath = utilities . realpath ( dirname , partsdir )
logger . warn ( "[%(dirname)s] cat() complete in %(fulldir)r but original files " "in %(partsdirpath)r must be manually removed" , vars ( ) )


signature:
def glob_parts ( prefix , ext ) :
    """Find files from a continuation run"""

implementation:
if ext . startswith ( '.' ) :
    ext = ext [ 1 : ]
files = glob . glob ( prefix + '.' + ext ) + glob . glob ( prefix + '.part[0-9][0-9][0-9][0-9].' + ext )
files . sort ( )
# at least some rough sorting . . .
return files


signature:
def grompp_qtot ( * args , ** kwargs ) :
    """Run ` ` gromacs . grompp ` ` and return the total charge of the system .
 : Arguments :
 The arguments are the ones one would pass to : func : ` gromacs . grompp ` .
 : Returns :
 The total charge as reported
 Some things to keep in mind :
 * The stdout output of grompp is only shown when an error occurs . For
 debugging , look at the log file or screen output and try running the
 normal : func : ` gromacs . grompp ` command and analyze the output if the
 debugging messages are not sufficient .
 * Check that ` ` qtot ` ` is correct . Because the function is based on pattern
 matching of the informative output of : program : ` grompp ` it can break when
 the output format changes . This version recognizes lines like : :
 ' System has non - zero total charge : - 4.000001e + 00'
 using the regular expression
 : regexp : ` System has non - zero total charge : * ( ? P < qtot > [ - + ] ? \ d * \ . \ d + ( [ eE ] [ - + ] \ d + ) ? ) ` ."""

implementation:
qtot_pattern = re . compile ( 'System has non-zero total charge: *(?P<qtot>[-+]?\d*\.\d+([eE][-+]\d+)?)' )
# make sure to capture ALL output
kwargs [ 'stdout' ] = False
kwargs [ 'stderr' ] = False
rc , output , error = grompp_warnonly ( * args , ** kwargs )
gmxoutput = "\n" . join ( [ x for x in [ output , error ] if x is not None ] )
if rc != 0 : # error occured and we want to see the whole output for debugging
    msg = "grompp_qtot() failed. See warning and screen output for clues."
    logger . error ( msg )
    import sys
    sys . stderr . write ( "=========== grompp (stdout/stderr) ============\n" )
    sys . stderr . write ( gmxoutput )
    sys . stderr . write ( "===============================================\n" )
    sys . stderr . flush ( )
    raise GromacsError ( rc , msg )
qtot = 0
for line in gmxoutput . split ( '\n' ) :
    m = qtot_pattern . search ( line )
    if m :
        qtot = float ( m . group ( 'qtot' ) )
        break
logger . info ( "system total charge qtot = {qtot!r}" . format ( ** vars ( ) ) )
return qtot


signature:
def _mdp_include_string ( dirs ) :
    """Generate a string that can be added to a mdp ' include = ' line ."""

implementation:
include_paths = [ os . path . expanduser ( p ) for p in dirs ]
return ' -I' . join ( [ '' ] + include_paths )


signature:
def add_mdp_includes ( topology = None , kwargs = None ) :
    """Set the mdp * include * key in the * kwargs * dict .
 1 . Add the directory containing * topology * .
 2 . Add all directories appearing under the key * includes *
 3 . Generate a string of the form " - Idir1 - Idir2 . . . " that
 is stored under the key * include * ( the corresponding
 mdp parameter )
 By default , the directories ` ` . ` ` and ` ` . . ` ` are also added to the
 * include * string for the mdp ; when fed into
 : func : ` gromacs . cbook . edit _ mdp ` it will result in a line such as : :
 include = - I . - I . . - I . . / topology _ dir . . . .
 Note that the user can always override the behaviour by setting
 the * include * keyword herself ; in this case this function does
 nothing .
 If no * kwargs * were supplied then a dict is generated with the
 single * include * entry .
 : Arguments :
 * topology * : top filename
 Topology file ; the name of the enclosing directory is added
 to the include path ( if supplied ) [ ` ` None ` ` ]
 * kwargs * : dict
 Optional dictionary of mdp keywords ; will be modified in place .
 If it contains the * includes * keyword with either a single string
 or a list of strings then these paths will be added to the
 include statement .
 : Returns : * kwargs * with the * include * keyword added if it did not
 exist previously ; if the keyword already existed , nothing
 happens .
 . . Note : : The * kwargs * dict is * * modified in place * * . This
 function is a bit of a hack . It might be removed once
 all setup functions become methods in a nice class ."""

implementation:
if kwargs is None :
    kwargs = { }
include_dirs = [ '.' , '..' ]
# should . & . . always be added ?
if topology is not None : # half - hack : find additional itps in the same directory as the topology
    topology_dir = os . path . dirname ( topology )
    include_dirs . append ( topology_dir )
include_dirs . extend ( asiterable ( kwargs . pop ( 'includes' , [ ] ) ) )
# includes can be a list or a string
# 1 . setdefault : we do nothing if user defined include
# 2 . modify input in place !
kwargs . setdefault ( 'include' , _mdp_include_string ( include_dirs ) )
return kwargs


signature:
def filter_grompp_options ( ** kwargs ) :
    """Returns one dictionary only containing valid : program : ` grompp ` options and everything else .
 Option list is hard coded and nased on : class : ` ~ gromacs . tools . grompp ` 4.5.3.
 : Returns : ` ` ( grompp _ dict , other _ dict ) ` `
 . . versionadded : : 0.2.4"""

implementation:
grompp_options = ( 'f' , 'po' , 'c' , 'r' , 'rb' , 'n' , 'p' , 'pp' , 'o' , 't' , 'e' , # files
'h' , 'noh' , 'version' , 'noversion' , 'nice' , 'v' , 'nov' , 'time' , 'rmvsbds' , 'normvsbds' , 'maxwarn' , 'zero' , 'nozero' , 'renum' , 'norenum' )
grompp = dict ( ( k , v ) for k , v in kwargs . items ( ) if k in grompp_options )
other = dict ( ( k , v ) for k , v in kwargs . items ( ) if k not in grompp_options )
return grompp , other


signature:
def create_portable_topology ( topol , struct , ** kwargs ) :
    """Create a processed topology .
 The processed ( or portable ) topology file does not contain any
 ` ` # include ` ` statements and hence can be easily copied around . It
 also makes it possible to re - grompp without having any special itp
 files available .
 : Arguments :
 * topol *
 topology file
 * struct *
 coordinat ( structure ) file
 : Keywords :
 * processed *
 name of the new topology file ; if not set then it is named like
 * topol * but with ` ` pp _ ` ` prepended
 * includes *
 path or list of paths of directories in which itp files are
 searched for
 * grompp _ kwargs * *
 other options for : program : ` grompp ` such as ` ` maxwarn = 2 ` ` can
 also be supplied
 : Returns : full path to the processed topology"""

implementation:
_topoldir , _topol = os . path . split ( topol )
processed = kwargs . pop ( 'processed' , os . path . join ( _topoldir , 'pp_' + _topol ) )
grompp_kwargs , mdp_kwargs = filter_grompp_options ( ** kwargs )
mdp_kwargs = add_mdp_includes ( topol , mdp_kwargs )
with tempfile . NamedTemporaryFile ( suffix = '.mdp' ) as mdp :
    mdp . write ( '; empty mdp file\ninclude = {include!s}\n' . format ( ** mdp_kwargs ) )
    mdp . flush ( )
    grompp_kwargs [ 'p' ] = topol
    grompp_kwargs [ 'pp' ] = processed
    grompp_kwargs [ 'f' ] = mdp . name
    grompp_kwargs [ 'c' ] = struct
    grompp_kwargs [ 'v' ] = False
    try :
        gromacs . grompp ( ** grompp_kwargs )
    finally :
        utilities . unlink_gmx ( 'topol.tpr' , 'mdout.mdp' )
return utilities . realpath ( processed )


signature:
def get_volume ( f ) :
    """Return the volume in nm ^ 3 of structure file * f * .
 ( Uses : func : ` gromacs . editconf ` ; error handling is not good )"""

implementation:
fd , temp = tempfile . mkstemp ( '.gro' )
try :
    rc , out , err = gromacs . editconf ( f = f , o = temp , stdout = False )
finally :
    os . unlink ( temp )
return [ float ( x . split ( ) [ 1 ] ) for x in out . splitlines ( ) if x . startswith ( 'Volume:' ) ] [ 0 ]


signature:
def edit_txt ( filename , substitutions , newname = None ) :
    """Primitive text file stream editor .
 This function can be used to edit free - form text files such as the
 topology file . By default it does an * * in - place edit * * of
 * filename * . If * newname * is supplied then the edited
 file is written to * newname * .
 : Arguments :
 * filename *
 input text file
 * substitutions *
 substitution commands ( see below for format )
 * newname *
 output filename ; if ` ` None ` ` then * filename * is changed in
 place [ ` ` None ` ` ]
 * substitutions * is a list of triplets ; the first two elements are regular
 expression strings , the last is the substitution value . It mimics
 ` ` sed ` ` search and replace . The rules for * substitutions * :
 . . productionlist : :
 substitutions : " [ " search _ replace _ tuple , . . . " ] "
 search _ replace _ tuple : " ( " line _ match _ RE " , " search _ RE " , " replacement " ) "
 line _ match _ RE : regular expression that selects the line ( uses match )
 search _ RE : regular expression that is searched in the line
 replacement : replacement string for search _ RE
 Running : func : ` edit _ txt ` does pretty much what a simple : :
 sed / line _ match _ RE / s / search _ RE / replacement /
 with repeated substitution commands does .
 Special replacement values :
 - ` ` None ` ` : the rule is ignored
 - ` ` False ` ` : the line is deleted ( even if other rules match )
 . . note : :
 * No sanity checks are performed and the substitutions must be supplied
 exactly as shown .
 * All substitutions are applied to a line ; thus the order of the substitution
 commands may matter when one substitution generates a match for a subsequent rule .
 * If replacement is set to ` ` None ` ` then the whole expression is ignored and
 whatever is in the template is used . To unset values you must provided an
 empty string or similar .
 * Delete a matching line if replacement = ` ` False ` ` ."""

implementation:
if newname is None :
    newname = filename
# No sanity checks ( figure out later how to give decent diagnostics ) .
# Filter out any rules that have None in replacement .
_substitutions = [ { 'lRE' : re . compile ( str ( lRE ) ) , 'sRE' : re . compile ( str ( sRE ) ) , 'repl' : repl } for lRE , sRE , repl in substitutions if repl is not None ]
with tempfile . TemporaryFile ( ) as target :
    with open ( filename , 'rb' ) as src :
        logger . info ( "editing txt = {0!r} ({1:d} substitutions)" . format ( filename , len ( substitutions ) ) )
        for line in src :
            line = line . decode ( "utf-8" )
            keep_line = True
            for subst in _substitutions :
                m = subst [ 'lRE' ] . match ( line )
                if m : # apply substition to this line ?
                    logger . debug ( 'match:    ' + line . rstrip ( ) )
                    if subst [ 'repl' ] is False : # special rule : delete line
                        keep_line = False
                    else : # standard replacement
                        line = subst [ 'sRE' ] . sub ( str ( subst [ 'repl' ] ) , line )
                        logger . debug ( 'replaced: ' + line . rstrip ( ) )
            if keep_line :
                target . write ( line . encode ( 'utf-8' ) )
            else :
                logger . debug ( "Deleting line %r" , line )
    target . seek ( 0 )
    with open ( newname , 'wb' ) as final :
        shutil . copyfileobj ( target , final )
logger . info ( "edited txt = {newname!r}" . format ( ** vars ( ) ) )


signature:
def remove_molecules_from_topology ( filename , ** kwargs ) :
    """Remove autogenerated [ molecules ] entries from * filename * .
 Valid entries in ` ` [ molecules ] ` ` below the default * marker *
 are removed . For example , a topology file such as : :
 [ molecules ]
 Protein 1
 SOL 213
 ; The next line is the marker !
 ; Gromacs auto - generated entries follow :
 SOL 12345
 NA + 15
 CL - 16
 ; This is a comment that is NOT deleted .
 SOL 333
 would become : :
 [ molecules ]
 Protein 1
 SOL 213
 ; The next line is the marker !
 ; Gromacs auto - generated entries follow :
 ; This is a comment that is NOT deleted .
 Valid molecule lines look like ` ` SOL 1234 ` ` , ` ` NA 17 ` ` etc . The
 actual regular expression used is " \ s * [ \ w + _ - ] + \ s + \ d + \ s * ( ; . * ) ? $ " .
 In order to use this function , the marker line has to be manually
 added to the topology file .
 : Arguments :
 * filename *
 The topology file that includes the ` ` [ molecules ] ` ` section .
 It is * * edited in place * * .
 * marker *
 Any ` ` [ molecules ] ` ` entries below this pattern ( python regular
 expression ) are removed . Leading white space is ignored . ` ` None ` `
 uses the default as described above ."""

implementation:
marker = kwargs . pop ( 'marker' , None )
if marker is None :
    marker = "; Gromacs auto-generated entries follow:"
logger . debug ( "Scrubbed [ molecules ]: marker = %(marker)r" , vars ( ) )
p_marker = re . compile ( "\s*{0!s}" . format ( marker ) )
p_molecule = re . compile ( "\s*[\w+_-]+\s+\d+\s*(;.*)?$" )
with tempfile . TemporaryFile ( ) as target :
    with open ( filename , 'rb' ) as src :
        autogenerated = False
        n_removed = 0
        for line in src :
            line = line . decode ( 'utf-8' )
            if p_marker . match ( line ) :
                autogenerated = True
            if autogenerated and p_molecule . match ( line ) :
                n_removed += 1
                continue
                # remove by skipping
            target . write ( line . encode ( 'utf-8' ) )
    if autogenerated and n_removed > 0 :
        target . seek ( 0 )
        with open ( filename , 'wb' ) as final : # overwrite original !
            shutil . copyfileobj ( target , final )
        logger . info ( "Removed %(n_removed)d autogenerated [ molecules ] from " "topol = %(filename)r" % vars ( ) )
return n_removed


signature:
def make_ndx_captured ( ** kwargs ) :
    """make _ ndx that captures all output
 Standard : func : ` ~ gromacs . make _ ndx ` command with the input and
 output pre - set in such a way that it can be conveniently used for
 : func : ` parse _ ndxlist ` .
 Example : :
 ndx _ groups = parse _ ndxlist ( make _ ndx _ captured ( n = ndx ) [ 0 ] )
 Note that the convenient : func : ` get _ ndx _ groups ` function does exactly
 that and can probably used in most cases .
 : Arguments :
 keywords are passed on to : func : ` ~ gromacs . make _ ndx `
 : Returns :
 ( * returncode * , * output * , ` ` None ` ` )"""

implementation:
kwargs [ 'stdout' ] = False
# required for proper output as described in doc
user_input = kwargs . pop ( 'input' , [ ] )
user_input = [ cmd for cmd in user_input if cmd != 'q' ]
# filter any quit
kwargs [ 'input' ] = user_input + [ '' , 'q' ]
# necessary commands
return gromacs . make_ndx ( ** kwargs )


signature:
def get_ndx_groups ( ndx , ** kwargs ) :
    """Return a list of index groups in the index file * ndx * .
 : Arguments :
 - * ndx * is a Gromacs index file .
 - kwargs are passed to : func : ` make _ ndx _ captured ` .
 : Returns :
 list of groups as supplied by : func : ` parse _ ndxlist `
 Alternatively , load the index file with
 : class : ` gromacs . formats . NDX ` for full control ."""

implementation:
fd , tmp_ndx = tempfile . mkstemp ( suffix = '.ndx' )
kwargs [ 'o' ] = tmp_ndx
try :
    g = parse_ndxlist ( make_ndx_captured ( n = ndx , ** kwargs ) [ 1 ] )
finally :
    utilities . unlink_gmx ( tmp_ndx )
return g


signature:
def parse_ndxlist ( output ) :
    """Parse output from make _ ndx to build list of index groups : :
 groups = parse _ ndxlist ( output )
 output should be the standard output from ` ` make _ ndx ` ` , e . g . : :
 rc , output , junk = gromacs . make _ ndx ( . . . , input = ( ' ' , ' q ' ) , stdout = False , stderr = True )
 ( or simply use
 rc , output , junk = cbook . make _ ndx _ captured ( . . . )
 which presets input , stdout and stderr ; of course input can be overriden . )
 : Returns :
 The function returns a list of dicts ( ` ` groups ` ` ) with fields
 name
 name of the groups
 nr
 number of the group ( starts at 0)
 natoms
 number of atoms in the group"""

implementation:
m = NDXLIST . search ( output )
# make sure we pick up a proper full list
grouplist = m . group ( 'LIST' )
return parse_groups ( grouplist )


signature:
def parse_groups ( output ) :
    """Parse ` ` make _ ndx ` ` output and return groups as a list of dicts ."""

implementation:
groups = [ ]
for line in output . split ( '\n' ) :
    m = NDXGROUP . match ( line )
    if m :
        d = m . groupdict ( )
        groups . append ( { 'name' : d [ 'GROUPNAME' ] , 'nr' : int ( d [ 'GROUPNUMBER' ] ) , 'natoms' : int ( d [ 'NATOMS' ] ) } )
return groups


signature:
def delete_frames ( self ) :
    """Delete all frames ."""

implementation:
for frame in glob . glob ( self . frameglob ) :
    os . unlink ( frame )


signature:
def gmx_resid ( self , resid ) :
    """Returns resid in the Gromacs index by transforming with offset ."""

implementation:
try :
    gmx_resid = int ( self . offset [ resid ] )
except ( TypeError , IndexError ) :
    gmx_resid = resid + self . offset
except KeyError :
    raise KeyError ( "offset must be a dict that contains the gmx resid for {0:d}" . format ( resid ) )
return gmx_resid


signature:
def combine ( self , name_all = None , out_ndx = None , operation = '|' , defaultgroups = False ) :
    """Combine individual groups into a single one and write output .
 : Keywords :
 name _ all : string
 Name of the combined group , ` ` None ` ` generates a name . [ ` ` None ` ` ]
 out _ ndx : filename
 Name of the output file that will contain the individual groups
 and the combined group . If ` ` None ` ` then default from the class
 constructor is used . [ ` ` None ` ` ]
 operation : character
 Logical operation that is used to generate the combined group from
 the individual groups : " | " ( OR ) or " & " ( AND ) ; if set to ` ` False ` `
 then no combined group is created and only the individual groups
 are written . [ " | " ]
 defaultgroups : bool
 ` ` True ` ` : append everything to the default groups produced by
 : program : ` make _ ndx ` ( or rather , the groups provided in the ndx file on
 initialization - - - if this was ` ` None ` ` then these are truly default groups ) ;
 ` ` False ` ` : only use the generated groups
 : Returns :
 ` ` ( combinedgroup _ name , output _ ndx ) ` ` , a tuple showing the
 actual group name and the name of the file ; useful when all names are autogenerated .
 . . Warning : : The order of the atom numbers in the combined group is
 * not * guaranteed to be the same as the selections on input because
 ` ` make _ ndx ` ` sorts them ascending . Thus you should be careful when
 using these index files for calculations of angles and dihedrals .
 Use : class : ` gromacs . formats . NDX ` in these cases .
 . . SeeAlso : : : meth : ` IndexBuilder . write ` ."""

implementation:
if not operation in ( '|' , '&' , False ) :
    raise ValueError ( "Illegal operation {0!r}, only '|' (OR) and '&' (AND) or False allowed." . format ( operation ) )
if name_all is None and operation :
    name_all = self . name_all or operation . join ( self . indexfiles )
if out_ndx is None :
    out_ndx = self . output
if defaultgroups : # make a default file ( using the original ndx where provided ! ! )
    fd , default_ndx = tempfile . mkstemp ( suffix = '.ndx' , prefix = 'default__' )
    try :
        self . make_ndx ( o = default_ndx , input = [ 'q' ] )
    except :
        utilities . unlink_gmx ( default_ndx )
        raise
    ndxfiles = [ default_ndx ]
else :
    ndxfiles = [ ]
ndxfiles . extend ( self . indexfiles . values ( ) )
if operation : # combine multiple selections and name them
    try :
        fd , tmp_ndx = tempfile . mkstemp ( suffix = '.ndx' , prefix = 'combined__' )
        # combine all selections by loading ALL temporary index files
        operation = ' ' + operation . strip ( ) + ' '
        cmd = [ operation . join ( [ '"{0!s}"' . format ( gname ) for gname in self . indexfiles ] ) , '' , 'q' ]
        rc , out , err = self . make_ndx ( n = ndxfiles , o = tmp_ndx , input = cmd )
        if self . _is_empty_group ( out ) :
            warnings . warn ( "No atoms found for {cmd!r}" . format ( ** vars ( ) ) , category = BadParameterWarning )
        # second pass for naming , sigh ( or : use NDX ? )
        groups = parse_ndxlist ( out )
        last = groups [ - 1 ]
        # name this group
        name_cmd = [ "name {0:d} {1!s}" . format ( last [ 'nr' ] , name_all ) , 'q' ]
        rc , out , err = self . make_ndx ( n = tmp_ndx , o = out_ndx , input = name_cmd )
        # For debugging , look at out and err or set stdout = True , stderr = True
        # TODO : check out if at least 1 atom selected
        # # print " DEBUG : combine ( ) "
        # # print out
    finally :
        utilities . unlink_gmx ( tmp_ndx )
        if defaultgroups :
            utilities . unlink_gmx ( default_ndx )
else : # just write individual groups in one file ( name _ all - - > None )
    rc , out , err = self . make_ndx ( n = ndxfiles , o = out_ndx , input = [ '' , 'q' ] )
return name_all , out_ndx


signature:
def write ( self , out_ndx = None , defaultgroups = False ) :
    """Write individual ( named ) groups to * out _ ndx * ."""

implementation:
name_all , out_ndx = self . combine ( operation = False , out_ndx = out_ndx , defaultgroups = defaultgroups )
return out_ndx


signature:
def cat ( self , out_ndx = None ) :
    """Concatenate input index files .
 Generate a new index file that contains the default Gromacs index
 groups ( if a structure file was defined ) and all index groups from the
 input index files .
 : Arguments :
 out _ ndx : filename
 Name of the output index file ; if ` ` None ` ` then use the default
 provided to the constructore . [ ` ` None ` ` ] ."""

implementation:
if out_ndx is None :
    out_ndx = self . output
self . make_ndx ( o = out_ndx , input = [ 'q' ] )
return out_ndx


signature:
def parse_selection ( self , selection , name = None ) :
    """Retuns ( groupname , filename ) with index group ."""

implementation:
if type ( selection ) is tuple : # range
    process = self . _process_range
elif selection . startswith ( '@' ) : # verbatim make _ ndx command
    process = self . _process_command
    selection = selection [ 1 : ]
else :
    process = self . _process_residue
return process ( selection , name )


signature:
def _process_command ( self , command , name = None ) :
    """Process ` ` make _ ndx ` ` command and return name and temp index file ."""

implementation:
self . _command_counter += 1
if name is None :
    name = "CMD{0:03d}" . format ( self . _command_counter )
# Need to build it with two make _ ndx calls because I cannot reliably
# name the new group without knowing its number .
try :
    fd , tmp_ndx = tempfile . mkstemp ( suffix = '.ndx' , prefix = 'tmp_' + name + '__' )
    cmd = [ command , '' , 'q' ]
    # empty command ' ' necessary to get list
    # This sometimes fails with ' OSError : Broken Pipe ' - - - hard to debug
    rc , out , err = self . make_ndx ( o = tmp_ndx , input = cmd )
    self . check_output ( out , "No atoms found for selection {command!r}." . format ( ** vars ( ) ) , err = err )
    # For debugging , look at out and err or set stdout = True , stderr = True
    # TODO : check ' 0 r _ 300 _ & _ ALA _ & _ O : 1 atoms ' has at least 1 atom
    # # print " DEBUG : _ process _ command ( ) "
    # # print out
    groups = parse_ndxlist ( out )
    last = groups [ - 1 ]
    # reduce and name this group
    fd , ndx = tempfile . mkstemp ( suffix = '.ndx' , prefix = name + '__' )
    name_cmd = [ "keep {0:d}" . format ( last [ 'nr' ] ) , "name 0 {0!s}" . format ( name ) , 'q' ]
    rc , out , err = self . make_ndx ( n = tmp_ndx , o = ndx , input = name_cmd )
finally :
    utilities . unlink_gmx ( tmp_ndx )
return name , ndx


signature:
def _process_residue ( self , selection , name = None ) :
    """Process residue / atom selection and return name and temp index file ."""

implementation:
if name is None :
    name = selection . replace ( ':' , '_' )
# XXX : use _ translate _ residue ( ) . . . .
m = self . RESIDUE . match ( selection )
if not m :
    raise ValueError ( "Selection {selection!r} is not valid." . format ( ** vars ( ) ) )
gmx_resid = self . gmx_resid ( int ( m . group ( 'resid' ) ) )
residue = m . group ( 'aa' )
if len ( residue ) == 1 :
    gmx_resname = utilities . convert_aa_code ( residue )
    # only works for AA
else :
    gmx_resname = residue
    # use 3 - letter for any resname
gmx_atomname = m . group ( 'atom' )
if gmx_atomname is None :
    gmx_atomname = 'CA'
# : select residue < gmx _ resname > < gmx _ resid > atom < gmx _ atomname >
_selection = 'r {gmx_resid:d} & r {gmx_resname!s} & a {gmx_atomname!s}' . format ( ** vars ( ) )
cmd = [ 'keep 0' , 'del 0' , _selection , 'name 0 {name!s}' . format ( ** vars ( ) ) , 'q' ]
fd , ndx = tempfile . mkstemp ( suffix = '.ndx' , prefix = name + '__' )
rc , out , err = self . make_ndx ( n = self . ndx , o = ndx , input = cmd )
self . check_output ( out , "No atoms found for " "%(selection)r --> %(_selection)r" % vars ( ) )
# For debugging , look at out and err or set stdout = True , stderr = True
# # print " DEBUG : _ process _ residue ( ) "
# # print out
return name , ndx


signature:
def _process_range ( self , selection , name = None ) :
    """Process a range selection .
 ( " S234 " , " A300 " , " CA " ) - - > selected all CA in this range
 ( " S234 " , " A300 " ) - - > selected all atoms in this range
 . . Note : : Ignores residue type , only cares about the resid ( but still required )"""

implementation:
try :
    first , last , gmx_atomname = selection
except ValueError :
    try :
        first , last = selection
        gmx_atomname = '*'
    except :
        logger . error ( "%r is not a valid range selection" , selection )
        raise
if name is None :
    name = "{first!s}-{last!s}_{gmx_atomname!s}" . format ( ** vars ( ) )
_first = self . _translate_residue ( first , default_atomname = gmx_atomname )
_last = self . _translate_residue ( last , default_atomname = gmx_atomname )
_selection = 'r {0:d} - {1:d} & & a {2!s}' . format ( _first [ 'resid' ] , _last [ 'resid' ] , gmx_atomname )
cmd = [ 'keep 0' , 'del 0' , _selection , 'name 0 {name!s}' . format ( ** vars ( ) ) , 'q' ]
fd , ndx = tempfile . mkstemp ( suffix = '.ndx' , prefix = name + '__' )
rc , out , err = self . make_ndx ( n = self . ndx , o = ndx , input = cmd )
self . check_output ( out , "No atoms found for " "%(selection)r --> %(_selection)r" % vars ( ) )
# For debugging , look at out and err or set stdout = True , stderr = True
# # print " DEBUG : _ process _ residue ( ) "
# # print out
return name , ndx


signature:
def _translate_residue ( self , selection , default_atomname = 'CA' ) :
    """Translate selection for a single res to make _ ndx syntax ."""

implementation:
m = self . RESIDUE . match ( selection )
if not m :
    errmsg = "Selection {selection!r} is not valid." . format ( ** vars ( ) )
    logger . error ( errmsg )
    raise ValueError ( errmsg )
gmx_resid = self . gmx_resid ( int ( m . group ( 'resid' ) ) )
# magic offset correction
residue = m . group ( 'aa' )
if len ( residue ) == 1 :
    gmx_resname = utilities . convert_aa_code ( residue )
    # only works for AA
else :
    gmx_resname = residue
    # use 3 - letter for any resname
gmx_atomname = m . group ( 'atom' )
if gmx_atomname is None :
    gmx_atomname = default_atomname
return { 'resname' : gmx_resname , 'resid' : gmx_resid , 'atomname' : gmx_atomname }


signature:
def check_output ( self , make_ndx_output , message = None , err = None ) :
    """Simple tests to flag problems with a ` ` make _ ndx ` ` run ."""

implementation:
if message is None :
    message = ""
else :
    message = '\n' + message
def format ( output , w = 60 ) :
    hrule = "====[ GromacsError (diagnostic output) ]" . ljust ( w , "=" )
    return hrule + '\n' + str ( output ) + hrule
rc = True
if self . _is_empty_group ( make_ndx_output ) :
    warnings . warn ( "Selection produced empty group.{message!s}" . format ( ** vars ( ) ) , category = GromacsValueWarning )
    rc = False
if self . _has_syntax_error ( make_ndx_output ) :
    rc = False
    out_formatted = format ( make_ndx_output )
    raise GromacsError ( "make_ndx encountered a Syntax Error, " "%(message)s\noutput:\n%(out_formatted)s" % vars ( ) )
if make_ndx_output . strip ( ) == "" :
    rc = False
    out_formatted = format ( err )
    raise GromacsError ( "make_ndx produced no output, " "%(message)s\nerror output:\n%(out_formatted)s" % vars ( ) )
return rc


signature:
def outfile ( self , p ) :
    """Path for an output file .
 If : attr : ` outdir ` is set then the path is
 ` ` outdir / basename ( p ) ` ` else just ` ` p ` `"""

implementation:
if self . outdir is not None :
    return os . path . join ( self . outdir , os . path . basename ( p ) )
else :
    return p


signature:
def rp ( self , * args ) :
    """Return canonical path to file under * dirname * with components * args *
 If * args * form an absolute path then just return it as the absolute path ."""

implementation:
try :
    p = os . path . join ( * args )
    if os . path . isabs ( p ) :
        return p
except TypeError :
    pass
return utilities . realpath ( self . dirname , * args )


signature:
def center_fit ( self , ** kwargs ) :
    """Write compact xtc that is fitted to the tpr reference structure .
 See : func : ` gromacs . cbook . trj _ fitandcenter ` for details and
 description of * kwargs * ( including * input * , * input1 * , * n * and
 * n1 * for how to supply custom index groups ) . The most important ones are listed
 here but in most cases the defaults should work .
 : Keywords :
 Input structure ( typically the default tpr file but can be set to
 some other file with a different conformation for fitting )
 Alternative index file .
 Name of the output trajectory .
 * xy * : Boolean
 If ` ` True ` ` then only fit in xy - plane ( useful for a membrane normal
 to z ) . The default is ` ` False ` ` .
 * force *
 - ` ` True ` ` : overwrite existing trajectories
 - ` ` False ` ` : throw a IOError exception
 - ` ` None ` ` : skip existing and log a warning [ default ]
 : Returns :
 dictionary with keys * tpr * , * xtc * , which are the names of the
 the new files"""

implementation:
kwargs . setdefault ( 's' , self . tpr )
kwargs . setdefault ( 'n' , self . ndx )
kwargs [ 'f' ] = self . xtc
kwargs . setdefault ( 'o' , self . outfile ( self . infix_filename ( None , self . xtc , '_centfit' , 'xtc' ) ) )
force = kwargs . pop ( 'force' , self . force )
logger . info ( "Centering and fitting trajectory {f!r}..." . format ( ** kwargs ) )
with utilities . in_dir ( self . dirname ) :
    if not self . check_file_exists ( kwargs [ 'o' ] , resolve = "indicate" , force = force ) :
        trj_fitandcenter ( ** kwargs )
    logger . info ( "Centered and fit trajectory: {o!r}." . format ( ** kwargs ) )
return { 'tpr' : self . rp ( kwargs [ 's' ] ) , 'xtc' : self . rp ( kwargs [ 'o' ] ) }


signature:
def fit ( self , xy = False , ** kwargs ) :
    """Write xtc that is fitted to the tpr reference structure .
 Runs : class : ` gromacs . tools . trjconv ` with appropriate arguments
 for fitting . The most important * kwargs * are listed
 here but in most cases the defaults should work .
 Note that the default settings do * not * include centering or
 periodic boundary treatment as this often does not work well
 with fitting . It is better to do this as a separate step ( see
 : meth : ` center _ fit ` or : func : ` gromacs . cbook . trj _ fitandcenter ` )
 : Keywords :
 Input structure ( typically the default tpr file but can be set to
 some other file with a different conformation for fitting )
 Alternative index file .
 Name of the output trajectory . A default name is created .
 If e . g . * dt * = 100 is one of the * kwargs * then the default name includes
 " _ dt100ps " .
 * xy * : boolean
 If ` ` True ` ` then only do a rot + trans fit in the xy plane
 ( good for membrane simulations ) ; default is ` ` False ` ` .
 * force *
 ` ` True ` ` : overwrite existing trajectories
 ` ` False ` ` : throw a IOError exception
 ` ` None ` ` : skip existing and log a warning [ default ]
 * fitgroup *
 index group to fit on [ " backbone " ]
 . . Note : : If keyword * input * is supplied then it will override
 * fitgroup * ; * input * = ` ` [ fitgroup , outgroup ] ` `
 * kwargs *
 kwargs are passed to : func : ` ~ gromacs . cbook . trj _ xyfitted `
 : Returns :
 dictionary with keys * tpr * , * xtc * , which are the names of the
 the new files"""

implementation:
kwargs . setdefault ( 's' , self . tpr )
kwargs . setdefault ( 'n' , self . ndx )
kwargs [ 'f' ] = self . xtc
force = kwargs . pop ( 'force' , self . force )
if xy :
    fitmode = 'rotxy+transxy'
    kwargs . pop ( 'fit' , None )
    infix_default = '_fitxy'
else :
    fitmode = kwargs . pop ( 'fit' , 'rot+trans' )
    # user can use ' progressive ' , too
    infix_default = '_fit'
dt = kwargs . get ( 'dt' )
if dt :
    infix_default += '_dt{0:d}ps' . format ( int ( dt ) )
# dt in ps
kwargs . setdefault ( 'o' , self . outfile ( self . infix_filename ( None , self . xtc , infix_default , 'xtc' ) ) )
fitgroup = kwargs . pop ( 'fitgroup' , 'backbone' )
kwargs . setdefault ( 'input' , [ fitgroup , "system" ] )
if kwargs . get ( 'center' , False ) :
    logger . warn ( "Transformer.fit(): center=%(center)r used: centering should not be combined with fitting." , kwargs )
    if len ( kwargs [ 'inputs' ] ) != 3 :
        logger . error ( "If you insist on centering you must provide three groups in the 'input' kwarg: (center, fit, output)" )
        raise ValuError ( "Insufficient index groups for centering,fitting,output" )
logger . info ( "Fitting trajectory %r to with xy=%r..." , kwargs [ 'f' ] , xy )
logger . info ( "Fitting on index group %(fitgroup)r" , vars ( ) )
with utilities . in_dir ( self . dirname ) :
    if self . check_file_exists ( kwargs [ 'o' ] , resolve = "indicate" , force = force ) :
        logger . warn ( "File %r exists; force regenerating it with force=True." , kwargs [ 'o' ] )
    else :
        gromacs . trjconv ( fit = fitmode , ** kwargs )
        logger . info ( "Fitted trajectory (fitmode=%s): %r." , fitmode , kwargs [ 'o' ] )
return { 'tpr' : self . rp ( kwargs [ 's' ] ) , 'xtc' : self . rp ( kwargs [ 'o' ] ) }


signature:
def strip_water ( self , os = None , o = None , on = None , compact = False , resn = "SOL" , groupname = "notwater" , ** kwargs ) :
    """Write xtc and tpr with water ( by resname ) removed .
 : Keywords :
 * os *
 Name of the output tpr file ; by default use the original but
 insert " nowater " before suffix .
 Name of the output trajectory ; by default use the original name but
 insert " nowater " before suffix .
 * on *
 Name of a new index file ( without water ) .
 * compact *
 ` ` True ` ` : write a compact and centered trajectory
 ` ` False ` ` : use trajectory as it is [ ` ` False ` ` ]
 * centergroup *
 Index group used for centering [ " Protein " ]
 . . Note : : If * input * is provided ( see below under * kwargs * )
 then * centergroup * is ignored and the group for
 centering is taken as the first entry in * input * .
 * resn *
 Residue name of the water molecules ; all these residues are excluded .
 * groupname *
 Name of the group that is generated by subtracting all waters
 from the system .
 * force * : Boolean
 - ` ` True ` ` : overwrite existing trajectories
 - ` ` False ` ` : throw a IOError exception
 - ` ` None ` ` : skip existing and log a warning [ default ]
 * kwargs *
 are passed on to : func : ` gromacs . cbook . trj _ compact ` ( unless the
 values have to be set to certain values such as s , f , n , o
 keywords ) . The * input * keyword is always mangled : Only the first
 entry ( the group to centre the trajectory on ) is kept , and as a
 second group ( the output group ) * groupname * is used .
 : Returns :
 dictionary with keys * tpr * , * xtc * , * ndx * which are the names of the
 the new files
 . . warning : : The input tpr file should * not * have * any position restraints * ;
 otherwise Gromacs will throw a hissy - fit and say
 * Software inconsistency error : Position restraint coordinates are
 missing *
 ( This appears to be a bug in Gromacs 4 . x . )"""

implementation:
force = kwargs . pop ( 'force' , self . force )
newtpr = self . outfile ( self . infix_filename ( os , self . tpr , '_nowater' ) )
newxtc = self . outfile ( self . infix_filename ( o , self . xtc , '_nowater' ) )
newndx = self . outfile ( self . infix_filename ( on , self . tpr , '_nowater' , 'ndx' ) )
nowater_ndx = self . _join_dirname ( newtpr , "nowater.ndx" )
# refers to original tpr
if compact :
    TRJCONV = trj_compact
    # input overrides centergroup
    if kwargs . get ( 'centergroup' ) is not None and 'input' in kwargs :
        logger . warn ( "centergroup = %r will be superceded by input[0] = %r" , kwargs [ 'centergroup' ] , kwargs [ 'input' ] [ 0 ] )
    _input = kwargs . get ( 'input' , [ kwargs . get ( 'centergroup' , 'Protein' ) ] )
    kwargs [ 'input' ] = [ _input [ 0 ] , groupname ]
    # [ center group , write - out selection ]
    del _input
    logger . info ( "Creating a compact trajectory centered on group %r" , kwargs [ 'input' ] [ 0 ] )
    logger . info ( "Writing %r to the output trajectory" , kwargs [ 'input' ] [ 1 ] )
else :
    TRJCONV = gromacs . trjconv
    kwargs [ 'input' ] = [ groupname ]
    logger . info ( "Writing %r to the output trajectory (no centering)" , kwargs [ 'input' ] [ 0 ] )
# clean kwargs , only legal arguments for Gromacs tool trjconv should remain
kwargs . pop ( "centergroup" , None )
NOTwater = "! r {resn!s}" . format ( ** vars ( ) )
# make _ ndx selection ( " not water residues " )
with utilities . in_dir ( self . dirname ) : # ugly because I cannot break from the block
    if not self . check_file_exists ( newxtc , resolve = "indicate" , force = force ) : # make no - water index
        B = IndexBuilder ( struct = self . tpr , selections = [ '@' + NOTwater ] , ndx = self . ndx , out_ndx = nowater_ndx )
        B . combine ( name_all = groupname , operation = "|" , defaultgroups = True )
        logger . debug ( "Index file for water removal: %r" , nowater_ndx )
        logger . info ( "TPR file without water {newtpr!r}" . format ( ** vars ( ) ) )
        gromacs . tpbconv ( s = self . tpr , o = newtpr , n = nowater_ndx , input = [ groupname ] )
        logger . info ( "NDX of the new system %r" , newndx )
        gromacs . make_ndx ( f = newtpr , o = newndx , input = [ 'q' ] , stderr = False , stdout = False )
        # PROBLEM : If self . ndx contained a custom group required for fitting then we are loosing
        # this group here . We could try to merge only this group but it is possible that
        # atom indices changed . The only way to solve this is to regenerate the group with
        # a selection or only use Gromacs default groups .
        logger . info ( "Trajectory without water {newxtc!r}" . format ( ** vars ( ) ) )
        kwargs [ 's' ] = self . tpr
        kwargs [ 'f' ] = self . xtc
        kwargs [ 'n' ] = nowater_ndx
        kwargs [ 'o' ] = newxtc
        TRJCONV ( ** kwargs )
        logger . info ( "pdb and gro for visualization" )
        for ext in 'pdb' , 'gro' :
            try : # see warning in doc . . . so we don ' t use the new xtc but the old one
                kwargs [ 'o' ] = self . filename ( newtpr , ext = ext )
                TRJCONV ( dump = 0 , stdout = False , stderr = False , ** kwargs )
                # silent
            except :
                logger . exception ( "Failed building the water-less %(ext)s. " "Position restraints in tpr file (see docs)?" % vars ( ) )
    logger . info ( "strip_water() complete" )
self . nowater [ self . rp ( newxtc ) ] = Transformer ( dirname = self . dirname , s = newtpr , f = newxtc , n = newndx , force = force )
return { 'tpr' : self . rp ( newtpr ) , 'xtc' : self . rp ( newxtc ) , 'ndx' : self . rp ( newndx ) }


signature:
def strip_fit ( self , ** kwargs ) :
    """Strip water and fit to the remaining system .
 First runs : meth : ` strip _ water ` and then : meth : ` fit ` ; see there
 for arguments .
 - * strip _ input * is used for : meth : ` strip _ water ` ( but is only useful in
 special cases , e . g . when there is no Protein group defined . Then set
 * strip _ input * = ` ` [ ' Other ' ] ` ` .
 - * input * is passed on to : meth : ` fit ` and can contain the
 ` ` [ center _ group , fit _ group , output _ group ] ` `
 - * fitgroup * is only passed to : meth : ` fit ` and just contains
 the group to fit to ( " backbone " by default )
 . . warning : : * fitgroup * can only be a Gromacs default group and not
 a custom group ( because the indices change after stripping )
 - By default * fit * = " rot + trans " ( and * fit * is passed to : meth : ` fit ` ,
 together with the * xy * = ` ` False ` ` keyword )
 . . Note : : The call signature of : meth : ` strip _ water ` is somewhat different from this one ."""

implementation:
kwargs . setdefault ( 'fit' , 'rot+trans' )
kw_fit = { }
for k in ( 'xy' , 'fit' , 'fitgroup' , 'input' ) :
    if k in kwargs :
        kw_fit [ k ] = kwargs . pop ( k )
kwargs [ 'input' ] = kwargs . pop ( 'strip_input' , [ 'Protein' ] )
kwargs [ 'force' ] = kw_fit [ 'force' ] = kwargs . pop ( 'force' , self . force )
paths = self . strip_water ( ** kwargs )
# updates self . nowater
transformer_nowater = self . nowater [ paths [ 'xtc' ] ]
# make sure to get the one we just produced
return transformer_nowater . fit ( ** kw_fit )


signature:
def _join_dirname ( self , * args ) :
    """return os . path . join ( os . path . dirname ( args [ 0 ] ) , * args [ 1 : ] )"""

implementation:
# extra function because I need to use it in a method that defines
# the kwarg ' os ' , which collides with os . path . . .
return os . path . join ( os . path . dirname ( args [ 0 ] ) , * args [ 1 : ] )


signature:
def create ( logger_name , logfile = 'gromacs.log' ) :
    """Create a top level logger .
 - The file logger logs everything ( including DEBUG ) .
 - The console logger only logs INFO and above .
 Logging to a file and the console .
 See http : / / docs . python . org / library / logging . html ? # logging - to - multiple - destinations
 The top level logger of the library is named ' gromacs ' . Note that
 we are configuring this logger with console output . If the root
 logger also does this then we will get two output lines to the
 console . We ' ll live with this because this is a simple
 convenience library . . ."""

implementation:
logger = logging . getLogger ( logger_name )
logger . setLevel ( logging . DEBUG )
logfile = logging . FileHandler ( logfile )
logfile_formatter = logging . Formatter ( '%(asctime)s %(name)-12s %(levelname)-8s %(message)s' )
logfile . setFormatter ( logfile_formatter )
logger . addHandler ( logfile )
# define a Handler which writes INFO messages or higher to the sys . stderr
console = logging . StreamHandler ( )
console . setLevel ( logging . INFO )
# set a format which is simpler for console use
formatter = logging . Formatter ( '%(name)-12s: %(levelname)-8s %(message)s' )
console . setFormatter ( formatter )
logger . addHandler ( console )
return logger


signature:
def _generate_template_dict ( dirname ) :
    """Generate a list of included files * and * extract them to a temp space .
 Templates have to be extracted from the egg because they are used
 by external code . All template filenames are stored in
 : data : ` config . templates ` ."""

implementation: return dict ( ( resource_basename ( fn ) , resource_filename ( __name__ , dirname + '/' + fn ) ) for fn in resource_listdir ( __name__ , dirname ) if not fn . endswith ( '~' ) )


signature:
def resource_basename ( resource ) :
    """Last component of a resource ( which always uses ' / ' as sep ) ."""

implementation:
if resource . endswith ( '/' ) :
    resource = resource [ : - 1 ]
parts = resource . split ( '/' )
return parts [ - 1 ]


signature:
def get_template ( t ) :
    """Find template file * t * and return its real path .
 * t * can be a single string or a list of strings . A string
 should be one of
 1 . a relative or absolute path ,
 2 . a file in one of the directories listed in : data : ` gromacs . config . path ` ,
 3 . a filename in the package template directory ( defined in the template dictionary
 : data : ` gromacs . config . templates ` ) or
 4 . a key into : data : ` ~ gromacs . config . templates ` .
 The first match ( in this order ) is returned . If the argument is a
 single string then a single string is returned , otherwise a list
 of strings .
 : Arguments : * t * : template file or key ( string or list of strings )
 : Returns : os . path . realpath ( * t * ) ( or a list thereof )
 : Raises : : exc : ` ValueError ` if no file can be located ."""

implementation:
templates = [ _get_template ( s ) for s in utilities . asiterable ( t ) ]
if len ( templates ) == 1 :
    return templates [ 0 ]
return templates


signature:
def _get_template ( t ) :
    """Return a single template * t * ."""

implementation:
if os . path . exists ( t ) : # 1 ) Is it an accessible file ?
    pass
else :
    _t = t
    _t_found = False
    for d in path : # 2 ) search config . path
        p = os . path . join ( d , _t )
        if os . path . exists ( p ) :
            t = p
            _t_found = True
            break
    _t = os . path . basename ( t )
    if not _t_found : # 3 ) try template dirs
        for p in templates . values ( ) :
            if _t == os . path . basename ( p ) :
                t = p
                _t_found = True
                # NOTE : in principle this could match multiple
                break
                # times if more than one template dir existed .
    if not _t_found : # 4 ) try it as a key into templates
        try :
            t = templates [ t ]
        except KeyError :
            pass
        else :
            _t_found = True
    if not _t_found : # 5 ) nothing else to try . . .
        raise ValueError ( "Failed to locate the template file {t!r}." . format ( ** vars ( ) ) )
return os . path . realpath ( t )


signature:
def get_configuration ( filename = CONFIGNAME ) :
    """Reads and parses the configuration file .
 Default values are loaded and then replaced with the values from
 ` ` ~ / . gromacswrapper . cfg ` ` if that file exists . The global
 configuration instance : data : ` gromacswrapper . config . cfg ` is updated
 as are a number of global variables such as : data : ` configdir ` ,
 : data : ` qscriptdir ` , : data : ` templatesdir ` , : data : ` logfilename ` , . . .
 Normally , the configuration is only loaded when the : mod : ` gromacs `
 package is imported but a re - reading of the configuration can be forced
 anytime by calling : func : ` get _ configuration ` .
 : Returns : a dict with all updated global configuration variables"""

implementation:
global cfg , configuration
# very iffy - - - most of the whole config mod should a class
# : : data : ` cfg ` is the instance of : class : ` GMXConfigParser ` that makes all
# : global configuration data accessible
cfg = GMXConfigParser ( filename = filename )
# update module - level cfg
globals ( ) . update ( cfg . configuration )
# update configdir , templatesdir . . .
configuration = cfg . configuration
# update module - level configuration
return cfg


signature:
def setup ( filename = CONFIGNAME ) :
    """Prepare a default GromacsWrapper global environment .
 1 ) Create the global config file .
 2 ) Create the directories in which the user can store template and config files .
 This function can be run repeatedly without harm ."""

implementation:
# setup ( ) must be separate and NOT run automatically when config
# is loaded so that easy _ install installations work
# ( otherwise we get a sandbox violation )
# populate cfg with defaults ( or existing data )
get_configuration ( )
if not os . path . exists ( filename ) :
    with open ( filename , 'w' ) as configfile :
        cfg . write ( configfile )
        # write the default file so that user can edit
        msg = "NOTE: GromacsWrapper created the configuration file \n\t%r\n" "      for you. Edit the file to customize the package." % filename
        print ( msg )
# directories
for d in config_directories :
    utilities . mkdir_p ( d )


signature:
def check_setup ( ) :
    """Check if templates directories are setup and issue a warning and help .
 Set the environment variable : envvar : ` GROMACSWRAPPER _ SUPPRESS _ SETUP _ CHECK `
 skip the check and make it always return ` ` True ` `
 : return ` ` True ` ` if directories were found and ` ` False ` ` otherwise
 . . versionchanged : : 0.3.1
 Uses : envvar : ` GROMACSWRAPPER _ SUPPRESS _ SETUP _ CHECK ` to suppress check
 ( useful for scripts run on a server )"""

implementation:
if "GROMACSWRAPPER_SUPPRESS_SETUP_CHECK" in os . environ :
    return True
missing = [ d for d in config_directories if not os . path . exists ( d ) ]
if len ( missing ) > 0 :
    print ( "NOTE: Some configuration directories are not set up yet: " )
    print ( "\t{0!s}" . format ( '\n\t' . join ( missing ) ) )
    print ( "NOTE: You can create the configuration file and directories with:" )
    print ( "\t>>> import gromacs" )
    print ( "\t>>> gromacs.config.setup()" )
    return False
return True