Skip to content

Commit

Permalink
Merge pull request #317 from Steinbeck-Lab/feat-charts
Browse files Browse the repository at this point in the history
Feat charts
  • Loading branch information
CS76 authored Dec 13, 2024
2 parents a50c181 + 36fe92a commit ef6aa30
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 30 deletions.
82 changes: 82 additions & 0 deletions app/Console/Commands/GenerateBubbleFrequencyCharts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;

class GenerateBubbleFrequencyCharts extends Command
{
protected $signature = 'coconut:generate-bubble-frequency-charts';

protected $description = 'Generate bubble frequency charts data for molecular tables and columns';

private $columnsForCharts = [
[
'first_column' => 'chemical_class',
'first_table' => 'properties',
'second_column' => 'np_classifier_class',
'second_table' => 'properties',
],
];

public function handle()
{
$bubbleFrequencyPlotData = [];

foreach ($this->columnsForCharts as $columnsInfo) {
$first_column = $columnsInfo['first_column'];
$second_column = $columnsInfo['second_column'];
$first_table = $columnsInfo['first_table'];
$second_table = $columnsInfo['second_table'];

$query1 = "SELECT DISTINCT f.$first_column col, COUNT(*) count FROM $first_table f WHERE f.$first_column IS NOT NULL AND f.$first_column!='' ";
$first_table == 'properties' ? $query1.'JOIN molecules m ON f.molecule_id=m.id WHERE m.active = TRUE AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE) ' : '';
$query2 = "SELECT DISTINCT s.$second_column col, COUNT(*) count FROM $second_table s WHERE s.$second_column IS NOT NULL AND s.$second_column!='' ";
$second_table == 'properties' ? $query2.'JOIN molecules m ON s.molecule_id=m.id WHERE m.active = TRUE AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE) ' : '';

$query1 .= 'GROUP BY 1';
$query2 .= 'GROUP BY 1';

$bubbleFrequencyPlotData[$first_column.'|'.$second_column.'|'.uniqid()] = DB::select("
WITH
t1 as ($query1)
SELECT t1.col column_values, t1.count first_column_count from t1 order by 2 desc limit 170;
");

$bubbleFrequencyPlotData[$first_column.'|'.$second_column.'|'.uniqid()] = DB::select("
WITH
t1 as ($query2)
SELECT t1.col column_values, t1.count second_column_count from t1 order by 2 desc limit 170;
");

// $bubbleFrequencyPlotData[$first_column.'|'.$second_column.'|'.uniqid()] = DB::select("
// WITH
// t1 as ($query1),
// t2 as ($query2)
// SELECT COALESCE(t1.col, t2.col) column_values , t1.count first_column_count, t2.count second_column_count FROM t1 LEFT JOIN t2 ON t1.col=t2.col WHERE t2.col IS NULL
// ;
// ");

// $bubbleFrequencyPlotData[$first_column.'|'.$second_column.'|'.uniqid()] = DB::select("
// WITH
// t1 as ($query1),
// t2 as ($query2)
// SELECT COALESCE(t1.col, t2.col) column_values , t1.count first_column_count, t2.count second_column_count FROM t1 RIGHT JOIN t2 ON t1.col=t2.col WHERE t1.col IS NULL
// ;
// ");

}

$filePath = public_path('reports/bubble_frequency_charts.json');
if (! file_exists(dirname($filePath))) {
mkdir(dirname($filePath), 0777, true);
}

File::put($filePath, json_encode($bubbleFrequencyPlotData, JSON_UNESCAPED_SLASHES));

$this->info('Bubble Frequency charts data saved to: public/reports/bubble_frequency_charts.json');

}
}
32 changes: 22 additions & 10 deletions app/Console/Commands/GenerateDensityCharts.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class GenerateDensityCharts extends Command

private $density_bins = 30;

private $excluded_collections = '63';

private $columnsToSkip = [
'properties' => [
'id',
Expand Down Expand Up @@ -249,9 +251,9 @@ private function calculateDensity(string $table, string $column, string $dataTyp
COUNT($column) as count,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY $column) as median
FROM $table p
LEFT JOIN molecules m ON p.molecule_id = m.id
WHERE m.active = TRUE
AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE);
JOIN molecules m ON p.molecule_id = m.id
join collection_molecule cm on p.molecule_id = cm.molecule_id
WHERE m.active = TRUE AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE) and cm.collection_id!=63;
")[0];
} else {
$stats = DB::select("
Expand All @@ -261,8 +263,10 @@ private function calculateDensity(string $table, string $column, string $dataTyp
COUNT($column) as count,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY $column) as median
FROM $table m
join collection_molecule cm on m.id = cm.molecule_id
WHERE m.active = TRUE
AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE);
AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE)
and cm.collection_id!=63;
")[0];
}

Expand Down Expand Up @@ -367,23 +371,27 @@ private function getDensityStats($stats, $table, $column)
$query = "
SELECT distinct p.$column as value, count(*) as count
FROM $table p
JOIN molecules m ON p.molecule_id = m.id";
JOIN molecules m ON p.molecule_id = m.id ";

