<commit_before>from __future__ import unicode_literals

from django.utils import six
from django.utils.translation import ugettext_lazy as _
from django.db.models import Lookup, Transform
from django.db.models.fields import *

from rdkit import Chem
from rdkit.Chem import Mol
from rdkit import DataStructs
from rdkit.DataStructs import ExplicitBitVect, SparseIntVect


__all__ = ["MolField", "BfpField", "SfpField",]
 

class ChemField(Field):

    def __init__(self, verbose_name=None, chem_index=True, *args, **kwargs):
        self.chem_index = chem_index
        kwargs['verbose_name'] = verbose_name
        super(ChemField, self).__init__(*args, **kwargs)
    
    #def select_format(self, compiler, sql, params):
    #    """
    #    Custom format for select clauses. For example, GIS columns need to be
    #    selected as AsText(table.col) on MySQL as the table.col data 
    #    can't be used by Django.
    #    """
    #    return sql, params

    def deconstruct(self):
        name, path, args, kwargs = super(ChemField, self).deconstruct()
        # include chem_index if not the default value.
        if self.chem_index is not True:
            kwargs['chem_index'] = self.chem_index
        return name, path, args, kwargs

    #def get_placeholder(self, value, compiler, connection):
    #    """
    #    Returns the placeholder for the geometry column for the
    #    given value.
    #    """
    #    if hasattr(value, 'as_sql'):
    #        # No geometry value used for F expression, substitute in
    #        # the column name instead.
    #        sql, _ = compiler.compile(value)
    #        return sql
    #    else:
    #        return '%s'


##########################################
# Molecule Field

class MolField(ChemField):

    description = _("Molecule")

    def db_type(self, connection):
        return 'mol'
    
    def get_placeholder(self, value, compiler, connection):
        if hasattr(value, 'as_sql'):
            # No value used for expressions, substitute in
            # the column name instead.
            sql, _ = compiler.compile(value)
            return sql
        else:
            return 'mol_from_pkl(%s)'

    def select_format(self, compiler, sql, params):
        return 'mol_to_pkl(%s)' % sql, params

    def from_db_value(self, value, connection, context):
        if value is None:
            return value
        return Mol(bytes(value))

    def to_python(self, value):
        if value is None or isinstance(value, Mol):
            return value
        elif isinstance(value, six.string_types):
            # The string case. A SMILES is assumed.
            return Chem.MolFromSmiles(str(value))
        elif isinstance(value, six.buffer_types):
            return Mol(bytes(value))
        else:
            raise ValidationError("Invalid input for a Mol instance")

    def get_prep_value(self, value):
        # convert the Molecule instance to the value used by the 
        # db driver
        if isinstance(value, six.string_types):
            # The string case. A SMILES is assumed.
            value = Chem.MolFromSmiles(str(value))
        if isinstance(value, Mol):
            value = six.memoryview(value.ToBinary())
        return value

    # don't reimplement db-specific preparation of query values for now
    # def get_db_prep_value(self, value, connection, prepared=False):
    #    return value

    def get_prep_lookup(self, lookup_type, value):
        "Perform preliminary non-db specific lookup checks and conversions"
        supported_lookup_types = (
            ['hassubstruct', 'issubstruct', 'exact',] +
            [T.lookup_name for T in DESCRIPTOR_TRANFORMS]
        )
        if lookup_type in supported_lookup_types:
            return value
        raise TypeError("Field has invalid lookup: %s" % lookup_type)

    # this will be probably needed.
    #def get_db_prep_lookup(lookup_type, value, connection, prepared=False):
    #    if not prepared:
    #        value = self.get_prep_lookup(lookup_type, value)
    #    return value


########################################################
# Binary Fingerprint Field

class BfpField(ChemField):

    description = _("Binary Fingerprint")

    def db_type(self, connection):
        return 'bfp'
    
    def get_placeholder(self, value, compiler, connection):
        if hasattr(value, 'as_sql'):
            # No value used for expressions, substitute in
            # the column name instead.
            sql, _ = compiler.compile(value)
            return sql
        else:
            return 'bfp_from_binary_text(%s)'

    def select_format(self, compiler, sql, params):
        return 'bfp_to_binary_text(%s)' % sql, params

    def from_db_value(self, value, connection, context):
        if value is None:
            return value
        return DataStructs.CreateFromBinaryText(bytes(value))

    def to_python(self, value):
        if value is None or isinstance(value, ExplicitBitVect):
            return value
        elif isinstance(value, six.buffer_types):
            return DataStructs.CreateFromBinaryText(bytes(value))
        else:
            raise ValidationError("Invalid input for a Bfp instance")

    def get_prep_value(self, value):
        # convert the ExplicitBitVect instance to the value used by the 
        # db driver
        if isinstance(value, ExplicitBitVect):
            value = six.memoryview(DataStructs.BitVectToBinaryText(value))<commit_msg>updated from_db_value signature<commit_after>from __future__ import unicode_literals

