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)
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)
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)
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)