// For collection-wise stats
if ($id) {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id = $id";
} else {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id not in ($this->excluded_collections) ";
}

$query .= " WHERE m.active = TRUE AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE)
GROUP BY p.$column";
} else {
$query = "
SELECT distinct m.$column as value, count(*) as count
FROM $table m";
FROM $table m ";

// For collection-wise stats
if ($id) {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id = $id";
} else {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id not in ($this->excluded_collections) ";
}

$query .= " WHERE m.active = TRUE AND NOT (m.is_parent = TRUE AND m.has_variants = TRUE)
Expand Down Expand Up @@ -414,13 +422,15 @@ private function getDensityStats($stats, $table, $column)

if ($table != 'molecules') {
$query = "
SELECT count(*) as count
SELECT count(distinct m.id) as count
FROM $table p
JOIN molecules m ON p.molecule_id = m.id";
JOIN molecules m ON p.molecule_id = m.id ";

// For collection-wise stats
if ($id) {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id = $id";
} else {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id not in ($this->excluded_collections) ";
}

$query .= " WHERE (CAST(p.$column AS DECIMAL(10,2)) BETWEEN ? AND ?)
Expand All @@ -430,12 +440,14 @@ private function getDensityStats($stats, $table, $column)
$count = DB::select($query, [$binStart, $binEnd])[0]->count;
} else {
$query = "
SELECT count(*) as count
FROM $table m";
SELECT count(distinct m.id) as count
FROM $table m ";

// For collection-wise stats
if ($id) {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id = $id";
} else {
$query .= " JOIN collection_molecule cm ON cm.molecule_id = m.id AND cm.collection_id not in ($this->excluded_collections) ";
}

$query .= " WHERE (CAST(m.$column AS DECIMAL(10,2)) BETWEEN ? AND ?)
Expand Down
42 changes: 42 additions & 0 deletions app/Livewire/BubbleFrequencyPlot.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace App\Livewire;

use Livewire\Component;

class BubbleFrequencyPlot extends Component
{
public $chartData;

public $firstColumnName;

public $secondColumnName;

public $chartId;

public $name_corrections = [

];

public function mount($chartName, $chartData)
{
// Extract column names
[$this->firstColumnName, $this->secondColumnName] = explode('|', $chartName);

// Ensure data is properly formatted
$this->chartData = array_map(function ($item) {
return [
'column_values' => $item['column_values'],
'first_column_count' => $item['first_column_count'] ?? 0,
'second_column_count' => $item['second_column_count'] ?? 0,
];
}, $chartData);

$this->chartId = 'bubble-chart-'.uniqid();
}

public function render()
{
return view('livewire.bubble-frequency-plot');
}
}
55 changes: 37 additions & 18 deletions app/Livewire/Stats.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,53 @@ class Stats extends Component
{
public $properties_json_data = [];

public $bubble_frequency_json_data = [];

public function mount()
{
$jsonPath = public_path('reports/density_charts.json');

try {
if (! file_exists($jsonPath)) {
throw new \Exception('Density chart data file not found');
// update the switch cases when you add new paths to this
$plotDataFiles = [
'reports/density_charts.json',
'reports/bubble_frequency_charts.json',
];

foreach ($plotDataFiles as $filePath) {
$plotJson = public_path($filePath);

try {
if (! file_exists($plotJson)) {
throw new \Exception('Density chart data file not found');
}

$jsonContent = file_get_contents($plotJson);
$decodedData = json_decode($jsonContent, true);

if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception('Error decoding JSON data: '.json_last_error_msg());
}

// Store in the corresponding public properties - updade this when adding a new path
switch ($filePath) {
case 'reports/density_charts.json':
$this->properties_json_data = $decodedData['properties'];
break;
case 'reports/bubble_frequency_charts.json':
$this->bubble_frequency_json_data = $decodedData;
break;
default:
break;
}
} catch (\Exception $e) {
\Log::error('Failed to load '.$filePath.' chart data: '.$e->getMessage());
}

$jsonContent = file_get_contents($jsonPath);
$decodedData = json_decode($jsonContent, true);

if (json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception('Error decoding JSON data: '.json_last_error_msg());
}

// Store in the public property
$this->properties_json_data = $decodedData['properties'];

} catch (\Exception $e) {
\Log::error('Failed to load density chart data: '.$e->getMessage());
}
}

public function render()
{
return view('livewire.stats', [
'properties_json_data' => $this->properties_json_data,
'bubble_frequency_json_data' => $this->bubble_frequency_json_data,
]);
}
}
1 change: 1 addition & 0 deletions public/reports/bubble_frequency_charts.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions resources/views/layouts/app.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

<!-- Styles -->
@livewireStyles
@stack('styles')
</head>

<body class="font-sans antialiased">
Expand Down Expand Up @@ -67,6 +68,7 @@

@stack('modals')
@livewireScripts
@stack('scripts')
@include('cookie-consent::index')
</body>

Expand Down
Loading

0 comments on commit ef6aa30

Please sign in to comment.