> ## Documentation Index
> Fetch the complete documentation index at: https://data.avert.ldeo.columbia.edu/llms.txt
> Use this file to discover all available pages before exploring further.

# RKPI

> Villarrica RKPI

export const RKPICo2Chart = ({availableYears = [], defaultYear}) => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [selectedYear, setSelectedYear] = useState(defaultYear || (availableYears.length > 0 ? availableYears[0] : new Date().getFullYear()));
  const years = useMemo(() => availableYears, [availableYears]);
  const chartId = "rkpi-co2-chart";
  const triggerBlobDownload = async (url, fallbackFilename) => {
    try {
      const response = await fetch(url, {
        method: "GET",
        mode: "cors",
        headers: {
          Accept: "application/octet-stream, application/csv, */*"
        }
      });
      if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
      const blob = await response.blob();
      let filename = fallbackFilename;
      const cd = response.headers.get("Content-Disposition");
      if (cd) {
        const match = cd.match(/filename=([^;]+)$/i);
        if (match && match[1]) filename = match[1].replace(/\"/g, "").trim();
      }
      const href = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = href;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(href);
    } catch (e) {
      console.error("Download failed:", e);
      alert("Failed to download file. Please try again.");
    }
  };
  const renderChart = (data, yearForDownload) => {
    if (typeof window !== "undefined" && window.Plotly) {
      const chartDiv = document.getElementById(chartId);
      if (chartDiv) {
        const config = {
          ...data.chart_config.config,
          modeBarButtonsToAdd: [{
            name: "Download Year CSV",
            icon: window.Plotly.Icons.disk || window.Plotly.Icons.camera,
            click: () => {
              const url = `https://avert.ldeo.columbia.edu/api/download/rkpi/${yearForDownload}/co2`;
              const fname = `RKPI_co2_${yearForDownload}.csv`;
              triggerBlobDownload(url, fname);
            }
          }],
          modeBarButtonsToRemove: [...data.chart_config.config?.modeBarButtonsToRemove || [], "zoom2d", "autoScale2d"]
        };
        const layout = {
          ...data.chart_config.layout,
          height: 600,
          paper_bgcolor: "rgba(0,0,0,0)",
          plot_bgcolor: "rgba(0,0,0,0)"
        };
        window.Plotly.newPlot(chartDiv, data.chart_config.data, layout, config);
      }
    }
  };
  const loadPlotly = () => {
    return new Promise(resolve => {
      if (typeof window !== "undefined") {
        if (window.Plotly) {
          resolve();
        } else {
          const script = document.createElement("script");
          script.src = "https://cdn.plot.ly/plotly-latest.min.js";
          script.onload = resolve;
          if (!document.querySelector('script[src*="plotly-latest"]')) {
            document.head.appendChild(script);
          }
        }
      } else {
        resolve();
      }
    });
  };
  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        setError(null);
        await loadPlotly();
        const url = `https://avert.ldeo.columbia.edu/api/generate-interactive-chart/rkpi/co2?year=${selectedYear}`;
        const response = await fetch(url, {
          method: "POST",
          mode: "cors",
          headers: {
            "Content-Type": "application/json",
            Accept: "application/json"
          }
        });
        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
        const data = await response.json();
        if (data.success) {
          setTimeout(() => renderChart(data, selectedYear), 100);
        } else {
          throw new Error("Failed to generate chart");
        }
      } catch (err) {
        setError(err.message);
        console.error("Error:", err);
      } finally {
        setLoading(false);
      }
    };
    fetchData();
  }, [selectedYear]);
  if (loading) {
    return <div className="flex items-center justify-center h-64">
        <div className="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-[#0B1D26]"></div>
        <p className="ml-4 text-gray-600 dark:text-gray-300">
          Loading chart data...
        </p>
      </div>;
  }
  if (error) {
    return <div className="items-center justify-center text-red-500 p-4 border border-red-300 rounded-md bg-red-50 dark:bg-red-900 dark:border-red-700">
        <p>{error}</p>
      </div>;
  }
  return <div className="border border-zinc-950/20 dark:border-white/20 rounded-xl overflow-hidden relative">
      <div className="bg-zinc-50 dark:bg-zinc-900 px-4 py-3 border-b border-zinc-950/20 dark:border-white/20">
        <div className="flex items-center justify-between">
          <div className="text-sm font-medium text-zinc-950 dark:text-white">
            [{selectedYear}] Soil CO₂ Monitoring - RKPI (VILLARRICA)
          </div>
          <select value={selectedYear} onChange={e => setSelectedYear(parseInt(e.target.value))} className="text-xs px-2 py-1 border border-zinc-300 dark:border-zinc-600 rounded bg-white dark:bg-zinc-800">
            {years.map(yearOption => <option key={yearOption} value={yearOption}>
                {yearOption}
              </option>)}
          </select>
        </div>
      </div>
      <div id={chartId} style={{
    width: "100%",
    height: "600px"
  }} className="relative"></div>
      <div className="px-4 py-3 bg-zinc-50 dark:bg-zinc-900 border-t border-zinc-950/20 dark:border-white/20 flex items-center justify-between">
        <div className="text-xs text-zinc-600 dark:text-zinc-300">
          Download processed CO₂ concentration data across all available years (CSV)
        </div>
        <button onClick={() => triggerBlobDownload("https://avert.ldeo.columbia.edu/api/download/rkpi/all-years/co2", "RKPI_co2_all_years.csv")} className="text-xs px-3 py-1 rounded bg-[#0B1D26] text-white hover:bg-[#0B1D26]/80">
          Download all-years (.csv)
        </button>
      </div>

      <style>{`
        #${chartId} .modebar-group {
          display: flex !important;
          flex-direction: column !important;
        }
      `}</style>
    </div>;
};

<RKPICo2Chart availableYears={[2026]} defaultYear={2026} />

The interactive chart above displays continuous soil CO₂ measurements from the RKPI monitoring station at Villarrica volcano, Chile. The LCO channel records CO₂ concentration in parts per million at 1 Hz and is resampled to 1-minute means.

## Station Information

**Location:** Villarrica volcano, Chile

**Network:** VC (Villarrica)

**Instrumentation:**

* LCO channel: soil CO₂ concentration (1 Hz)
* LDO channel: soil temperature (1 Hz)

**Data Collection:**

* Continuous CO₂ concentration measurements via miniseed archive
* Data resampled to 1-minute means

**Co-located instruments:**

* HHE/HHN/HHZ: broadband seismic (100 Hz, RSAM)
* HDF: infrasound (100 Hz, RSAM)
* LDO: soil temperature
