def predict_properties(pred_smiles: List[Optional[str]], checkpoint_dir: str, computed_prop: str) -> List[float]: # Check that exactly one of checkpoint_dir and computed_prop is provided assert (checkpoint_dir is None) != (computed_prop is None) pred_smiles = [smiles for smiles in pred_smiles if smiles is not None] # Create and modify predict args parser = ArgumentParser() add_predict_args(parser) args = parser.parse_args([]) if checkpoint_dir is not None: args.test_path = 'None' args.checkpoint_dir = checkpoint_dir update_checkpoint_args(args) args.quiet = True print('Make predictions') with NamedTemporaryFile() as temp_file: args.preds_path = temp_file.name property_predictions = make_predictions(args, smiles=pred_smiles) property_predictions = [property_prediction[0] for property_prediction in property_predictions] else: if computed_prop == 'penalized_logp': scorer = penalized_logp elif computed_prop == 'logp': scorer = logp elif computed_prop == 'qed': scorer = qed elif computed_prop == 'sascore': scorer = sascore elif computed_prop == 'drd2': scorer = drd2 else: raise ValueError(f'Computed property "{computed_prop}" not supported') property_predictions = [scorer(s) for s in pred_smiles] return property_predictions
def predict(): """Renders the predict page and makes predictions if the method is POST.""" if request.method == 'GET': return render_predict() # Get arguments ckpt_id = request.form['checkpointName'] if request.form['textSmiles'] != '': smiles = request.form['textSmiles'].split() elif request.form['drawSmiles'] != '': smiles = [request.form['drawSmiles']] else: # Upload data file with SMILES data = request.files['data'] data_name = secure_filename(data.filename) data_path = os.path.join(app.config['TEMP_FOLDER'], data_name) data.save(data_path) # Check if header is smiles possible_smiles = get_header(data_path)[0] smiles = [possible_smiles ] if Chem.MolFromSmiles(possible_smiles) is not None else [] # Get remaining smiles smiles.extend(get_smiles(data_path)) models = db.get_models(ckpt_id) model_paths = [ os.path.join(app.config['CHECKPOINT_FOLDER'], f'{model["id"]}.pt') for model in models ] task_names = load_task_names(model_paths[0]) num_tasks = len(task_names) gpu = request.form.get('gpu') train_args = load_args(model_paths[0]) # Build arguments arguments = [ '--test_path', 'None', '--preds_path', os.path.join(app.config['TEMP_FOLDER'], app.config['PREDICTIONS_FILENAME']), '--checkpoint_paths', *model_paths ] if gpu is not None: if gpu == 'None': arguments.append('--no_cuda') else: arguments += ['--gpu', gpu] # Handle additional features if train_args.features_path is not None: # TODO: make it possible to specify the features generator if trained using features_path arguments += [ '--features_generator', 'rdkit_2d_normalized', '--no_features_scaling' ] elif train_args.features_generator is not None: arguments += ['--features_generator', *train_args.features_generator] if not train_args.features_scaling: arguments.append('--no_features_scaling') # Parse arguments args = PredictArgs().parse_args(arguments) # Run predictions preds = make_predictions(args=args, smiles=smiles) if all(p is None for p in preds): return render_predict(errors=['All SMILES are invalid']) # Replace invalid smiles with message invalid_smiles_warning = 'Invalid SMILES String' preds = [ pred if pred is not None else [invalid_smiles_warning] * num_tasks for pred in preds ] return render_predict( predicted=True, smiles=smiles, num_smiles=min(10, len(smiles)), show_more=max(0, len(smiles) - 10), task_names=task_names, num_tasks=len(task_names), preds=preds, warnings=["List contains invalid SMILES strings"] if None in preds else None, errors=["No SMILES strings given"] if len(preds) == 0 else None)
def predict(): if request.method == 'GET': return render_template('predict.html', checkpoints=get_checkpoints(), cuda=app.config['CUDA'], gpus=app.config['GPUS']) # Get arguments checkpoint_name = request.form['checkpointName'] if 'data' in request.files: # Upload data file with SMILES show_file_upload = True data = request.files['data'] data_name = secure_filename(data.filename) data_path = os.path.join(app.config['TEMP_FOLDER'], data_name) data.save(data_path) smiles = [] with open(data_path, 'r') as f: header = f.readline() try: # if there's no header, add the smiles in the first line possible_smiles = header.strip().split(',')[0] mol = Chem.MolFromSmiles(possible_smiles) smiles.append(possible_smiles) except: pass for line in f: smiles.append(line.strip().split(',')[0]) else: show_file_upload = False smiles = request.form['smiles'] smiles = smiles.split() checkpoint_path = os.path.join(app.config['CHECKPOINT_FOLDER'], checkpoint_name) task_names = load_task_names(checkpoint_path) gpu = request.form.get('gpu', None) # Create and modify args parser = ArgumentParser() add_predict_args(parser) args = parser.parse_args() preds_path = os.path.join(app.config['TEMP_FOLDER'], app.config['PREDICTIONS_FILENAME']) args.preds_path = preds_path args.checkpoint_paths = [checkpoint_path] if gpu is not None: if gpu == 'None': args.no_cuda = True else: args.gpu = int(gpu) invalid_smiles_warning = "Invalid SMILES String" if len(smiles) > 0: # Run prediction preds = make_predictions(args, smiles=smiles, invalid_smiles_warning=invalid_smiles_warning) else: preds = [] return render_template( 'predict.html', checkpoints=get_checkpoints(), cuda=app.config['CUDA'], gpus=app.config['GPUS'], predicted=True, smiles=smiles, num_smiles=min(10, len(smiles)), show_more=max(0, len(smiles) - 10), task_names=task_names, num_tasks=len(task_names), preds=preds, show_file_upload=show_file_upload, warning="List contains invalid SMILES strings" if invalid_smiles_warning in preds else None, error="No SMILES strings given" if len(preds) == 0 else None)
def predict(): """Renders the predict page and makes predictions if the method is POST.""" if request.method == 'GET': return render_predict() # Get arguments ckpt_id = request.form['checkpointName'] if request.form['textSmiles'] != '': smiles = request.form['textSmiles'].split() elif request.form['drawSmiles'] != '': smiles = [request.form['drawSmiles']] else: print(" GOT HERE") # Upload data file with SMILES data = request.files['data'] data_name = secure_filename(data.filename) data_path = os.path.join(app.config['TEMP_FOLDER'], data_name) data.save(data_path) # Check if header is smiles possible_smiles = get_header(data_path)[0] smiles = [possible_smiles] if Chem.MolFromSmiles(possible_smiles) is not None else [] # Get remaining smiles smiles.extend(get_smiles(data_path)) models = db.get_models(ckpt_id) model_paths = [os.path.join(app.config['CHECKPOINT_FOLDER'], f'{model["id"]}.pt') for model in models] task_names = load_task_names(model_paths[0]) num_tasks = len(task_names) gpu = request.form.get('gpu') # Create and modify args args = load_args(model_paths[0]) if args.features_path != None: args.features_generator = ["rdkit_2d_normalized"] args.features_path = None preds_path = os.path.join(app.config['TEMP_FOLDER'], app.config['PREDICTIONS_FILENAME']) args.test_path = 'None' # TODO: Remove this hack to avoid assert crashing in modify_predict_args args.preds_path = preds_path args.checkpoint_paths = model_paths if gpu is not None: if gpu == 'None': args.no_cuda = True else: args.gpu = int(gpu) modify_predict_args(args) # Run predictions preds = make_predictions(args, smiles=smiles) if all(p is None for p in preds): return render_predict(errors=['All SMILES are invalid']) # Replace invalid smiles with message invalid_smiles_warning = "Invalid SMILES String" preds = [pred if pred is not None else [invalid_smiles_warning] * num_tasks for pred in preds] return render_predict(predicted=True, smiles=smiles, num_smiles=min(10, len(smiles)), show_more=max(0, len(smiles)-10), task_names=task_names, num_tasks=len(task_names), preds=preds, warnings=["List contains invalid SMILES strings"] if None in preds else None, errors=["No SMILES strings given"] if len(preds) == 0 else None)
def predict(): if request.method == 'GET': return render_predict() # Get arguments checkpoint_name = request.form['checkpointName'] if 'data' in request.files: # Upload data file with SMILES data = request.files['data'] data_name = secure_filename(data.filename) data_path = os.path.join(app.config['TEMP_FOLDER'], data_name) data.save(data_path) # Check if header is smiles possible_smiles = get_header(data_path)[0] smiles = [possible_smiles ] if Chem.MolFromSmiles(possible_smiles) is not None else [] # Get remaining smiles smiles.extend(get_smiles(data_path)) elif request.form['textSmiles'] != '': smiles = request.form['textSmiles'].split() else: smiles = [request.form['drawSmiles']] checkpoint_path = os.path.join(app.config['CHECKPOINT_FOLDER'], checkpoint_name) task_names = load_task_names(checkpoint_path) num_tasks = len(task_names) gpu = request.form.get('gpu') # Create and modify args parser = ArgumentParser() add_predict_args(parser) args = parser.parse_args() preds_path = os.path.join(app.config['TEMP_FOLDER'], app.config['PREDICTIONS_FILENAME']) args.test_path = 'None' # TODO: Remove this hack to avoid assert crashing in modify_predict_args args.preds_path = preds_path args.checkpoint_path = checkpoint_path args.write_smiles = True if gpu is not None: if gpu == 'None': args.no_cuda = True else: args.gpu = int(gpu) modify_predict_args(args) # Run predictions preds = make_predictions(args, smiles=smiles) if all(p is None for p in preds): return render_predict(errors=['All SMILES are invalid']) # Replace invalid smiles with message invalid_smiles_warning = "Invalid SMILES String" preds = [ pred if pred is not None else [invalid_smiles_warning] * num_tasks for pred in preds ] return render_predict( predicted=True, smiles=smiles, num_smiles=min(10, len(smiles)), show_more=max(0, len(smiles) - 10), task_names=task_names, num_tasks=len(task_names), preds=preds, warnings=["List contains invalid SMILES strings"] if None in preds else None, errors=["No SMILES strings given"] if len(preds) == 0 else None)