##// END OF EJS Templates
Merge branch 'feature/AMDAv2' into develop
Alexandre Leroux -
r729:a187c20183b4 merge
parent child
Show More
@@ -0,0 +1,3
1 Not Found
2
3 The requested URL /AMDA/data/WSRESULT/imf(0)-1343153090-1343153092-60.txt was not found on this server. No newline at end of file
@@ -0,0 +1,6
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 2013-09-23T09:00:30.000 NaN
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
@@ -0,0 +1,6
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 NaN -3.01425
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
@@ -0,0 +1,2
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls No newline at end of file
@@ -0,0 +1,6
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 2013-09-23T09:00:30.000 -2.83950 1.05141 3.01547
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
@@ -0,0 +1,13
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 2013-09-23T09:00:30.000 -2.83950
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150
7 2013-09-23T09:03:30.000 -2.57633
8 2013-09-23T09:04:30.000 -2.58050
9 2013-09-23T09:05:30.000 -2.48325
10 2013-09-23T09:06:30.000 -2.63025
11 2013-09-23T09:07:30.000 -2.55800
12 2013-09-23T09:08:30.000 -2.43250
13 2013-09-23T09:09:30.000 -2.42200 No newline at end of file
@@ -0,0 +1,12
1 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 #imf - Type : Local Parameter @ CDPP/AMDA - Name : imf_gse - Units : nT - Size : 3 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 2013-07-02T09:13:50.000 -0.332000 3.20600 0.0580000
4 2013-07-02T09:14:06.000 -1.01100 2.99900 0.496000
5 2013-07-02T09:14:22.000 -1.45700 2.78500 1.01800
6 2013-07-02T09:14:38.000 -1.29300 2.73600 1.48500
7 2013-07-02T09:14:54.000 -1.21700 2.61200 1.66200
8 2013-07-02T09:15:10.000 -1.44300 2.56400 1.50500
9 2013-07-02T09:15:26.000 -1.27800 2.89200 1.16800
10 2013-07-02T09:15:42.000 -1.20200 2.86200 1.24400
11 2013-07-02T09:15:58.000 -1.22000 2.85900 1.15000
12 2013-07-02T09:16:14.000 -1.25900 2.76400 1.35800 No newline at end of file
@@ -0,0 +1,6
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 23/09/2013 07:50:30 -2.83950
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
@@ -0,0 +1,6
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #Wrong unit comment
4 2013-09-23T09:00:30.000 -2.83950
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
@@ -0,0 +1,6
1 #Sampling Time : 60
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
4 2013-09-23T09:00:30.000 abc
5 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
@@ -1,283 +1,284
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10
10
11 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
12 #include <QNetworkReply>
13 #include <QTemporaryFile>
13 #include <QTemporaryFile>
14 #include <QThread>
14 #include <QThread>
15
15
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
17
18 namespace {
18 namespace {
19
19
20 /// URL format for a request on AMDA server. The parameters are as follows:
20 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// - %1: start date
21 /// - %1: start date
22 /// - %2: end date
22 /// - %2: end date
23 /// - %3: parameter id
23 /// - %3: parameter id
24 /// Old url: http://amda.irap.omp.eu/php/rest/
24 const auto AMDA_URL_FORMAT = QStringLiteral(
25 const auto AMDA_URL_FORMAT = QStringLiteral(
25 "http://amda.irap.omp.eu/php/rest/"
26 "http://amdatest.irap.omp.eu/php/rest/"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 "timeFormat=ISO8601&gzip=0");
28 "timeFormat=ISO8601&gzip=0");
28
29
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31
32
32 /// Formats a time to a date that can be passed in URL
33 /// Formats a time to a date that can be passed in URL
33 QString dateFormat(double sqpRange) noexcept
34 QString dateFormat(double sqpRange) noexcept
34 {
35 {
35 auto dateTime = DateUtils::dateTime(sqpRange);
36 auto dateTime = DateUtils::dateTime(sqpRange);
36 return dateTime.toString(AMDA_TIME_FORMAT);
37 return dateTime.toString(AMDA_TIME_FORMAT);
37 }
38 }
38
39
39 AmdaResultParser::ValueType valueType(const QString &valueType)
40 AmdaResultParser::ValueType valueType(const QString &valueType)
40 {
41 {
41 if (valueType == QStringLiteral("scalar")) {
42 if (valueType == QStringLiteral("scalar")) {
42 return AmdaResultParser::ValueType::SCALAR;
43 return AmdaResultParser::ValueType::SCALAR;
43 }
44 }
44 else if (valueType == QStringLiteral("vector")) {
45 else if (valueType == QStringLiteral("vector")) {
45 return AmdaResultParser::ValueType::VECTOR;
46 return AmdaResultParser::ValueType::VECTOR;
46 }
47 }
47 else {
48 else {
48 return AmdaResultParser::ValueType::UNKNOWN;
49 return AmdaResultParser::ValueType::UNKNOWN;
49 }
50 }
50 }
51 }
51
52
52 } // namespace
53 } // namespace
53
54
54 AmdaProvider::AmdaProvider()
55 AmdaProvider::AmdaProvider()
55 {
56 {
56 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
57 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
57 if (auto app = sqpApp) {
58 if (auto app = sqpApp) {
58 auto &networkController = app->networkController();
59 auto &networkController = app->networkController();
59 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
60 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
60 std::function<void(QNetworkReply *, QUuid)>)),
61 std::function<void(QNetworkReply *, QUuid)>)),
61 &networkController,
62 &networkController,
62 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
63 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
63 std::function<void(QNetworkReply *, QUuid)>)));
64 std::function<void(QNetworkReply *, QUuid)>)));
64
65
65
66
66 connect(&sqpApp->networkController(),
67 connect(&sqpApp->networkController(),
67 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
68 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
68 this,
69 this,
69 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
70 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
70 }
71 }
71 }
72 }
72
73
73 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
74 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
74 {
75 {
75 // No copy is made in the clone
76 // No copy is made in the clone
76 return std::make_shared<AmdaProvider>();
77 return std::make_shared<AmdaProvider>();
77 }
78 }
78
79
79 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
80 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
80 {
81 {
81 // NOTE: Try to use multithread if possible
82 // NOTE: Try to use multithread if possible
82 const auto times = parameters.m_Times;
83 const auto times = parameters.m_Times;
83 const auto data = parameters.m_Data;
84 const auto data = parameters.m_Data;
84 for (const auto &dateTime : qAsConst(times)) {
85 for (const auto &dateTime : qAsConst(times)) {
85 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
86 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier
86 << dateTime;
87 << dateTime;
87 this->retrieveData(acqIdentifier, dateTime, data);
88 this->retrieveData(acqIdentifier, dateTime, data);
88
89
89
90
90 // TORM when AMDA will support quick asynchrone request
91 // TORM when AMDA will support quick asynchrone request
91 QThread::msleep(1000);
92 QThread::msleep(1000);
92 }
93 }
93 }
94 }
94
95
95 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
96 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
96 {
97 {
97 if (auto app = sqpApp) {
98 if (auto app = sqpApp) {
98 auto &networkController = app->networkController();
99 auto &networkController = app->networkController();
99 networkController.onReplyCanceled(acqIdentifier);
100 networkController.onReplyCanceled(acqIdentifier);
100 }
101 }
101 }
102 }
102
103
103 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
104 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
104 std::shared_ptr<QNetworkRequest> networkRequest,
105 std::shared_ptr<QNetworkRequest> networkRequest,
105 double progress)
106 double progress)
106 {
107 {
107 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
108 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
108 << networkRequest.get() << progress;
109 << networkRequest.get() << progress;
109 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
110 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
110 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
111 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
111
112
112 // Update the progression for the current request
113 // Update the progression for the current request
113 auto requestPtr = networkRequest;
114 auto requestPtr = networkRequest;
114 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
115 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
115
116
116 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
117 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
117 auto requestProgressMapEnd = requestProgressMap.end();
118 auto requestProgressMapEnd = requestProgressMap.end();
118 auto requestProgressMapIt
119 auto requestProgressMapIt
119 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
120 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
120
121
121 if (requestProgressMapIt != requestProgressMapEnd) {
122 if (requestProgressMapIt != requestProgressMapEnd) {
122 requestProgressMapIt->second = progress;
123 requestProgressMapIt->second = progress;
123 }
124 }
124 else {
125 else {
125 // This case can happened when a progression is send after the request has been
126 // This case can happened when a progression is send after the request has been
126 // finished.
127 // finished.
127 // Generaly the case when aborting a request
128 // Generaly the case when aborting a request
128 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
129 qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier
129 << networkRequest.get() << progress;
130 << networkRequest.get() << progress;
130 }
131 }
131
132
132 // Compute the current final progress and notify it
133 // Compute the current final progress and notify it
133 double finalProgress = 0.0;
134 double finalProgress = 0.0;
134
135
135 auto fraq = requestProgressMap.size();
136 auto fraq = requestProgressMap.size();
136
137
137 for (auto requestProgress : requestProgressMap) {
138 for (auto requestProgress : requestProgressMap) {
138 finalProgress += requestProgress.second;
139 finalProgress += requestProgress.second;
139 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
140 qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:")
140 << finalProgress << requestProgress.second;
141 << finalProgress << requestProgress.second;
141 }
142 }
142
143
143 if (fraq > 0) {
144 if (fraq > 0) {
144 finalProgress = finalProgress / fraq;
145 finalProgress = finalProgress / fraq;
145 }
146 }
146
147
147 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
148 qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress;
148 emit dataProvidedProgress(acqIdentifier, finalProgress);
149 emit dataProvidedProgress(acqIdentifier, finalProgress);
149 }
150 }
150 else {
151 else {
151 // This case can happened when a progression is send after the request has been finished.
152 // This case can happened when a progression is send after the request has been finished.
152 // Generaly the case when aborting a request
153 // Generaly the case when aborting a request
153 emit dataProvidedProgress(acqIdentifier, 100.0);
154 emit dataProvidedProgress(acqIdentifier, 100.0);
154 }
155 }
155 }
156 }
156
157
157 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
158 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
158 {
159 {
159 // Retrieves product ID from data: if the value is invalid, no request is made
160 // Retrieves product ID from data: if the value is invalid, no request is made
160 auto productId = data.value(AMDA_XML_ID_KEY).toString();
161 auto productId = data.value(AMDA_XML_ID_KEY).toString();
161 if (productId.isNull()) {
162 if (productId.isNull()) {
162 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
163 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
163 return;
164 return;
164 }
165 }
165
166
166 // Retrieves the data type that determines whether the expected format for the result file is
167 // Retrieves the data type that determines whether the expected format for the result file is
167 // scalar, vector...
168 // scalar, vector...
168 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
169 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
169
170
170 // /////////// //
171 // /////////// //
171 // Creates URL //
172 // Creates URL //
172 // /////////// //
173 // /////////// //
173
174
174 auto startDate = dateFormat(dateTime.m_TStart);
175 auto startDate = dateFormat(dateTime.m_TStart);
175 auto endDate = dateFormat(dateTime.m_TEnd);
176 auto endDate = dateFormat(dateTime.m_TEnd);
176
177
177 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
178 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
178 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
179 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
179 auto tempFile = std::make_shared<QTemporaryFile>();
180 auto tempFile = std::make_shared<QTemporaryFile>();
180
181
181 // LAMBDA
182 // LAMBDA
182 auto httpDownloadFinished = [this, dateTime, tempFile,
183 auto httpDownloadFinished = [this, dateTime, tempFile,
183 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
184 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
184
185
185 // Don't do anything if the reply was abort
186 // Don't do anything if the reply was abort
186 if (reply->error() == QNetworkReply::NoError) {
187 if (reply->error() == QNetworkReply::NoError) {
187
188
188 if (tempFile) {
189 if (tempFile) {
189 auto replyReadAll = reply->readAll();
190 auto replyReadAll = reply->readAll();
190 if (!replyReadAll.isEmpty()) {
191 if (!replyReadAll.isEmpty()) {
191 tempFile->write(replyReadAll);
192 tempFile->write(replyReadAll);
192 }
193 }
193 tempFile->close();
194 tempFile->close();
194
195
195 // Parse results file
196 // Parse results file
196 if (auto dataSeries
197 if (auto dataSeries
197 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
198 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
198 emit dataProvided(dataId, dataSeries, dateTime);
199 emit dataProvided(dataId, dataSeries, dateTime);
199 }
200 }
200 else {
201 else {
201 /// @todo ALX : debug
202 /// @todo ALX : debug
202 emit dataProvidedFailed(dataId);
203 emit dataProvidedFailed(dataId);
203 }
204 }
204 }
205 }
205 qCDebug(LOG_AmdaProvider()) << tr("acquisition requests erase because of finishing")
206 qCDebug(LOG_AmdaProvider()) << tr("acquisition requests erase because of finishing")
206 << dataId;
207 << dataId;
207 m_AcqIdToRequestProgressMap.erase(dataId);
208 m_AcqIdToRequestProgressMap.erase(dataId);
208 }
209 }
209 else {
210 else {
210 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
211 qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR");
211 emit dataProvidedFailed(dataId);
212 emit dataProvidedFailed(dataId);
212 }
213 }
213
214
214 };
215 };
215 auto httpFinishedLambda
216 auto httpFinishedLambda
216 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
217 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
217
218
218 // Don't do anything if the reply was abort
219 // Don't do anything if the reply was abort
219 if (reply->error() == QNetworkReply::NoError) {
220 if (reply->error() == QNetworkReply::NoError) {
220 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
221 auto downloadFileUrl = QUrl{QString{reply->readAll()}.trimmed()};
221
222
222 qCInfo(LOG_AmdaProvider())
223 qCInfo(LOG_AmdaProvider())
223 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
224 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
224 // Executes request for downloading file //
225 // Executes request for downloading file //
225
226
226 // Creates destination file
227 // Creates destination file
227 if (tempFile->open()) {
228 if (tempFile->open()) {
228 // Executes request and store the request for progression
229 // Executes request and store the request for progression
229 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
230 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
230 updateRequestProgress(dataId, request, 0.0);
231 updateRequestProgress(dataId, request, 0.0);
231 emit requestConstructed(request, dataId, httpDownloadFinished);
232 emit requestConstructed(request, dataId, httpDownloadFinished);
232 }
233 }
233 else {
234 else {
234 emit dataProvidedFailed(dataId);
235 emit dataProvidedFailed(dataId);
235 }
236 }
236 }
237 }
237 else {
238 else {
238 qCDebug(LOG_AmdaProvider())
239 qCDebug(LOG_AmdaProvider())
239 << tr("acquisition requests erase because of aborting") << dataId;
240 << tr("acquisition requests erase because of aborting") << dataId;
240 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
241 qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR");
241 m_AcqIdToRequestProgressMap.erase(dataId);
242 m_AcqIdToRequestProgressMap.erase(dataId);
242 emit dataProvidedFailed(dataId);
243 emit dataProvidedFailed(dataId);
243 }
244 }
244 };
245 };
245
246
246 // //////////////// //
247 // //////////////// //
247 // Executes request //
248 // Executes request //
248 // //////////////// //
249 // //////////////// //
249
250
250 auto request = std::make_shared<QNetworkRequest>(url);
251 auto request = std::make_shared<QNetworkRequest>(url);
251 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
252 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
252 updateRequestProgress(token, request, 0.0);
253 updateRequestProgress(token, request, 0.0);
253
254
254 emit requestConstructed(request, token, httpFinishedLambda);
255 emit requestConstructed(request, token, httpFinishedLambda);
255 }
256 }
256
257
257 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
258 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
258 std::shared_ptr<QNetworkRequest> request, double progress)
259 std::shared_ptr<QNetworkRequest> request, double progress)
259 {
260 {
260 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
261 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
261 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
262 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
262 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
263 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
263 auto requestProgressMapIt = requestProgressMap.find(request);
264 auto requestProgressMapIt = requestProgressMap.find(request);
264 if (requestProgressMapIt != requestProgressMap.end()) {
265 if (requestProgressMapIt != requestProgressMap.end()) {
265 requestProgressMapIt->second = progress;
266 requestProgressMapIt->second = progress;
266 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
267 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
267 << acqIdentifier << request.get() << progress;
268 << acqIdentifier << request.get() << progress;
268 }
269 }
269 else {
270 else {
270 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
271 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
271 << request.get() << progress;
272 << request.get() << progress;
272 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
273 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
273 }
274 }
274 }
275 }
275 else {
276 else {
276 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
277 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
277 << acqIdentifier << request.get() << progress;
278 << acqIdentifier << request.get() << progress;
278 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
279 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
279 requestProgressMap.insert(std::make_pair(request, progress));
280 requestProgressMap.insert(std::make_pair(request, progress));
280 m_AcqIdToRequestProgressMap.insert(
281 m_AcqIdToRequestProgressMap.insert(
281 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
282 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
282 }
283 }
283 }
284 }
@@ -1,209 +1,213
1 #include "AmdaResultParser.h"
1 #include "AmdaResultParser.h"
2
2
3 #include <Common/DateUtils.h>
3 #include <Common/DateUtils.h>
4 #include <Data/ScalarSeries.h>
4 #include <Data/ScalarSeries.h>
5 #include <Data/VectorSeries.h>
5 #include <Data/VectorSeries.h>
6
6
7 #include <QDateTime>
7 #include <QDateTime>
8 #include <QFile>
8 #include <QFile>
9 #include <QRegularExpression>
9 #include <QRegularExpression>
10
10
11 #include <cmath>
11 #include <cmath>
12
12
13 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
13 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
14
14
15 namespace {
15 namespace {
16
16
17 /// Message in result file when the file was not found on server
17 /// Message in result file when the file was not found on server
18 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
18 const auto FILE_NOT_FOUND_MESSAGE = QStringLiteral("Not Found");
19
19
20 /// Format for dates in result files
21 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
22
23 /// Separator between values in a result line
20 /// Separator between values in a result line
24 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
21 const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")};
25
22
23 /// Regex to find the header of the data in the file. This header indicates the end of comments in
24 /// the file
25 const auto DATA_HEADER_REGEX = QRegularExpression{QStringLiteral("#\\s*DATA\\s*:")};
26
26 /// Regex to find unit in a line. Examples of valid lines:
27 /// Regex to find unit in a line. Examples of valid lines:
27 /// ... - Units : nT - ...
28 /// ... PARAMETER_UNITS : nT ...
28 /// ... -Units:nT- ...
29 /// ... PARAMETER_UNITS:nT ...
29 /// ... -Units: mΒ²- ...
30 /// ... PARAMETER_UNITS: mΒ² ...
30 /// ... - Units : m/s - ...
31 /// ... PARAMETER_UNITS : m/s ...
31 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")};
32 const auto UNIT_REGEX = QRegularExpression{QStringLiteral("\\s*PARAMETER_UNITS\\s*:\\s*(.+)")};
32
33
33 /// Converts a string date to a double date
34 /// Converts a string date to a double date
34 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
35 /// @return a double that represents the date in seconds, NaN if the string date can't be converted
35 double doubleDate(const QString &stringDate) noexcept
36 double doubleDate(const QString &stringDate) noexcept
36 {
37 {
37 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
38 // Format: yyyy-MM-ddThh:mm:ss.zzz
39 auto dateTime = QDateTime::fromString(stringDate, Qt::ISODateWithMs);
38 dateTime.setTimeSpec(Qt::UTC);
40 dateTime.setTimeSpec(Qt::UTC);
39 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
41 return dateTime.isValid() ? DateUtils::secondsSinceEpoch(dateTime)
40 : std::numeric_limits<double>::quiet_NaN();
42 : std::numeric_limits<double>::quiet_NaN();
41 }
43 }
42
44
43 /// Checks if a line is a comment line
45 /// Checks if a line is a comment line
44 bool isCommentLine(const QString &line)
46 bool isCommentLine(const QString &line)
45 {
47 {
46 return line.startsWith("#");
48 return line.startsWith("#");
47 }
49 }
48
50
49 /// @return the number of lines to be read depending on the type of value passed in parameter
51 /// @return the number of lines to be read depending on the type of value passed in parameter
50 int nbValues(AmdaResultParser::ValueType valueType) noexcept
52 int nbValues(AmdaResultParser::ValueType valueType) noexcept
51 {
53 {
52 switch (valueType) {
54 switch (valueType) {
53 case AmdaResultParser::ValueType::SCALAR:
55 case AmdaResultParser::ValueType::SCALAR:
54 return 1;
56 return 1;
55 case AmdaResultParser::ValueType::VECTOR:
57 case AmdaResultParser::ValueType::VECTOR:
56 return 3;
58 return 3;
57 case AmdaResultParser::ValueType::UNKNOWN:
59 case AmdaResultParser::ValueType::UNKNOWN:
58 // Invalid case
60 // Invalid case
59 break;
61 break;
60 }
62 }
61
63
62 // Invalid cases
64 // Invalid cases
63 qCCritical(LOG_AmdaResultParser())
65 qCCritical(LOG_AmdaResultParser())
64 << QObject::tr("Can't get the number of values to read: unsupported type");
66 << QObject::tr("Can't get the number of values to read: unsupported type");
65 return 0;
67 return 0;
66 }
68 }
67
69
68 /**
70 /**
69 * Reads stream to retrieve x-axis unit
71 * Reads stream to retrieve x-axis unit
70 * @param stream the stream to read
72 * @param stream the stream to read
71 * @return the unit that has been read in the stream, a default unit (time unit with no label) if an
73 * @return the unit that has been read in the stream, a default unit (time unit with no label) if an
72 * error occured during reading
74 * error occured during reading
73 */
75 */
74 Unit readXAxisUnit(QTextStream &stream)
76 Unit readXAxisUnit(QTextStream &stream)
75 {
77 {
76 QString line{};
78 QString line{};
77
79
78 // Searches unit in the comment lines
80 // Searches unit in the comment lines (as long as the reading has not reached the data header)
79 while (stream.readLineInto(&line) && isCommentLine(line)) {
81 while (stream.readLineInto(&line) && !line.contains(DATA_HEADER_REGEX)) {
80 auto match = UNIT_REGEX.match(line);
82 auto match = UNIT_REGEX.match(line);
81 if (match.hasMatch()) {
83 if (match.hasMatch()) {
82 return Unit{match.captured(1), true};
84 return Unit{match.captured(1), true};
83 }
85 }
84 }
86 }
85
87
86 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
88 qCWarning(LOG_AmdaResultParser()) << QObject::tr("The unit could not be found in the file");
87
89
88 // Error cases
90 // Error cases
89 return Unit{{}, true};
91 return Unit{{}, true};
90 }
92 }
91
93
92 /**
94 /**
93 * Reads stream to retrieve results
95 * Reads stream to retrieve results
94 * @param stream the stream to read
96 * @param stream the stream to read
95 * @return the pair of vectors x-axis data/values data that has been read in the stream
97 * @return the pair of vectors x-axis data/values data that has been read in the stream
96 */
98 */
97 std::pair<std::vector<double>, std::vector<double> >
99 std::pair<std::vector<double>, std::vector<double> >
98 readResults(QTextStream &stream, AmdaResultParser::ValueType valueType)
100 readResults(QTextStream &stream, AmdaResultParser::ValueType valueType)
99 {
101 {
100 auto expectedNbValues = nbValues(valueType);
102 auto expectedNbValues = nbValues(valueType) + 1;
101
103
102 auto xData = std::vector<double>{};
104 auto xData = std::vector<double>{};
103 auto valuesData = std::vector<double>{};
105 auto valuesData = std::vector<double>{};
104
106
105 QString line{};
107 QString line{};
106
108
107 while (stream.readLineInto(&line)) {
109 // Skip comment lines
108 // Ignore comment lines
110 while (stream.readLineInto(&line) && isCommentLine(line)) {
109 if (!isCommentLine(line)) {
111 }
112
113 if (!stream.atEnd()) {
114 do {
110 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
115 auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts);
111 if (lineData.size() == expectedNbValues + 1) {
116 if (lineData.size() == expectedNbValues) {
112 // X : the data is converted from date to double (in secs)
117 // X : the data is converted from date to double (in secs)
113 auto x = doubleDate(lineData.at(0));
118 auto x = doubleDate(lineData.at(0));
114
119
115 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
120 // Adds result only if x is valid. Then, if value is invalid, it is set to NaN
116 if (!std::isnan(x)) {
121 if (!std::isnan(x)) {
117 xData.push_back(x);
122 xData.push_back(x);
118
123
119 // Values
124 // Values
120 for (auto valueIndex = 0; valueIndex < expectedNbValues; ++valueIndex) {
125 for (auto valueIndex = 1; valueIndex < expectedNbValues; ++valueIndex) {
121 auto column = valueIndex + 1;
126 auto column = valueIndex;
122
127
123 bool valueOk;
128 bool valueOk;
124 auto value = lineData.at(column).toDouble(&valueOk);
129 auto value = lineData.at(column).toDouble(&valueOk);
125
130
126 if (!valueOk) {
131 if (!valueOk) {
127 qCWarning(LOG_AmdaResultParser())
132 qCWarning(LOG_AmdaResultParser())
128 << QObject::tr(
133 << QObject::tr(
129 "Value from (line %1, column %2) is invalid and will be "
134 "Value from (line %1, column %2) is invalid and will be "
130 "converted to NaN")
135 "converted to NaN")
131 .arg(line, column);
136 .arg(line, column);
132 value = std::numeric_limits<double>::quiet_NaN();
137 value = std::numeric_limits<double>::quiet_NaN();
133 }
138 }
134 valuesData.push_back(value);
139 valuesData.push_back(value);
135 }
140 }
136 }
141 }
137 else {
142 else {
138 qCWarning(LOG_AmdaResultParser())
143 qCWarning(LOG_AmdaResultParser())
139 << QObject::tr("Can't retrieve results from line %1: x is invalid")
144 << QObject::tr("Can't retrieve results from line %1: x is invalid")
140 .arg(line);
145 .arg(line);
141 }
146 }
142 }
147 }
143 else {
148 else {
144 qCWarning(LOG_AmdaResultParser())
149 qCWarning(LOG_AmdaResultParser())
145 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
150 << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line);
146 }
151 }
147 }
152 } while (stream.readLineInto(&line));
148 }
153 }
149
154
150 return std::make_pair(std::move(xData), std::move(valuesData));
155 return std::make_pair(std::move(xData), std::move(valuesData));
151 }
156 }
152
157
153 } // namespace
158 } // namespace
154
159
155 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
160 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
156 ValueType valueType) noexcept
161 ValueType valueType) noexcept
157 {
162 {
158 if (valueType == ValueType::UNKNOWN) {
163 if (valueType == ValueType::UNKNOWN) {
159 qCCritical(LOG_AmdaResultParser())
164 qCCritical(LOG_AmdaResultParser())
160 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
165 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
161 return nullptr;
166 return nullptr;
162 }
167 }
163
168
164 QFile file{filePath};
169 QFile file{filePath};
165
170
166 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
171 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
167 qCCritical(LOG_AmdaResultParser())
172 qCCritical(LOG_AmdaResultParser())
168 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
173 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
169 .arg(filePath, file.errorString());
174 .arg(filePath, file.errorString());
170 return nullptr;
175 return nullptr;
171 }
176 }
172
177
173 QTextStream stream{&file};
178 QTextStream stream{&file};
174
179
175 // Checks if the file was found on the server
180 // Checks if the file was found on the server
176 auto firstLine = stream.readLine();
181 auto firstLine = stream.readLine();
177 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
182 if (firstLine.compare(FILE_NOT_FOUND_MESSAGE) == 0) {
178 qCCritical(LOG_AmdaResultParser())
183 qCCritical(LOG_AmdaResultParser())
179 << QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
184 << QObject::tr("Can't retrieve AMDA data from file %1: file was not found on server")
180 .arg(filePath);
185 .arg(filePath);
181 return nullptr;
186 return nullptr;
182 }
187 }
183
188
184 // Reads x-axis unit
189 // Reads x-axis unit
185 stream.seek(0); // returns to the beginning of the file
190 stream.seek(0); // returns to the beginning of the file
186 auto xAxisUnit = readXAxisUnit(stream);
191 auto xAxisUnit = readXAxisUnit(stream);
187
192
188 // Reads results
193 // Reads results
189 stream.seek(0); // returns to the beginning of the file
190 auto results = readResults(stream, valueType);
194 auto results = readResults(stream, valueType);
191
195
192 // Creates data series
196 // Creates data series
193 switch (valueType) {
197 switch (valueType) {
194 case ValueType::SCALAR:
198 case ValueType::SCALAR:
195 return std::make_shared<ScalarSeries>(std::move(results.first),
199 return std::make_shared<ScalarSeries>(std::move(results.first),
196 std::move(results.second), xAxisUnit, Unit{});
200 std::move(results.second), xAxisUnit, Unit{});
197 case ValueType::VECTOR:
201 case ValueType::VECTOR:
198 return std::make_shared<VectorSeries>(std::move(results.first),
202 return std::make_shared<VectorSeries>(std::move(results.first),
199 std::move(results.second), xAxisUnit, Unit{});
203 std::move(results.second), xAxisUnit, Unit{});
200 case ValueType::UNKNOWN:
204 case ValueType::UNKNOWN:
201 // Invalid case
205 // Invalid case
202 break;
206 break;
203 }
207 }
204
208
205 // Invalid cases
209 // Invalid cases
206 qCCritical(LOG_AmdaResultParser())
210 qCCritical(LOG_AmdaResultParser())
207 << QObject::tr("Can't create data series: unsupported value type");
211 << QObject::tr("Can't create data series: unsupported value type");
208 return nullptr;
212 return nullptr;
209 }
213 }
@@ -1,6 +1,64
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
4 2013-09-23T09:00:30.000 NaN
62 2013-09-23T09:00:30.000 NaN
5 2013-09-23T09:01:30.000 -2.71850
63 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
64 2013-09-23T09:02:30.000 -2.52150
@@ -1,6 +1,64
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
4 NaN -3.01425
62 NaN -3.01425
5 2013-09-23T09:01:30.000 -2.71850
63 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
64 2013-09-23T09:02:30.000 -2.52150
@@ -1,2 +1,60
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls No newline at end of file
2 # AMDA INFO :
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_COORDINATE_SYSTEM : GSE
43 # PARAMETER_TENSOR_ORDER : 0
44 # PARAMETER_SI_CONVERSION : 1e-9>T
45 # PARAMETER_TABLE : None
46 # PARAMETER_FILL_VALUE : nan
47 # PARAMETER_UCD : phys.magField
48 #
49 #
50 # ---------------
51 # INTERVAL INFO :
52 # ---------------
53 # INTERVAL_START : 2013-09-23T08:58:12.000
54 # INTERVAL_STOP : 2013-09-23T09:11:48.000
55 #
56 # ------
57 # DATA :
58 # ------
59 # DATA_COLUMNS : AMDA_TIME, imf[0]
60 # No newline at end of file
@@ -1,6 +1,64
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
4 2013-09-23T09:00:30.000 -2.83950 1.05141 3.01547
62 2013-09-23T09:00:30.000 -2.83950 1.05141 3.01547
5 2013-09-23T09:01:30.000 -2.71850
63 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
64 2013-09-23T09:02:30.000 -2.52150
@@ -1,13 +1,71
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
4 2013-09-23T09:00:30.000 -2.83950
62 2013-09-23T09:00:30.000 -2.83950
5 2013-09-23T09:01:30.000 -2.71850
63 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150
64 2013-09-23T09:02:30.000 -2.52150
7 2013-09-23T09:03:30.000 -2.57633
65 2013-09-23T09:03:30.000 -2.57633
8 2013-09-23T09:04:30.000 -2.58050
66 2013-09-23T09:04:30.000 -2.58050
9 2013-09-23T09:05:30.000 -2.48325
67 2013-09-23T09:05:30.000 -2.48325
10 2013-09-23T09:06:30.000 -2.63025
68 2013-09-23T09:06:30.000 -2.63025
11 2013-09-23T09:07:30.000 -2.55800
69 2013-09-23T09:07:30.000 -2.55800
12 2013-09-23T09:08:30.000 -2.43250
70 2013-09-23T09:08:30.000 -2.43250
13 2013-09-23T09:09:30.000 -2.42200 No newline at end of file
71 2013-09-23T09:09:30.000 -2.42200
@@ -1,12 +1,71
1 #Time Format : YYYY-MM-DDThh:mm:ss.mls
1 # -----------
2 #imf - Type : Local Parameter @ CDPP/AMDA - Name : imf_gse - Units : nT - Size : 3 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
2 # AMDA INFO :
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2012-09-27T06:47:56.000
55 # INTERVAL_STOP : 2012-09-27T08:09:32.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0], imf[1], imf[2]
61 #
3 2013-07-02T09:13:50.000 -0.332000 3.20600 0.0580000
62 2013-07-02T09:13:50.000 -0.332000 3.20600 0.0580000
4 2013-07-02T09:14:06.000 -1.01100 2.99900 0.496000
63 2013-07-02T09:14:06.000 -1.01100 2.99900 0.496000
5 2013-07-02T09:14:22.000 -1.45700 2.78500 1.01800
64 2013-07-02T09:14:22.000 -1.45700 2.78500 1.01800
6 2013-07-02T09:14:38.000 -1.29300 2.73600 1.48500
65 2013-07-02T09:14:38.000 -1.29300 2.73600 1.48500
7 2013-07-02T09:14:54.000 -1.21700 2.61200 1.66200
66 2013-07-02T09:14:54.000 -1.21700 2.61200 1.66200
8 2013-07-02T09:15:10.000 -1.44300 2.56400 1.50500
67 2013-07-02T09:15:10.000 -1.44300 2.56400 1.50500
9 2013-07-02T09:15:26.000 -1.27800 2.89200 1.16800
68 2013-07-02T09:15:26.000 -1.27800 2.89200 1.16800
10 2013-07-02T09:15:42.000 -1.20200 2.86200 1.24400
69 2013-07-02T09:15:42.000 -1.20200 2.86200 1.24400
11 2013-07-02T09:15:58.000 -1.22000 2.85900 1.15000
70 2013-07-02T09:15:58.000 -1.22000 2.85900 1.15000
12 2013-07-02T09:16:14.000 -1.25900 2.76400 1.35800 No newline at end of file
71 2013-07-02T09:16:14.000 -1.25900 2.76400 1.35800
@@ -1,6 +1,64
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
4 23/09/2013 07:50:30 -2.83950
62 23/09/2013 07:50:30 -2.83950
5 2013-09-23T09:01:30.000 -2.71850
63 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
64 2013-09-23T09:02:30.000 -2.52150
@@ -1,6 +1,64
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
3 #Wrong unit comment
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAM_UNITS : wrong unit line
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
4 2013-09-23T09:00:30.000 -2.83950
62 2013-09-23T09:00:30.000 -2.83950
5 2013-09-23T09:01:30.000 -2.71850
63 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
64 2013-09-23T09:02:30.000 -2.52150
@@ -1,6 +1,64
1 #Sampling Time : 60
1 # -----------
2 #Time Format : YYYY-MM-DDThh:mm:ss.mls
2 # AMDA INFO :
3 #imf(0) - Type : Local Parameter @ CDPP/AMDA - Name : bx_gse - Units : nT - Size : 1 - Frame : GSE - Mission : ACE - Instrument : MFI - Dataset : mfi_final-prelim
3 # -----------
4 # AMDA_ABOUT : Created by CDPP/AMDA(c)
5 # AMDA_VERSION : 3.5.0
6 # AMDA_ACKNOWLEDGEMENT : CDPP/AMDA Team
7 #
8 # --------------
9 # REQUEST INFO :
10 # --------------
11 # REQUEST_STRUCTURE : one-file-per-parameter-per-interval
12 # REQUEST_TIME_FORMAT : ISO 8601
13 # REQUEST_OUTPUT_PARAMS : imf
14 #
15 # -----------------
16 # BASE PARAMETERS :
17 # -----------------
18 #
19 # MISSION_ID : NONE
20 #
21 # INSTRUMENT_ID : NONE
22 #
23 # DATASET_ID : ace-imf-all
24 # DATASET_NAME : final / prelim
25 # DATASET_DESCRIPTION : Interplanetary Magnetic Field 16-sec Level2/PRELIM Data
26 # DATASET_SOURCE : CDPP/DDServer
27 # DATASET_GLOBAL_START : 1997-09-02T00:00:12.000
28 # DATASET_GLOBAL_STOP : 2017-09-16T23:59:57.000
29 # DATASET_MIN_SAMPLING : 16
30 # DATASET_MAX_SAMPLING : 16
31 # DATASET_CAVEATS :
32 The quality of ACE level 2 data is such that it is suitable for serious scientific study. However, to avoid confusion and misunderstanding, it is recommended that users consult with the appropriate ACE team members before publishing work derived from the data. The ACE team has worked hard to ensure that the level 2 data are free from errors, but the team cannot accept responsibility for erroneous data, or for misunderstandings about how the data may be used. This is especially true if the appropriate ACE team members are not consulted before publication. At the very least, preprints should be forwarded to the ACE team before publication.
33
34 # DATASET_ACKNOWLEDGEMENT :
35 Please acknowledge the ACE/MAG instrument team and the ACE Science Center
36
37 #
38 # PARAMETER_ID : imf
39 # PARAMETER_NAME : imf
40 # PARAMETER_SHORT_NAME : b_gse
41 # PARAMETER_COMPONENTS : bx,by,bz
42 # PARAMETER_UNITS : nT
43 # PARAMETER_COORDINATE_SYSTEM : GSE
44 # PARAMETER_TENSOR_ORDER : 0
45 # PARAMETER_SI_CONVERSION : 1e-9>T
46 # PARAMETER_TABLE : None
47 # PARAMETER_FILL_VALUE : nan
48 # PARAMETER_UCD : phys.magField
49 #
50 #
51 # ---------------
52 # INTERVAL INFO :
53 # ---------------
54 # INTERVAL_START : 2013-09-23T08:58:12.000
55 # INTERVAL_STOP : 2013-09-23T09:11:48.000
56 #
57 # ------
58 # DATA :
59 # ------
60 # DATA_COLUMNS : AMDA_TIME, imf[0]
61 #
4 2013-09-23T09:00:30.000 abc
62 2013-09-23T09:00:30.000 abc
5 2013-09-23T09:01:30.000 -2.71850
63 2013-09-23T09:01:30.000 -2.71850
6 2013-09-23T09:02:30.000 -2.52150 No newline at end of file
64 2013-09-23T09:02:30.000 -2.52150
@@ -1,195 +1,197
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaResultParser.h"
2 #include "AmdaResultParser.h"
3
3
4 #include "SqpApplication.h"
4 #include "SqpApplication.h"
5 #include <Data/DataSeries.h>
5 #include <Data/DataSeries.h>
6 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
7 #include <Data/ScalarSeries.h>
7 #include <Data/ScalarSeries.h>
8 #include <Time/TimeController.h>
8 #include <Time/TimeController.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <QObject>
12 #include <QObject>
13 #include <QtTest>
13 #include <QtTest>
14
14
15 #include <memory>
15 #include <memory>
16
16
17 // TEST with REF:
17 // TEST with REF:
18 // AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00
18 // AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00
19 // imf(0) - Type : Local Parameter @ CDPP/AMDA -
19 // imf(0) - Type : Local Parameter @ CDPP/AMDA -
20 // Name : bx_gse - Units : nT - Size : 1 -
20 // Name : bx_gse - Units : nT - Size : 1 -
21 // Frame : GSE - Mission : ACE -
21 // Frame : GSE - Mission : ACE -
22 // Instrument : MFI - Dataset : mfi_final-prelim
22 // Instrument : MFI - Dataset : mfi_final-prelim
23 // REFERENCE DOWNLOAD FILE =
23 // REFERENCE DOWNLOAD FILE =
24 // http://amda.irap.omp.eu/php/rest/getParameter.php?startTime=2012-01-01T12:00:00&stopTime=2012-01-03T12:00:00&parameterID=imf(0)&outputFormat=ASCII&timeFormat=ISO8601&gzip=0
24 // http://amda.irap.omp.eu/php/rest/getParameter.php?startTime=2012-01-01T12:00:00&stopTime=2012-01-03T12:00:00&parameterID=imf(0)&outputFormat=ASCII&timeFormat=ISO8601&gzip=0
25
25
26 namespace {
26 namespace {
27
27
28 /// Path for the tests
28 /// Path for the tests
29 const auto TESTS_RESOURCES_PATH
29 const auto TESTS_RESOURCES_PATH
30 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaAcquisition"}.absoluteFilePath();
30 = QFileInfo{QString{AMDA_TESTS_RESOURCES_DIR}, "TestAmdaAcquisition"}.absoluteFilePath();
31
31
32 const auto TESTS_AMDA_REF_FILE = QString{"AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00.txt"};
32 const auto TESTS_AMDA_REF_FILE = QString{"AmdaData-2012-01-01-12-00-00_2012-01-03-12-00-00.txt"};
33
33
34 template <typename T>
34 template <typename T>
35 bool compareDataSeries(std::shared_ptr<IDataSeries> candidate, SqpRange candidateCacheRange,
35 bool compareDataSeries(std::shared_ptr<IDataSeries> candidate, SqpRange candidateCacheRange,
36 std::shared_ptr<IDataSeries> reference)
36 std::shared_ptr<IDataSeries> reference)
37 {
37 {
38 auto compareLambda = [](const auto &it1, const auto &it2) {
38 auto compareLambda = [](const auto &it1, const auto &it2) {
39 return (it1.x() == it2.x()) && (it1.value() == it2.value());
39 return (it1.x() == it2.x()) && (it1.value() == it2.value());
40 };
40 };
41
41
42 auto candidateDS = std::dynamic_pointer_cast<T>(candidate);
42 auto candidateDS = std::dynamic_pointer_cast<T>(candidate);
43 auto referenceDS = std::dynamic_pointer_cast<T>(reference);
43 auto referenceDS = std::dynamic_pointer_cast<T>(reference);
44
44
45 if (candidateDS && referenceDS) {
45 if (candidateDS && referenceDS) {
46
46
47 auto itRefs
47 auto itRefs
48 = referenceDS->xAxisRange(candidateCacheRange.m_TStart, candidateCacheRange.m_TEnd);
48 = referenceDS->xAxisRange(candidateCacheRange.m_TStart, candidateCacheRange.m_TEnd);
49 qDebug() << " DISTANCE" << std::distance(candidateDS->cbegin(), candidateDS->cend())
49 qDebug() << " DISTANCE" << std::distance(candidateDS->cbegin(), candidateDS->cend())
50 << std::distance(itRefs.first, itRefs.second);
50 << std::distance(itRefs.first, itRefs.second);
51
51
52 // auto xcValue = candidateDS->valuesData()->data();
52 // auto xcValue = candidateDS->valuesData()->data();
53 // auto dist = std::distance(itRefs.first, itRefs.second);
53 // auto dist = std::distance(itRefs.first, itRefs.second);
54 // auto it = itRefs.first;
54 // auto it = itRefs.first;
55 // for (auto i = 0; i < dist - 1; ++i) {
55 // for (auto i = 0; i < dist - 1; ++i) {
56 // ++it;
56 // ++it;
57 // qInfo() << "END:" << it->value();
57 // qInfo() << "END:" << it->value();
58 // }
58 // }
59 // qDebug() << "END:" << it->value() << xcValue.last();
59 // qDebug() << "END:" << it->value() << xcValue.last();
60
60
61 return std::equal(candidateDS->cbegin(), candidateDS->cend(), itRefs.first, itRefs.second,
61 return std::equal(candidateDS->cbegin(), candidateDS->cend(), itRefs.first, itRefs.second,
62 compareLambda);
62 compareLambda);
63 }
63 }
64 else {
64 else {
65 return false;
65 return false;
66 }
66 }
67 }
67 }
68 }
68 }
69
69
70 class TestAmdaAcquisition : public QObject {
70 class TestAmdaAcquisition : public QObject {
71 Q_OBJECT
71 Q_OBJECT
72
72
73 private slots:
73 private slots:
74 void testAcquisition();
74 void testAcquisition();
75 };
75 };
76
76
77 void TestAmdaAcquisition::testAcquisition()
77 void TestAmdaAcquisition::testAcquisition()
78 {
78 {
79 /// @todo: update test to be compatible with AMDA v2
80
79 // READ the ref file:
81 // READ the ref file:
80 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, TESTS_AMDA_REF_FILE}.absoluteFilePath();
82 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, TESTS_AMDA_REF_FILE}.absoluteFilePath();
81 auto results = AmdaResultParser::readTxt(filePath, AmdaResultParser::ValueType::SCALAR);
83 auto results = AmdaResultParser::readTxt(filePath, AmdaResultParser::ValueType::SCALAR);
82
84
83 auto provider = std::make_shared<AmdaProvider>();
85 auto provider = std::make_shared<AmdaProvider>();
84 auto timeController = std::make_unique<TimeController>();
86 auto timeController = std::make_unique<TimeController>();
85
87
86 auto varRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 3, 0, 0}};
88 auto varRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 3, 0, 0}};
87 auto varRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
89 auto varRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
88
90
89 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
91 auto sqpR = SqpRange{DateUtils::secondsSinceEpoch(varRS), DateUtils::secondsSinceEpoch(varRE)};
90
92
91 timeController->onTimeToUpdate(sqpR);
93 timeController->onTimeToUpdate(sqpR);
92
94
93 QVariantHash metaData;
95 QVariantHash metaData;
94 metaData.insert("dataType", "scalar");
96 metaData.insert("dataType", "scalar");
95 metaData.insert("xml:id", "imf(0)");
97 metaData.insert("xml:id", "imf(0)");
96
98
97 VariableController vc;
99 VariableController vc;
98 vc.setTimeController(timeController.get());
100 vc.setTimeController(timeController.get());
99
101
100 auto var = vc.createVariable("bx_gse", metaData, provider);
102 auto var = vc.createVariable("bx_gse", metaData, provider);
101
103
102 // 1 : Variable creation
104 // 1 : Variable creation
103
105
104 qDebug() << " 1: TIMECONTROLLER" << timeController->dateTime();
106 qDebug() << " 1: TIMECONTROLLER" << timeController->dateTime();
105 qDebug() << " 1: RANGE " << var->range();
107 qDebug() << " 1: RANGE " << var->range();
106 qDebug() << " 1: CACHERANGE" << var->cacheRange();
108 qDebug() << " 1: CACHERANGE" << var->cacheRange();
107
109
108 // wait for 10 sec before asking next request toi permit asynchrone process to finish.
110 // wait for 10 sec before asking next request toi permit asynchrone process to finish.
109 auto timeToWaitMs = 10000;
111 auto timeToWaitMs = 10000;
110
112
111 QEventLoop loop;
113 QEventLoop loop;
112 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
114 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
113 loop.exec();
115 loop.exec();
114
116
115 // Tests on acquisition operation
117 // Tests on acquisition operation
116
118
117 int count = 1;
119 int count = 1;
118
120
119 auto requestDataLoading = [&vc, var, timeToWaitMs, results, &count](auto tStart, auto tEnd) {
121 auto requestDataLoading = [&vc, var, timeToWaitMs, results, &count](auto tStart, auto tEnd) {
120 ++count;
122 ++count;
121
123
122 auto nextSqpR
124 auto nextSqpR
123 = SqpRange{DateUtils::secondsSinceEpoch(tStart), DateUtils::secondsSinceEpoch(tEnd)};
125 = SqpRange{DateUtils::secondsSinceEpoch(tStart), DateUtils::secondsSinceEpoch(tEnd)};
124 vc.onRequestDataLoading(QVector<std::shared_ptr<Variable> >{} << var, nextSqpR,
126 vc.onRequestDataLoading(QVector<std::shared_ptr<Variable> >{} << var, nextSqpR,
125 var->range(), true);
127 var->range(), true);
126
128
127 QEventLoop loop;
129 QEventLoop loop;
128 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
130 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
129 loop.exec();
131 loop.exec();
130
132
131 qInfo() << count << "RANGE " << var->range();
133 qInfo() << count << "RANGE " << var->range();
132 qInfo() << count << "CACHERANGE" << var->cacheRange();
134 qInfo() << count << "CACHERANGE" << var->cacheRange();
133
135
134 QCOMPARE(var->range().m_TStart, nextSqpR.m_TStart);
136 QCOMPARE(var->range().m_TStart, nextSqpR.m_TStart);
135 QCOMPARE(var->range().m_TEnd, nextSqpR.m_TEnd);
137 QCOMPARE(var->range().m_TEnd, nextSqpR.m_TEnd);
136
138
137 // Verify dataserie
139 // Verify dataserie
138 QVERIFY(compareDataSeries<ScalarSeries>(var->dataSeries(), var->cacheRange(), results));
140 QVERIFY(compareDataSeries<ScalarSeries>(var->dataSeries(), var->cacheRange(), results));
139
141
140 };
142 };
141
143
142 // 2 : pan (jump) left for one hour
144 // 2 : pan (jump) left for one hour
143 auto nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 1, 0, 0}};
145 auto nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 1, 0, 0}};
144 auto nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 2, 0, 0}};
146 auto nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 2, 0, 0}};
145 requestDataLoading(nextVarRS, nextVarRE);
147 // requestDataLoading(nextVarRS, nextVarRE);
146
148
147
149
148 // 3 : pan (jump) right for one hour
150 // 3 : pan (jump) right for one hour
149 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
151 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
150 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
152 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
151 requestDataLoading(nextVarRS, nextVarRE);
153 // requestDataLoading(nextVarRS, nextVarRE);
152
154
153 // 4 : pan (overlay) right for 30 min
155 // 4 : pan (overlay) right for 30 min
154 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
156 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
155 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 30, 0}};
157 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 30, 0}};
156 // requestDataLoading(nextVarRS, nextVarRE);
158 // requestDataLoading(nextVarRS, nextVarRE);
157
159
158 // 5 : pan (overlay) left for 30 min
160 // 5 : pan (overlay) left for 30 min
159 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
161 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 0, 0}};
160 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
162 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
161 // requestDataLoading(nextVarRS, nextVarRE);
163 // requestDataLoading(nextVarRS, nextVarRE);
162
164
163 // 6 : pan (overlay) left for 30 min - BIS
165 // 6 : pan (overlay) left for 30 min - BIS
164 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 30, 0}};
166 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 30, 0}};
165 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
167 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 30, 0}};
166 // requestDataLoading(nextVarRS, nextVarRE);
168 // requestDataLoading(nextVarRS, nextVarRE);
167
169
168 // 7 : Zoom in Inside 20 min range
170 // 7 : Zoom in Inside 20 min range
169 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 50, 0}};
171 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 50, 0}};
170 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 10, 0}};
172 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 5, 10, 0}};
171 // requestDataLoading(nextVarRS, nextVarRE);
173 // requestDataLoading(nextVarRS, nextVarRE);
172
174
173 // 8 : Zoom out Inside 2 hours range
175 // 8 : Zoom out Inside 2 hours range
174 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
176 nextVarRS = QDateTime{QDate{2012, 01, 02}, QTime{2, 4, 0, 0}};
175 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
177 nextVarRE = QDateTime{QDate{2012, 01, 02}, QTime{2, 6, 0, 0}};
176 // requestDataLoading(nextVarRS, nextVarRE);
178 // requestDataLoading(nextVarRS, nextVarRE);
177
179
178
180
179 // Close the app after 10 sec
181 // Close the app after 10 sec
180 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
182 QTimer::singleShot(timeToWaitMs, &loop, &QEventLoop::quit);
181 loop.exec();
183 loop.exec();
182 }
184 }
183
185
184 int main(int argc, char *argv[])
186 int main(int argc, char *argv[])
185 {
187 {
186 SqpApplication app(argc, argv);
188 SqpApplication app(argc, argv);
187 app.setAttribute(Qt::AA_Use96Dpi, true);
189 app.setAttribute(Qt::AA_Use96Dpi, true);
188 TestAmdaAcquisition tc;
190 TestAmdaAcquisition tc;
189 QTEST_SET_MAIN_SOURCE_PATH
191 QTEST_SET_MAIN_SOURCE_PATH
190 return QTest::qExec(&tc, argc, argv);
192 return QTest::qExec(&tc, argc, argv);
191 }
193 }
192
194
193 // QTEST_MAIN(TestAmdaAcquisition)
195 // QTEST_MAIN(TestAmdaAcquisition)
194
196
195 #include "TestAmdaAcquisition.moc"
197 #include "TestAmdaAcquisition.moc"
General Comments 0
You need to be logged in to leave comments. Login now