Isis 3 Programmer Reference
SerialNumberList.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "SerialNumberList.h"
8
9#include <QString>
10
11#include "IException.h"
12#include "FileList.h"
13#include "FileName.h"
14#include "ObservationNumber.h"
15#include "Progress.h"
16#include "Pvl.h"
17#include "SerialNumber.h"
18
19namespace Isis {
27 m_checkTarget = checkTarget;
28 m_target.clear();
29 }
30
31
46 SerialNumberList::SerialNumberList(const QString &listfile,
47 bool checkTarget,
48 Progress *progress) {
49 m_checkTarget = checkTarget;
50 m_target.clear();
51
52 try {
53 FileList flist(listfile);
54 if (progress != NULL) {
55 progress->SetText("Creating Isis serial numbers from list file.");
56 progress->SetMaximumSteps((int) flist.size() + 1);
57 progress->CheckStatus();
58 }
59 for (int i = 0; i < flist.size(); i++) {
60 add(flist[i].toString());
61 if (progress != NULL) {
62 progress->CheckStatus();
63 }
64 }
65 }
66 catch (IException &e) {
67 QString msg = "Can't open or invalid file list [" + listfile + "].";
68 throw IException(e, IException::User, msg, _FILEINFO_);
69 }
70
71 }
72
73
79
80
88 void SerialNumberList::remove(const QString &sn) {
89 int index = serialNumberIndex(sn);
90 QString sFileName = fileName(sn);
91
92 // Delete the reference to this serial number in the vector and the maps
93 m_pairs.erase(m_pairs.begin() + index);
94 m_serialMap.erase(sn);
95 m_fileMap.erase(sFileName);
96 }
97
98
121 void SerialNumberList::add(const QString &filename, bool def2filename) {
122 Pvl p(Isis::FileName(filename).expanded());
123 PvlObject cubeObj = p.findObject("IsisCube");
124
125 try {
126
127 // Test the target name if desired
128 if (m_checkTarget) {
129 QString target;
130 PvlGroup targetGroup;
131 if (cubeObj.hasGroup("Instrument")) {
132 targetGroup = cubeObj.findGroup("Instrument");
133 }
134 else if (def2filename) {
135 // No instrument, try Mapping
136 if (cubeObj.hasGroup("Mapping")) {
137 targetGroup = cubeObj.findGroup("Mapping");
138 }
139 else {
140 QString msg = "Unable to find Instrument or Mapping group in "
141 + filename + " for comparing target.";
142 throw IException(IException::User, msg, _FILEINFO_);
143 }
144 }
145 else {
146 // No Instrument group
147 QString msg = "Unable to find Instrument group in " + filename
148 + " for comparing target.";
149 throw IException(IException::User, msg, _FILEINFO_);
150 }
151
152 target = targetGroup["TargetName"][0];
153 target = target.toUpper();
154 if (m_target.isEmpty()) {
155 m_target = target;
156 }
157 else if (m_target != target) {
158 QString msg = "Target name of [" + target + "] from file ["
159 + filename + "] does not match [" + m_target + "].";
160 throw IException(IException::User, msg, _FILEINFO_);
161 }
162 }
163
164 // Create the SN
165 QString sn = SerialNumber::Compose(p, def2filename);
166 QString on = ObservationNumber::Compose(p, def2filename);
167 if (sn == "Unknown") {
168 QString msg = "Invalid serial number [Unknown] from file ["
169 + filename + "].";
170 throw IException(IException::User, msg, _FILEINFO_);
171 }
172 else if (hasSerialNumber(sn)) {
173 int index = serialNumberIndex(sn);
174 QString msg = "Duplicate serial number [" + sn + "] from files ["
175 + SerialNumberList::fileName(sn) + "] and [" + fileName(index) + "].";
176 throw IException(IException::User, msg, _FILEINFO_);
177 }
178
179 Pair nextpair;
180 nextpair.filename = Isis::FileName(filename).expanded();
181 nextpair.serialNumber = sn;
182 nextpair.observationNumber = on;
183
184 // If a CSM cube, obtain the CSMPlatformID and CSMInstrumentId from the CsmInfo
185 // group for use in bundle adjustment
186 if (cubeObj.hasGroup("CsmInfo")) {
187 PvlGroup csmGroup = cubeObj.findGroup("CsmInfo");
188 if (csmGroup.hasKeyword("CSMPlatformID") && csmGroup.hasKeyword("CSMInstrumentId")) {
189 nextpair.spacecraftName = cubeObj.findGroup("CsmInfo")["CSMPlatformID"][0];
190 nextpair.instrumentId = cubeObj.findGroup("CsmInfo")["CSMInstrumentId"][0];
191 }
192 }
193
194 // Otherwise obtain the SpacecraftName and InstrumentId from the Instrument
195 // group for use in bundle adjustment
196 else if (cubeObj.hasGroup("Instrument")) {
197 PvlGroup instGroup = cubeObj.findGroup("Instrument");
198 if (instGroup.hasKeyword("SpacecraftName") && instGroup.hasKeyword("InstrumentId")) {
199 nextpair.spacecraftName = cubeObj.findGroup("Instrument")["SpacecraftName"][0];
200 nextpair.instrumentId = cubeObj.findGroup("Instrument")["InstrumentId"][0];
201 }
202 }
203
204 m_pairs.push_back(nextpair);
205 m_serialMap.insert(std::pair<QString, int>(sn, (int)(m_pairs.size() - 1)));
206 m_fileMap.insert(std::pair<QString, int>(nextpair.filename, (int)(m_pairs.size() - 1)));
207 }
208 catch (IException &e) {
209 QString msg = "FileName [" + Isis::FileName(filename).expanded() +
210 "] can not be added to serial number list.";
211 throw IException(e, IException::User, msg, _FILEINFO_);
212 }
213
214 }
215
216
227 void SerialNumberList::add(const char *serialNumber, const char *filename) {
228 add((QString)serialNumber, (QString)filename);
229 }
230
231
251 void SerialNumberList::add(const QString &serialNumber, const QString &filename) {
252 Pvl p(Isis::FileName(filename).expanded());
253 PvlObject cubeObj = p.findObject("IsisCube");
254
255 try {
256
257 // Test the target name if desired
258 if (m_checkTarget) {
259 QString target;
260 PvlGroup targetGroup;
261 if (cubeObj.hasGroup("Instrument")) {
262 targetGroup = cubeObj.findGroup("Instrument");
263 }
264 else if (cubeObj.hasGroup("Mapping")) {
265 // No instrument, try Mapping
266 targetGroup = cubeObj.findGroup("Mapping");
267 }
268 else {
269 QString msg = "Unable to find Instrument or Mapping group in "
270 + filename + " for comparing target.";
271 throw IException(IException::User, msg, _FILEINFO_);
272 }
273
274 target = targetGroup["TargetName"][0];
275 target = target.toUpper();
276 if (m_target.isEmpty()) {
277 m_target = target;
278 }
279 else if (m_target != target) {
280 QString msg = "Target name of [" + target + "] from file ["
281 + filename + "] does not match [" + m_target + "].";
282 throw IException(IException::User, msg, _FILEINFO_);
283 }
284 }
285
286 QString observationNumber = "Unknown";
287 if (serialNumber == "Unknown") {
288 QString msg = "Invalid serial number [Unknown] from file ["
289 + filename + "].";
290 throw IException(IException::User, msg, _FILEINFO_);
291 }
292 else if (hasSerialNumber(serialNumber)) {
293 int index = serialNumberIndex(serialNumber);
294 QString msg = "Duplicate, serial number [" + serialNumber + "] from files ["
296 + "] and [" + fileName(index) + "].";
297 throw IException(IException::User, msg, _FILEINFO_);
298 }
299
300 // Check if it is not a CSM label before checking SpacecraftName and InstrumentId
301 if (!cubeObj.hasGroup("CsmInfo")) {
302
303 // Need to obtain the SpacecraftName and InstrumentId from the Instrument
304 // group for use in bundle adjustment
305 if (!cubeObj.hasGroup("Instrument")) {
306 QString msg = "Unable to find Instrument group in " + filename
307 + " needed for performing bundle adjustment.";
308 throw IException(IException::User, msg, _FILEINFO_);
309 }
310 PvlGroup instGroup = cubeObj.findGroup("Instrument");
311 if (!instGroup.hasKeyword("SpacecraftName") || !instGroup.hasKeyword("InstrumentId")) {
312 QString msg = "Unable to find SpacecraftName or InstrumentId keywords in " + filename
313 + " needed for performing bundle adjustment.";
314 throw IException(IException::User, msg, _FILEINFO_);
315 }
316 }
317 // Check if CSM label has CSMPlatformID and CSMInstrumentId
318 else {
319 PvlGroup csmGroup = cubeObj.findGroup("CSMInfo");
320 if (!csmGroup.hasKeyword("CSMPlatformID") || !csmGroup.hasKeyword("CSMInstrumentId")) {
321 QString msg = "Unable to find CSMPlatformID or CSMInstrumentId keywords in " + filename
322 + " needed for performing bundle adjustment.";
323 throw IException(IException::User, msg, _FILEINFO_);
324 }
325 }
326
327 Pair nextpair;
328 nextpair.filename = Isis::FileName(filename).expanded();
329 nextpair.serialNumber = serialNumber;
330 nextpair.observationNumber = observationNumber;
331
332 // If a CSM cube, obtain the CSMPlatformID and CSMInstrumentId from the CsmInfo
333 // group for use in bundle adjustment
334 if (cubeObj.hasGroup("CsmInfo")) {
335 PvlGroup csmGroup = cubeObj.findGroup("CsmInfo");
336 if (csmGroup.hasKeyword("CSMPlatformID") && csmGroup.hasKeyword("CSMInstrumentId")) {
337 nextpair.spacecraftName = cubeObj.findGroup("CsmInfo")["CSMPlatformID"][0];
338 nextpair.instrumentId = cubeObj.findGroup("CsmInfo")["CSMInstrumentId"][0];
339 }
340 }
341
342 // Otherwise obtain the SpacecraftName and InstrumentId from the Instrument
343 // group for use in bundle adjustment
344 else if (cubeObj.hasGroup("Instrument")) {
345 PvlGroup instGroup = cubeObj.findGroup("Instrument");
346 if (instGroup.hasKeyword("SpacecraftName") && instGroup.hasKeyword("InstrumentId")) {
347 nextpair.spacecraftName = cubeObj.findGroup("Instrument")["SpacecraftName"][0];
348 nextpair.instrumentId = cubeObj.findGroup("Instrument")["InstrumentId"][0];
349 }
350 }
351
352 m_pairs.push_back(nextpair);
353 m_serialMap.insert(std::pair<QString, int>(serialNumber, (int)(m_pairs.size() - 1)));
354 m_fileMap.insert(std::pair<QString, int>(nextpair.filename, (int)(m_pairs.size() - 1)));
355 }
356 catch (IException &e) {
357 QString msg = "[SerialNumber, FileName] = [" + serialNumber + ", "
358 + Isis::FileName(filename).expanded()
359 + "] can not be added to serial number list.";
360 throw IException(e, IException::User, msg, _FILEINFO_);
361 }
362
363 }
364
365
374 if (m_serialMap.find(sn) == m_serialMap.end()) return false;
375 return true;
376 }
377
378
385 return m_pairs.size();
386 }
387
388
399 QString SerialNumberList::fileName(const QString &sn) {
400 if (hasSerialNumber(sn)) {
401 int index = m_serialMap.find(sn)->second;
402 return m_pairs[index].filename;
403 }
404 else {
405 QString msg = "Unable to get the FileName. The given serial number ["
406 + sn + "] does not exist in the list.";
407 throw IException(IException::Programmer, msg, _FILEINFO_);
408 }
409 }
410
411
426 QString SerialNumberList::serialNumber(const QString &filename) {
427 if (m_fileMap.find(Isis::FileName(filename).expanded()) == m_fileMap.end()) {
428 QString msg = "Unable to get the SerialNumber. The given file name ["
429 + Isis::FileName(filename).expanded() + "] does not exist in the list.";
430 throw IException(IException::Programmer, msg, _FILEINFO_);
431 }
432 int index = fileNameIndex(filename);
433 return m_pairs[index].serialNumber;
434 }
435
436
447 if (index >= 0 && index < (int) m_pairs.size()) {
448 return m_pairs[index].serialNumber;
449 }
450 else {
451 QString msg = "Unable to get the SerialNumber. The given index ["
452 + toString(index) + "] is invalid.";
453 throw IException(IException::Programmer, msg, _FILEINFO_);
454 }
455 }
456
457
469 if (index >= 0 && index < (int) m_pairs.size()) {
470 return m_pairs[index].observationNumber;
471 }
472 else {
473 QString msg = "Unable to get the ObservationNumber. The given index ["
474 + toString(index) + "] is invalid.";
475 throw IException(IException::Programmer, msg, _FILEINFO_);
476 }
477 }
478
479
490 int SerialNumberList::serialNumberIndex(const QString &sn) {
491 if (hasSerialNumber(sn)) {
492 return m_serialMap.find(sn)->second;
493 }
494 else {
495 QString msg = "Unable to get the SerialNumber index. The given serial number ["
496 + sn + "] does not exist in the list.";
497 throw IException(IException::Programmer, msg, _FILEINFO_);
498 }
499 }
500
501
517 int SerialNumberList::fileNameIndex(const QString &filename) {
518 std::map<QString, int>::iterator pos;
519 if ((pos = m_fileMap.find(Isis::FileName(filename).expanded())) == m_fileMap.end()) {
520 QString msg = "Unable to get the FileName index. The given file name ["
521 + Isis::FileName(filename).expanded() + "] does not exist in the list.";
522 throw IException(IException::Programmer, msg, _FILEINFO_);
523 }
524 return pos->second;
525 }
526
527
537 QString SerialNumberList::fileName(int index) {
538 if (index >= 0 && index < (int) m_pairs.size()) {
539 return m_pairs[index].filename;
540 }
541 else {
542 QString msg = "Unable to get the FileName. The given index ["
543 + toString(index) + "] is invalid.";
544 throw IException(IException::Programmer, msg, _FILEINFO_);
545 }
546 }
547
548
560 if (index >= 0 && index < (int) m_pairs.size()) {
561 QString scid = (m_pairs[index].spacecraftName + "/" + m_pairs[index].instrumentId).toUpper();
562
563 // silence 'unused-result' warnings with arbitrary cast
564 (void)scid.simplified();
565 return scid.replace(" ","");
566 }
567 else {
568 QString msg = "Unable to get the Spacecraft InstrumentId. The given index ["
569 + toString(index) + "] is invalid.";
570 throw IException(IException::Programmer, msg, _FILEINFO_);
571 }
572 }
573
574
585 QString SerialNumberList::spacecraftInstrumentId(const QString &sn) {
586 if (hasSerialNumber(sn)) {
587 int index = m_serialMap.find(sn)->second;
588 QString scid = (m_pairs[index].spacecraftName + "/" + m_pairs[index].instrumentId).toUpper();
589
590 // silence 'unused-result' warnings with arbitrary cast
591 (void)scid.simplified();
592 return scid.replace(" ","");
593 }
594 else {
595 QString msg = "Unable to get the Spacecraft InstrumentId. The given serial number ["
596 + sn + "] does not exist in the list.";
597 throw IException(IException::Programmer, msg, _FILEINFO_);
598 }
599 }
600
601
613 std::vector<QString> SerialNumberList::possibleSerialNumbers(const QString &on) {
614 std::vector<QString> numbers;
615 for (unsigned index = 0; index < m_pairs.size(); index++) {
616 if (m_pairs[index].observationNumber == on) {
617 numbers.push_back(m_pairs[index].serialNumber);
618 }
619 }
620 if (numbers.size() > 0) {
621 return numbers;
622 }
623 else {
624 QString msg = "Unable to get the possible serial numbers. The given observation number ["
625 + on + "] does not exist in the list.";
626 throw IException(IException::Programmer, msg, _FILEINFO_);
627 }
628 }
629
630
631}
Internalizes a list of files.
Definition FileList.h:54
File name manipulation and expansion.
Definition FileName.h:100
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition FileName.cpp:196
Isis exception class.
Definition IException.h:91
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
static QString Compose(Pvl &label, bool def2filename=false)
Compose a ObservationNumber from a PVL.
Program progress reporter.
Definition Progress.h:42
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition Progress.cpp:85
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition Progress.cpp:61
void CheckStatus()
Checks and updates the status.
Definition Progress.cpp:105
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition PvlObject.h:276
static QString Compose(Pvl &label, bool def2filename=false)
Compose a SerialNumber from a PVL.
virtual ~SerialNumberList()
Destructor.
bool hasSerialNumber(QString sn)
Determines whether or not the requested serial number exists in the list.
QString observationNumber(int index)
Return a observation number given an index.
std::map< QString, int > m_serialMap
Maps serial numbers to their positions in the list.
std::map< QString, int > m_fileMap
Maps filenames to their positions in the list.
void remove(const QString &sn)
Remove the specified serial number from the list.
QString serialNumber(const QString &filename)
Return a serial number given a filename.
void add(const QString &filename, bool def2filename=false)
Adds a new filename / serial number pair to the SerialNumberList.
bool m_checkTarget
Specifies whether or not to check to make sure the target names match between files added to the seri...
SerialNumberList(bool checkTarget=true)
Creates an empty SerialNumberList.
QString spacecraftInstrumentId(int index)
Return the spacecraftname/instrumentid at the given index.
QString m_target
Target name that the files must have if m_checkTarget is true
int size() const
How many serial number / filename combos are in the list.
int serialNumberIndex(const QString &sn)
Return a list index given a serial number.
int fileNameIndex(const QString &filename)
Return a list index given a filename.
std::vector< Pair > m_pairs
List of serial number Pair entities.
std::vector< QString > possibleSerialNumbers(const QString &on)
Return possible serial numbers given an observation number.
QString fileName(const QString &sn)
Return a filename given a serial number.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
A serial number list entity that contains the filename serial number pair.