Пример #1
0
    def search(self, params):
        limit, offset, sort = parse_pagination_params(params)

        query_string = params.get('q')
        formula = params.get('formula')
        cactus = params.get('cactus')
        if query_string is None and formula is None and cactus is None:
            raise RestException(
                'Either \'q\', \'formula\' or \'cactus\' is required.')

        if query_string is not None:
            try:
                mongo_query = query.to_mongo_query(query_string)
            except query.InvalidQuery:
                raise RestException('Invalid query', 400)

            fields = ['inchikey', 'smiles', 'properties', 'name']
            cursor = MoleculeModel().find(query=mongo_query,
                                          fields=fields,
                                          limit=limit,
                                          offset=offset,
                                          sort=sort)
            mols = [x for x in cursor]
            num_matches = cursor.collection.count_documents(mongo_query)

            return search_results_dict(mols, num_matches, limit, offset, sort)

        elif formula:
            # Search using formula
            return MoleculeModel().findmol(params)

        elif cactus:
            if getCurrentUser() is None:
                raise RestException('Must be logged in to search with cactus.')

            # Disable cert verification for now
            # TODO Ensure we have the right root certs so this just works.
            r = requests.get(
                'https://cactus.nci.nih.gov/chemical/structure/%s/file?format=sdf'
                % cactus,
                verify=False)

            if r.status_code == 404:
                return []
            else:
                r.raise_for_status()

            sdf_data = r.content.decode('utf8')
            provenance = 'cactus: ' + cactus
            mol = create_molecule(sdf_data,
                                  'sdf',
                                  getCurrentUser(),
                                  True,
                                  provenance=provenance)

            return search_results_dict([mol], 1, limit, offset, sort)
Пример #2
0
    def findmol(self, search=None):
        limit, offset, sort = parse_pagination_params(search)

        if search is None:
            search = {}

        query = {}
        if 'queryString' in search:
            # queryString takes precedence over all other search params
            query_string = search['queryString']
            try:
                query = mol_query.to_mongo_query(query_string)
            except mol_query.InvalidQuery:
                raise RestException('Invalid query', 400)
        elif search:
            # If the search dict is not empty, perform a search
            if 'name' in search:
                query['name'] = {
                    '$regex': '^' + search['name'],
                    '$options': 'i'
                }
            if 'inchi' in search:
                query['inchi'] = search['inchi']
            if 'inchikey' in search:
                query['inchikey'] = search['inchikey']
            if 'smiles' in search:
                # Make sure it is canonical before searching
                query['smiles'] = openbabel.to_smiles(search['smiles'], 'smi')
            if 'formula' in search:
                formula_regx = re.compile('^%s$' % search['formula'],
                                          re.IGNORECASE)
                query['properties.formula'] = formula_regx
            if 'creatorId' in search:
                query['creatorId'] = ObjectId(search['creatorId'])

        fields = ['inchikey', 'smiles', 'properties', 'name']

        cursor = self.find(query,
                           fields=fields,
                           limit=limit,
                           offset=offset,
                           sort=sort)

        num_matches = cursor.collection.count_documents(query)

        mols = [x for x in cursor]
        return search_results_dict(mols, num_matches, limit, offset, sort)
Пример #3
0
    def find_geometries(self, moleculeId, user, paging_params):

        limit, offset, sort = parse_pagination_params(paging_params)

        query = {'moleculeId': ObjectId(moleculeId)}

        fields = [
            'creatorId', 'moleculeId', 'provenanceId', 'provenanceType',
            'energy'
        ]

        cursor = self.findWithPermissions(query,
                                          user=user,
                                          fields=fields,
                                          limit=limit,
                                          offset=offset,
                                          sort=sort)

        num_matches = cursor.collection.count_documents(query)

        geometries = [x for x in cursor]
        return search_results_dict(geometries, num_matches, limit, offset,
                                   sort)
Пример #4
0
    def findcal(self,
                molecule_id=None,
                image_name=None,
                input_parameters_hash=None,
                input_geometry_hash=None,
                name=None,
                inchi=None,
                inchikey=None,
                smiles=None,
                formula=None,
                creator_id=None,
                pending=None,
                limit=None,
                offset=None,
                sort=None,
                user=None):
        # Set these to their defaults if they are not already set
        limit, offset, sort = default_pagination_params(limit, offset, sort)

        query = {}

        # If a molecule id is specified it has higher priority
        if molecule_id:
            query['moleculeId'] = ObjectId(molecule_id)
        # Otherwise, if query parameters for the molecules are
        # specified, search for matching molecules first
        elif any((name, inchi, inchikey, smiles, formula)):
            params = {'offset': 0, 'limit': sys.maxsize}

            if name:
                params['name'] = name
            if inchi:
                params['inchi'] = inchi
            if inchikey:
                params['inchikey'] = inchikey
            if smiles:
                params['smiles'] = smiles
            if formula:
                params['formula'] = formula

            molecules = MoleculeModel().findmol(params)['results']
            molecule_ids = [molecule['_id'] for molecule in molecules]
            query['moleculeId'] = {'$in': molecule_ids}

        if image_name:
            repository, tag = oc.parse_image_name(image_name)
            query['image.repository'] = repository
            query['image.tag'] = tag

        if input_parameters_hash:
            query['input.parametersHash'] = input_parameters_hash

        if input_geometry_hash:
            query['input.geometryHash'] = input_geometry_hash

        if creator_id:
            query['creatorId'] = ObjectId(creator_id)

        if pending is not None:
            pending = toBool(pending)
            query['properties.pending'] = pending
            # The absence of the field mean the calculation is not pending ...
            if not pending:
                query['properties.pending'] = {'$ne': True}

        fields = [
            'image', 'input', 'cjson', 'cjson.vibrations.modes',
            'cjson.vibrations.intensities', 'cjson.vibrations.frequencies',
            'properties', 'fileId', 'access', 'moleculeId', 'public'
        ]

        calcs = self.find(query,
                          fields=fields,
                          limit=limit,
                          offset=offset,
                          sort=sort)
        num_matches = calcs.collection.count_documents(query)

        calcs = self.filterResultsByPermission(calcs,
                                               user,
                                               AccessType.READ,
                                               limit=limit)
        calcs = [self.filter(x, user) for x in calcs]

        return search_results_dict(calcs, num_matches, limit, offset, sort)