Skip to content

Commit

Permalink
Merge branch 'development' into doi
Browse files Browse the repository at this point in the history
  • Loading branch information
CS76 committed Dec 2, 2024
2 parents 063f0fe + 73380ae commit a8eef52
Show file tree
Hide file tree
Showing 83 changed files with 13,363 additions and 1,652 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ COCONUT infrastructure code is licensed under the MIT license - see the [LICENSE

## ![Citations](https://www.google.com/s2/favicons?domain=doi.org)Citations

### COCONUT 2.0
- Venkata Chandrasekhar, Kohulan Rajan, Sri Ram Sagar Kanakam, Nisha Sharma, Viktor Weißenborn, Jonas Schaub, Christoph Steinbeck, COCONUT 2.0: a comprehensive overhaul and curation of the collection of open natural products database, Nucleic Acids Research, 2024;, gkae1063, https://doi.org/10.1093/nar/gkae1063

### COCONUT (Legacy)
- Sorokina, M., Merseburger, P., Rajan, K. et al. (2021). COCONUT online: COlleCtion of Open Natural prodUcTs database. *Journal of Cheminformatics*, 13, 2.
https://doi.org/10.1186/s13321-020-00478-9

### COCONUT 2.0
- Nainala, V.C., Rajan, K., Kanakam, S.R.S., Sharma, N., Weißenborn, V., Schaub, J., et al. (2024). COCONUT 2.0: A comprehensive overhaul and curation of the collection of open natural products database. *ChemRxiv*.
https://doi.org/10.26434/chemrxiv-2024-fxq2s

## ![Maintained](https://www.google.com/s2/favicons?domain=uni-jena.de) Maintained by

Expand Down
75 changes: 25 additions & 50 deletions app/Actions/Coconut/SearchMolecule.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function query($query, $size, $type, $sort, $tagType, $page)
$this->query = $query;
$this->size = $size;
$this->type = $type;

$this->sort = $sort;
$this->tagType = $tagType;
$this->page = $page;
Expand All @@ -61,10 +62,15 @@ public function query($query, $size, $type, $sort, $tagType, $page)
}
$queryType = strtolower($queryType);

$filterMap = $this->getFilterMap();
$filterMap = getFilterMap();

if ($queryType == 'tags') {
$results = $this->buildTagsStatement($offset);
} elseif ($queryType == 'filters') {
$statement = $this->buildStatement($queryType, $offset, $filterMap);
if ($statement) {
$results = $this->executeQuery($statement);
}
} else {
$statement = $this->buildStatement($queryType, $offset, $filterMap);
if ($statement) {
Expand All @@ -73,11 +79,9 @@ public function query($query, $size, $type, $sort, $tagType, $page)
}

return [$results, $this->collection, $this->organisms];

} catch (QueryException $exception) {

return $this->handleException($exception);

}
}

Expand All @@ -89,6 +93,7 @@ private function determineQueryType($query)
$patterns = [
'inchi' => '/^((InChI=)?[^J][0-9BCOHNSOPrIFla+\-\(\)\\\\\/,pqbtmsih]{6,})$/i',
'inchikey' => '/^([0-9A-Z\-]{27})$/i', // Modified to ensure exact length
'parttialinchikey' => '/^([A-Z]{14})$/i',
'smiles' => '/^([^J][0-9BCOHNSOPrIFla@+\-\[\]\(\)\\\\\/%=#$]{6,})$/i',
];

Expand All @@ -102,6 +107,8 @@ private function determineQueryType($query)
return 'inchi';
} elseif ($type == 'inchikey' && substr($query, 14, 1) == '-' && strlen($query) == 27) {
return 'inchikey';
} elseif ($type == 'parttialinchikey' && strlen($query) == 14) {
return 'parttialinchikey';
} elseif ($type == 'smiles') {
return 'smiles';
}
Expand All @@ -111,43 +118,6 @@ private function determineQueryType($query)
return 'text';
}

/**
* Return a mapping of filter codes to database columns.
*/
private function getFilterMap()
{
return [
'mf' => 'molecular_formula',
'mw' => 'molecular_weight',
'hac' => 'heavy_atom_count',
'tac' => 'total_atom_count',
'arc' => 'aromatic_ring_count',
'rbc' => 'rotatable_bond_count',
'mrc' => 'minimal_number_of_rings',
'fc' => 'formal_charge',
'cs' => 'contains_sugar',
'crs' => 'contains_ring_sugars',
'cls' => 'contains_linear_sugars',
'npl' => 'np_likeness_score',
'alogp' => 'alogp',
'topopsa' => 'topo_psa',
'fsp3' => 'fsp3',
'hba' => 'h_bond_acceptor_count',
'hbd' => 'h_bond_donor_count',
'ro5v' => 'rule_of_5_violations',
'lhba' => 'lipinski_h_bond_acceptor_count',
'lhbd' => 'lipinski_h_bond_donor_count',
'lro5v' => 'lipinski_rule_of_5_violations',
'ds' => 'found_in_databases',
'class' => 'chemical_class',
'subclass' => 'chemical_sub_class',
'superclass' => 'chemical_super_class',
'parent' => 'direct_parent_classification',
'org' => 'organism',
'cite' => 'ciatation',
];
}

/**
* Build the SQL statement based on the query type.
*/
Expand Down Expand Up @@ -175,6 +145,7 @@ private function buildStatement($queryType, $offset, $filterMap)
break;

