From 2dae251b9bf19ee040fec47da874edb3db1b3e45 Mon Sep 17 00:00:00 2001
From: Romain Broucquart <romain.broucquart@synchrotron-soleil.fr>
Date: Thu, 4 Apr 2024 15:17:07 +0200
Subject: [PATCH] feat: Add extract between dates for vectors

* Also fix missing Dynamic Attribute removal for method=nearest
---
 ArchiveExtractor/Core.py | 56 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/ArchiveExtractor/Core.py b/ArchiveExtractor/Core.py
index c46b006..58246e4 100644
--- a/ArchiveExtractor/Core.py
+++ b/ArchiveExtractor/Core.py
@@ -169,6 +169,8 @@ def _extract_vector(attribute, method, date1, date2, db):
         # Read the history
         logger.debug("Retrieve history of %d values. Dynamic attribute named %s."%(N, name))
         attrHist = ae._Extractors[{'H':0, 'T':1}[db]].attribute_history(name, N)
+        ae._Extractors[{'H':0, 'T':1}[db]].RemoveDynamicAttribute(name)
+
 
         # Transform to datetime - value arrays
         mx = min(int(info["max_dim_x"]), 2048) # Quick fix: Crop dimension
@@ -183,11 +185,61 @@ def _extract_vector(attribute, method, date1, date2, db):
         idx=np.argmin(abs(_date-date1))
         logger.debug("Found nearest value at index {}: {}".format(idx, _date[idx]))
 
-        # Fabricate return pandas.Series
-        d=pd.Series(index=[_date[idx],], data=[_value[idx],], name=attribute)
+        # Fabricate return pandas.Series, droping empty columns
+        d=pd.Series(index=[_date[idx],], data=[_value[idx],], name=attribute).dropna(axis=1, how='all')
 
         return d
 
+    # =====================
+    if method == "between":
+        # Cut the time horizon in chunks
+        cdates = aea._chunkerize(attribute, date1, date2, db)
+
+        # Array to hold data
+        data = []
+
+        # For each date chunk
+        for i_d in range(len(cdates)-1):
+            cmdreturn = aea._cmd_with_retry(ae._Extractors[{'H':0, 'T':1}[db]], "GetAttDataBetweenDates", [
+                                                    attribute,
+                                                    cdates[i_d].strftime(aea._DBDFMT),
+                                                    cdates[i_d+1].strftime(aea._DBDFMT)
+                                                    ])
+
+            # Unpack return
+            try:
+                [N,], [name,] = cmdreturn
+                N=int(N)
+            except TypeError:
+                logger.error("Could not extract this attribute. Check the device extractor")
+                return None
+
+
+            # Read the history
+            logger.debug("Retrieve history of %d values. Dynamic attribute named %s."%(N, name))
+            attrHist = ae._Extractors[{'H':0, 'T':1}[db]].attribute_history(name, N)
+            ae._Extractors[{'H':0, 'T':1}[db]].RemoveDynamicAttribute(name)
+
+            # Transform to datetime - value arrays
+            mx = min(int(info["max_dim_x"]), 2048) # Quick fix: Crop dimension
+            _value = np.empty((N, mx), dtype=float)
+            _value[:] = np.nan
+            _date = np.empty(N, dtype=object)
+            for i_h in range(N):
+                _value[i_h,:attrHist[i_h].dim_x]=attrHist[i_h].value
+                _date[i_h]=attrHist[i_h].time.todatetime()
+
+            # Fabricate return pandas.Series
+            data.append(pd.DataFrame(index=_date, data=_value))
+
+        # Concatenate chunks, dropping empty columns
+        return pd.concat(data).dropna(axis=1, how='all')
+
+    # ========================
+    if method == "minmaxmean":
+        pass
+
+
     # If we are here, the method is not implemented
     logger.error("Method {} is not implemented for vectors.".format(method))
     raise NotImplemented
-- 
GitLab