from django.utils import six
from django.utils.translation import ugettext_lazy as _
from django.db.models import Lookup, Transform
from django.db.models.fields import *

from rdkit import Chem
from rdkit.Chem import Mol
from rdkit import DataStructs
from rdkit.DataStructs import ExplicitBitVect, SparseIntVect


__all__ = ["MolField", "BfpField", "SfpField",]
 

class ChemField(Field):

    def __init__(self, verbose_name=None, chem_index=True, *args, **kwargs):
        self.chem_index = chem_index
        kwargs['verbose_name'] = verbose_name
        super(ChemField, self).__init__(*args, **kwargs)
    
    #def select_format(self, compiler, sql, params):
    #    """
    #    Custom format for select clauses. For example, GIS columns need to be
    #    selected as AsText(table.col) on MySQL as the table.col data 
    #    can't be used by Django.
    #    """
    #    return sql, params

    def deconstruct(self):
        name, path, args, kwargs = super(ChemField, self).deconstruct()
        # include chem_index if not the default value.
        if self.chem_index is not True:
            kwargs['chem_index'] = self.chem_index
        return name, path, args, kwargs

    #def get_placeholder(self, value, compiler, connection):
    #    """
    #    Returns the placeholder for the geometry column for the
    #    given value.
    #    """
    #    if hasattr(value, 'as_sql'):
    #        # No geometry value used for F expression, substitute in
    #        # the column name instead.
    #        sql, _ = compiler.compile(value)
    #        return sql
    #    else:
    #        return '%s'


##########################################
# Molecule Field

class MolField(ChemField):

    description = _("Molecule")

    def db_type(self, connection):
        return 'mol'
    
    def get_placeholder(self, value, compiler, connection):
        if hasattr(value, 'as_sql'):
            # No value used for expressions, substitute in
            # the column name instead.
            sql, _ = compiler.compile(value)
            return sql
        else:
            return 'mol_from_pkl(%s)'

    def select_format(self, compiler, sql, params):
        return 'mol_to_pkl(%s)' % sql, params

    def from_db_value(self, value, expression, connection, context):
        if value is None:
            return value
        return Mol(bytes(value))

    def to_python(self, value):
        if value is None or isinstance(value, Mol):
            return value
        elif isinstance(value, six.string_types):
            # The string case. A SMILES is assumed.
            return Chem.MolFromSmiles(str(value))
        elif isinstance(value, six.buffer_types):
            return Mol(bytes(value))
        else:
            raise ValidationError("Invalid input for a Mol instance")

    def get_prep_value(self, value):
        # convert the Molecule instance to the value used by the 
        # db driver
        if isinstance(value, six.string_types):
            # The string case. A SMILES is assumed.
            value = Chem.MolFromSmiles(str(value))
        if isinstance(value, Mol):
            value = six.memoryview(value.ToBinary())
        return value

    # don't reimplement db-specific preparation of query values for now
    # def get_db_prep_value(self, value, connection, prepared=False):
    #    return value

    def get_prep_lookup(self, lookup_type, value):
        "Perform preliminary non-db specific lookup checks and conversions"
        supported_lookup_types = (
            ['hassubstruct', 'issubstruct', 'exact',] +
            [T.lookup_name for T in DESCRIPTOR_TRANFORMS]
        )
        if lookup_type in supported_lookup_types:
            return value
        raise TypeError("Field has invalid lookup: %s" % lookup_type)

    # this will be probably needed.
    #def get_db_prep_lookup(lookup_type, value, connection, prepared=False):
    #    if not prepared:
    #        value = self.get_prep_lookup(lookup_type, value)
    #    return value


########################################################
# Binary Fingerprint Field

class BfpField(ChemField):

    description = _("Binary Fingerprint")

    def db_type(self, connection):
        return 'bfp'
    
    def get_placeholder(self, value, compiler, connection):
        if hasattr(value, 'as_sql'):
            # No value used for expressions, substitute in
            # the column name instead.
            sql, _ = compiler.compile(value)
            return sql
        else:
            return 'bfp_from_binary_text(%s)'

    def select_format(self, compiler, sql, params):
        return 'bfp_to_binary_text(%s)' % sql, params

    def from_db_value(self, value, expression, connection, context):
        if value is None:
            return value
        return DataStructs.CreateFromBinaryText(bytes(value))

    def to_python(self, value):
        if value is None or isinstance(value, ExplicitBitVect):
            return value
        elif isinstance(value, six.buffer_types):
            return DataStructs.CreateFromBinaryText(bytes(value))
        else:
            raise ValidationError("Invalid input for a Bfp instance")

    def get_prep_value(self, value):
        # convert the ExplicitBitVect instance to the value used by the 
        # db driver
        if isinstance(value, ExplicitBitVect):
            value = six.memoryview(DataStructs.BitVectToBinaryText(value))
{'fraction_non_alphanumeric': 0.10229759299781181, 'fraction_numerical': 0.0, 'mean_word_length': 2.557898151151476, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2953845', 'n_tokens_mistral': 3111, 'n_tokens_neox': 2986, 'n_words': 925}