case 'inchikey':
case 'parttialinchikey':
$statement = "SELECT id, COUNT(*) OVER ()
FROM molecules
WHERE standard_inchi_key LIKE '%{$this->query}%'
Expand Down Expand Up @@ -262,19 +233,23 @@ private function buildTagsStatement($offset)
private function buildFiltersStatement($filterMap)
{
$orConditions = explode('OR', $this->query);
$statement = 'SELECT molecule_id as id, COUNT(*) OVER ()
FROM properties WHERE ';

foreach ($orConditions as $index => $orCondition) {
if ($index > 0) {
$statement = 'SELECT properties.molecule_id as id, COUNT(*) OVER ()
FROM properties
INNER JOIN molecules ON properties.molecule_id = molecules.id
WHERE molecules.active = TRUE
AND NOT (molecules.is_parent = TRUE AND molecules.has_variants = TRUE)
AND ';

foreach ($orConditions as $outerIndex => $orCondition) {
if ($outerIndex > 0) {
$statement .= ' OR ';
}

$andConditions = explode(' ', trim($orCondition));
$statement .= '(';

foreach ($andConditions as $index => $andCondition) {
if ($index > 0) {
foreach ($andConditions as $innerIndex => $andCondition) {
if ($innerIndex > 0) {
$statement .= ' AND ';
}

Expand Down Expand Up @@ -326,7 +301,7 @@ private function buildDefaultStatement($offset)
WHEN \"name\"::TEXT ILIKE '%{$this->query}%' THEN 4
WHEN \"synonyms\"::TEXT ILIKE '%{$this->query}%' THEN 5
WHEN \"identifier\"::TEXT ILIKE '%{$this->query}%' THEN 6
ELSE 7
ELSE 7
END
LIMIT {$this->size} OFFSET {$offset}";
} else {
Expand All @@ -350,16 +325,16 @@ private function executeQuery($statement)

$ids_array = collect($hits)->pluck('id')->toArray();
$ids = implode(',', $ids_array);
// dd($ids);

if ($ids != '') {

$statement = "
SELECT identifier, canonical_smiles, annotation_level, name, iupac_name, organism_count, citation_count, geo_count, collection_count
FROM molecules
WHERE id = ANY (array[{$ids}])
WHERE id = ANY (array[{$ids}]) AND active = TRUE AND NOT (is_parent = TRUE AND has_variants = TRUE)
ORDER BY array_position(array[{$ids}], id);
";

if ($this->sort == 'recent') {
$statement .= ' ORDER BY created_at DESC';
}
Expand Down
18 changes: 9 additions & 9 deletions app/Console/Commands/DashWidgetsRefresh.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,49 +32,49 @@ public function handle()
// Cache::flush();

// Create the cache for all DashboardStats widgets
Cache::remember('stats.collections', 172800, function () {
Cache::rememberForever('stats.collections', function () {
return DB::table('collections')->selectRaw('count(*)')->get()[0]->count;
});
$this->info('Cache for collections refreshed.');

Cache::remember('stats.citations', 172800, function () {
Cache::rememberForever('stats.citations', function () {
return DB::table('citations')->selectRaw('count(*)')->get()[0]->count;
});
$this->info('Cache for citations refreshed.');

Cache::remember('stats.organisms', 172800, function () {
Cache::rememberForever('stats.organisms', function () {
return DB::table('organisms')->selectRaw('count(*)')->get()[0]->count;
});
$this->info('Cache for organisms refreshed.');

Cache::remember('stats.geo_locations', 172800, function () {
Cache::rememberForever('stats.geo_locations', function () {
return DB::table('geo_locations')->selectRaw('count(*)')->get()[0]->count;
});
$this->info('Cache for geo locations refreshed.');

Cache::remember('stats.reports', 172800, function () {
Cache::rememberForever('stats.reports', function () {
return DB::table('reports')->selectRaw('count(*)')->get()[0]->count;
});
$this->info('Cache for reports refreshed.');

// Create the cache for all DashboardStatsMid widgets

Cache::remember('stats.molecules.non_stereo', 172800, function () {
Cache::rememberForever('stats.molecules.non_stereo', function () {
return DB::table('molecules')->selectRaw('count(*)')->whereRaw('has_stereo=false and is_parent=false')->get()[0]->count;
});
$this->info('Cache for molecules non-stereo refreshed.');

Cache::remember('stats.molecules.stereo', 172800, function () {
Cache::rememberForever('stats.molecules.stereo', function () {
return DB::table('molecules')->selectRaw('count(*)')->whereRaw('has_stereo=true')->get()[0]->count;
});
$this->info('Cache for molecules stereo refreshed.');

Cache::remember('stats.molecules.parent', 172800, function () {
Cache::rememberForever('stats.molecules.parent', function () {
return DB::table('molecules')->selectRaw('count(*)')->whereRaw('has_stereo=false and is_parent=true')->get()[0]->count;
});
$this->info('Cache for molecules parent refreshed.');

Cache::remember('stats.molecules', 172800, function () {
Cache::rememberForever('stats.molecules', function () {
return DB::table('molecules')->selectRaw('count(*)')->whereRaw('active=true and NOT (is_parent=true AND has_variants=true)')->get()[0]->count;
});
$this->info('Cache for molecules refreshed.');
Expand Down
Loading

0 comments on commit a8eef52

Please sign in to comment.