Isis 3 Programmer Reference
PipelineApplication.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <iostream>
8
9#include "PipelineApplication.h"
10#include "Pipeline.h"
11#include "IException.h"
12#include "Application.h"
13
14using namespace Isis;
15using namespace std;
16
17namespace Isis {
26 p_name = appName;
27 p_enabled = true;
28 p_previous = NULL;
29 p_next = NULL;
30 p_pipeline = pipe;
31 p_continue = false;
32
33 if(p_pipeline->OriginalBranches().size() == 1) {
34 p_inBranches.push_back("");
35 p_outBranches.push_back("");
36 p_enableBranch.push_back(true);
37 }
38 else {
41 for(int i=0; i<(int)p_outBranches.size(); i++) {
42 p_enableBranch.push_back(true);
43 }
44 }
45 };
46
47
56 p_name = appName;
57 p_enabled = true;
58 p_previous = previous;
59 p_next = NULL;
61
64 for(int i=0; i<(int)p_outBranches.size(); i++) {
65 p_enableBranch.push_back(true);
66 }
67 p_previous->SetNext(this);
68 }
69
70
79 void PipelineApplication::SetInputParameter(const QString &inputParamName, bool supportsVirtualBands) {
80 p_input.clear();
81 p_input.push_back(PipelineParameter(inputParamName));
82 p_supportsVirtualBands = supportsVirtualBands;
83 }
84
85
96 void PipelineApplication::SetInputParameter(const QString &inputParamName, CustomParameterValue value, bool supportsVirtualBands) {
97 if(value == LastAppOutputList) {
98 // Merge
99 p_outBranches.clear();
100 p_outBranches.push_back("");
101 }
102 else if(value == LastAppOutputListNoMerge) {
103 // No merge
104 value = LastAppOutputList;
105 }
106
107 p_input.push_back(PipelineParameter(inputParamName, value));
108 p_supportsVirtualBands = supportsVirtualBands;
109 }
110
111
122 void PipelineApplication::SetOutputParameter(const QString &branch, const QString &outputParamName,
123 const QString &outNameModifier, const QString &outFileExtension) {
124 p_output.push_back(PipelineParameter(FindBranch(branch, false), outputParamName));
125 p_outputMod = outNameModifier;
126 p_outputExtension = outFileExtension;
127 }
128
129
137 void PipelineApplication::SetOutputParameter(const QString &outputParamName, const QString &outNameModifier, const QString &outFileExtension) {
138 p_output.clear();
139 p_output.push_back(PipelineParameter(outputParamName));
140 p_outputMod = outNameModifier;
141 p_outputExtension = outFileExtension;
142 }
143
144
163 void PipelineApplication::AddBranch(const QString &modString, NameModifierType type) {
164 if(modString == "") {
165 string msg = "Can not add empty branch to pipeline";
166 throw IException(IException::Programmer, msg, _FILEINFO_);
167 }
168
169 //if(p_inBranches.size() != 1 || p_inBranches[0] != "") {
170 // string msg = "Can not branch an already branched pipeline";
171 // throw iException::Message(iException::Programmer, msg, _FILEINFO_);
172 //}
173
174 if(p_outBranches[0] == "") {
175 p_outBranches.clear();
176 p_enableBranch.clear();
177 }
178
179 if(p_inBranches.size() == 1) {
180 p_outBranches.push_back(modString);
181 p_enableBranch.push_back(true);
182 }
183 else if(p_inBranches.size() == p_outBranches.size()) {
184 for(int outBranch = p_outBranches.size() - 1; outBranch >= 0; outBranch --) {
185 if(p_inBranches[outBranch] == p_outBranches[outBranch]) {
186 p_outBranches[outBranch] = p_inBranches[outBranch] + "." + modString;
187 }
188 else {
189 p_outBranches.push_back(p_inBranches[outBranch] + "." + modString);
190 p_enableBranch.push_back(true);
191 }
192 }
193 }
194 else {
195 for(unsigned int inBranch = 0; inBranch < p_inBranches.size(); inBranch ++) {
196 p_outBranches.push_back(p_inBranches[inBranch] + "." + modString);
197 p_enableBranch.push_back(true);
198 }
199 }
200 }
201
202
210 void PipelineApplication::AddParameter(const QString &inputParamName, const QString &appParamName) {
212
213 if(ui.WasEntered(inputParamName)) {
214 p_params.push_back(PipelineParameter(appParamName, ui.GetAsString(inputParamName)));
215 }
216 }
217
218
228 void PipelineApplication::AddParameter(const QString &branch, const QString &inputParamName, const QString &appParamName) {
230
231 if(ui.WasEntered(inputParamName)) {
232 p_params.push_back(PipelineParameter(FindBranch(branch, false), appParamName, ui.GetAsString(inputParamName)));
233 }
234 }
235
236
244 void PipelineApplication::AddConstParameter(const QString &appParamName, const QString &appParamValue) {
245 bool added = false;
246
247 for(unsigned int i = 0; !added && i < p_params.size(); i++) {
248 if(p_params[i].Name() == appParamName) {
249 p_params[i] = PipelineParameter(appParamName, appParamValue);
250 added = true;
251 }
252 }
253
254 if(!added) {
255 p_params.push_back(PipelineParameter(appParamName, appParamValue));
256 added = true;
257 }
258 }
259
260
270 void PipelineApplication::AddConstParameter(const QString &branch, const QString &appParamName, const QString &appParamValue) {
271 p_params.push_back(PipelineParameter(FindBranch(branch, false), appParamName, appParamValue));
272 }
273
274
282 void PipelineApplication::AddParameter(const QString &appParamName, CustomParameterValue value) {
283 p_params.push_back(PipelineParameter(appParamName, value));
284 }
285
286
295 void PipelineApplication::AddParameter(const QString &branch, const QString &appParamName, CustomParameterValue value) {
296 p_params.push_back(PipelineParameter(FindBranch(branch, false), appParamName, value));
297 }
298
299
309 p_paramString.clear();
310 p_outputs.clear();
311 p_tempFiles.clear();
312
313 if(!Enabled()) return;
314
315 // These are used if the pipeline needs a list file; must be out here in case multiple branches use
316 // the list file.
317 bool needList = false;
318 QString listFile;
319
320 bool runOnce = Merges() && !Branches();
321
322 /*cerr << "***BuildParamString App " << p_name << " RunOnce="<< runOnce << "***\nInput Branches Size=" << p_inBranches.size() << endl;
323 for(int i=0; i<(int)p_inBranches.size(); i++) {
324 cerr << "Branch" << i << " = " << p_inBranches[i] << endl;
325 }
326
327 cerr << "Output Branches Size=" << p_outBranches.size() << endl;
328 for(int i=0; i<(int)p_outBranches.size(); i++) {
329 cerr << "Branch" << i << " = " << p_outBranches[i] << " Enabled=" << p_enableBranch[i] << endl;
330 }*/
331
332 // Make sure we have different inputs for different runs...
333 if(!runOnce && p_input.size() == 1) {
334 PipelineParameter &inputParam = p_input[0];
335 if(inputParam.IsSpecial() && inputParam.Special() == LastAppOutputList) {
336 runOnce = true;
337
338 for(int param = 0; param < (int)p_params.size() && runOnce; param++) {
339 runOnce = (p_params[param].IsSpecial() && p_params[param].Special() == LastAppOutputList) ||
340 (!p_params[param].IsSpecial() && p_params[param].AffectsAllBranches());
341 }
342 }
343 }
344
345 // We need to build execute calls for all of the branches
346 for(int branch = 0; branch < (int)p_inBranches.size(); branch ++) {
347 if(runOnce && branch > 0) {
348 return;
349 }
350
351 if(!BranchEnabled(branch)) {
352 QString tmpBranch(branch);
353 p_outputs.push_back(p_name + "." +tmpBranch + ".blank");
354 continue;
355 }
356
357
358 // Figure out the input file; could throw an exception if the user didnt set it
359 QString inputFile = CalculateInputFile(branch);
360 // Figure out the output file; This adds the output to the output list*
361 QString outputFile = CalculateOutputFile(branch);
362 // This parameter gives us more detail about the input parameter
363 PipelineParameter &inputParam = GetInputParameter(branch);
364
365 QString params = "";
366
367 // If we havent needed a list yet, let's see if we need one now
368 if(!needList) {
369 // We need to know if we need a list file ahead of time; look at input and parameters
370 needList = (inputParam.IsSpecial() && inputParam.Special() == LastAppOutputList);
371
372 for(int param = 0; param < (int)p_params.size() && !needList; param++) {
373 needList = (p_params[param].IsSpecial() && p_params[param].Special() == LastAppOutputList);
374 }
375
376 // If we need a list file, create a parameter that starts with ">>LIST" to say it's a list file.
377 // The first element is the list file, the rest is the contents of the list file.
378 if(needList) {
379 QString listName = outputFile;
380
381 if(listName.isEmpty()) {
382 // This might have to become more robust in the future, we
383 // have an input list but no outputs to the program for
384 // this case. This is the naming of the list.
385 listName = Name();
386 }
387
388 QString input = p_pipeline->TemporaryFolder() + "/" + FileName(listName).baseName() + ".lis";
389 params = ">>LIST " + input + " ";
390
391 PipelineApplication * prev = Previous();
392 int infile = 0;
393 while(prev != NULL && infile < (int)p_inBranches.size()) {
394 for(int i = 0; i < (int)prev->OutputBranches().size(); i++) {
395 if(prev->BranchEnabled(i)) {
396 params += " " + prev->GetOutputs()[i];
397 infile++;
398 }
399 }
400 prev = prev->Previous();
401 }
402
403 p_tempFiles.push_back(input);
404 p_paramString.push_back(params);
405 params = "";
406 listFile = input;
407 }
408 }
409
410 // If the input is a list file, set it to the list file
411 if(inputParam.IsSpecial() && inputParam.Special() == LastAppOutputList) {
412 params = GetInputParameter(branch).Name() + "=\"" + listFile + "\"";
413 }
414 else {
415 // Otherwise it's the input file. Try to add virtual bands.
416 // Pipeline will set p_virtualBands to an empty string if we are to not apply it.
417 params = GetInputParameter(branch).Name() + "=\"" + inputFile;
418 if(p_virtualBands.size() == 1) {
419 params += "+" + p_virtualBands[0];
420 }
421 else if(p_virtualBands.size() == p_inBranches.size() && !p_virtualBands[branch].isEmpty()) {
422 params += "+" + p_virtualBands[branch];
423 }
424
425 params += "\"";
426 }
427
428 // If we have output, add it on to our parameters
429 if(p_output.size() != 0) {
430 if(Branches() && p_output.size() != 1) {
431 // Set output variable for every branch
432 for(unsigned int outBranch = 0; outBranch < p_outBranches.size(); outBranch ++) {
433 // Each branch should have at least 1 output file
434 bool outputSet = false;
435
436 // ... unless there is a split, look for the split (check name start)
437 if(p_inBranches.size() > 1) {
438 if(!StringStartsWith(p_outBranches[outBranch], p_inBranches[branch])) {
439 continue;
440 }
441 }
442
443 // Match the output variable with it's param name
444 for(unsigned int outParam = 0; outParam < p_output.size(); outParam++) {
445 if(p_output[outParam].AppliesToBranch(outBranch)) {
446 params += " " + p_output[outParam].Name() + "=\"" + p_outputs[outBranch] + "\"";
447
448 if(outputSet) {
449 QString message = "Application [" + Name() + "] in the pipeline branches with an ";
450 message += "output parameter for each branch, but branch [" + p_outBranches[outBranch];
451 message += "] has multiple output files specified.";
452 throw IException(IException::Programmer, message, _FILEINFO_);
453 }
454
455 outputSet = true;
456 }
457 }
458
459 if(!outputSet) {
460 QString message = "Application [" + Name() + "] in the pipeline branches with an ";
461 message += "output parameter for each branch, but branch [" + p_outBranches[outBranch];
462 message += "] has no output files specified.";
463 throw IException(IException::Programmer, message, _FILEINFO_);
464 }
465 }
466 }
467 else {
468 bool foundBranch = false;
469
470 // Find the output parameter name that is acceptable. If we cant find an output branch, then there isnt one!
471 for(unsigned int outputParam = 0; outputParam < p_output.size(); outputParam++) {
472 if(p_output[outputParam].AppliesToBranch(branch)) {
473 params += " " + p_output[0].Name() + "=\"" + outputFile + "\"";
474 foundBranch = true;
475 }
476 }
477
478 if(!foundBranch) continue;
479 }
480 }
481
482 // Add the remaining parameters
483 for(int i = 0; i < (int)p_params.size() && i < (int)p_params.size(); i++) {
484 if(p_params[i].AppliesToBranch(branch)) {
485 if(!p_params[i].IsSpecial()) {
486 params += " " + p_params[i].Name() + "=\"" + p_params[i].Value() + "\"";
487 }
488 else if(p_params[i].Special() == LastOutput) {
489 params += " " + p_params[i].Name() + "=\"" + GetRealLastOutput(true) + "\"";
490 }
491 else if(p_params[i].Special() == LastAppOutputList) {
492 params += " " + p_params[i].Name() + "=\"" + listFile + "\"";
493 }
494 }
495 }
496
497 if(inputFile.isEmpty()) {
498 QString message = "There was a problem with calculating the inputs for program [" + Name();
499 message += "]. Please verify your program is not setting outputs for branches that ";
500 message += "don't have input.";
501 throw IException(IException::Programmer, message, _FILEINFO_);
502 }
503
504 // Remember this parameter string
505 p_paramString.push_back(params);
506 }
507 }
508
509
520 QString file = "";
521
523
524 if(prev != NULL) {
525 // The last app exists, look for output on this branch
526 if(branch < (int)prev->GetOutputs().size() && prev->BranchEnabled(branch)) {
527 file = prev->GetOutputs()[branch];
528 }
529 else {
530 while (prev != NULL && file=="") {
531 if(prev->Branches()){
532 if (!prev->BranchEnabled(branch)) {
533 string msg = "Application branches but branch is disabled";
534 throw IException(IException::Programmer, msg, _FILEINFO_);
535 }
536 }
537 /* else {
538 vector<QString> inputs = prev->GetInputs();
539 if((int)inputs.size() > branch) {
540 file = inputs[branch];
541 }
542 else {
543 file = inputs[0];
544 }
545 break;
546 }
547 } */
548 //else {
549 if(prev->BranchEnabled(branch)) {
550 if(branch < (int)prev->GetOutputs().size()) {
551 file = prev->GetOutputs()[branch];
552 break;
553 }
554 }
555 // }
556 prev = prev->Previous();
557 }
558 }
559 }
560
561 // We're either the first program, or nothing has generated output yet.
562 if(file.isEmpty()){
563 file = p_pipeline->OriginalInput(branch);
564 if (file.isEmpty()) {
565 int index = branch / (p_pipeline->OriginalBranchesSize() / p_pipeline->OriginalInputSize());
566 file = p_pipeline->OriginalInput(index);
567 }
568 }
569
570 // deal with special cases
571 for(int i = 0; i < (int)p_input.size(); i++) {
572 if(p_input[i].AppliesToBranch(branch) && p_input[i].IsSpecial()) {
573 if(p_input[i].Special() == LastOutput) {
574 file = GetRealLastOutput();
575 break;
576 }
577 }
578 }
579 return file;
580 }
581
582
591 QString outputFile;
592 QString outFolder = p_pipeline->TemporaryFolder();
593
594 // We need to know this to know if we actually need to add modifiers to the
595 // output name
596 bool usedBranch = false;
597 unsigned int usedBranchIndex = 0;
598 unsigned int numUsedBranches = 0;
599
600 for(unsigned int outputBranch = 0; outputBranch < p_outBranches.size(); outputBranch++) {
601 bool outBranchUsed = false;
602
603 for(unsigned int outputParam = 0; outputParam < p_output.size(); outputParam ++) {
604 if(p_output[outputParam].AppliesToBranch(outputBranch)) {
605 outBranchUsed = true;
606 }
607 }
608
609 if(outBranchUsed) {
610 if(outputBranch < (unsigned int)branch) {
611 usedBranchIndex ++;
612 }
613
614 if((unsigned int)branch == outputBranch) {
615 usedBranch = true;
616 }
617
618 numUsedBranches ++;
619 }
620 }
621
622 if(!usedBranch) return "";
623
625 QString lastOutput = p_pipeline->FinalOutput(branch, false);
626 outputFile = outFolder + "/" +
627 FileName(lastOutput).baseName() + "." + p_outputMod + "." + p_outputExtension;
628
629 if(p_outputMod.isEmpty()) {
630 outputFile = outFolder + "/" +
631 FileName(lastOutput).baseName() + "." + p_outputExtension;
632 }
633 }
634 else {
635 outputFile = p_pipeline->FinalOutput(branch, numUsedBranches > 1);
636 outFolder = FileName(outputFile).path();
637 }
638
639 if(!LastApplicationWithOutput() && numUsedBranches != 1 && !p_outputMod.isEmpty()) {
640 FileName outfile(outputFile);
641
642 QString realOut(outFolder + "/" + outfile.baseName() + "." + p_outBranches[branch] + "." + p_outputExtension);
643
644 if(usedBranch) {
645
646 // This assumes CalculateOutputFile is called in order (branch 0,1,2...n)
647 if(p_outputs.size() == usedBranchIndex) {
648 p_outputs.push_back(realOut);
649 }
650
651 // If we're only run once, but we branch, we need to store the rest of these real output files...
652 // recursively call to get them stored away. Also we could be run twice, but really have 4 outputs,
653 // so always do this if we branch.
654 if(branch == 0 && Branches()) {
655 for(unsigned int i = 1; i < OutputBranches().size(); i++) {
657 }
658 }
659
660 // If branches is false, then we need to tell the truth about the output file.
661 // REASONING: thm2isis needs to be lied to (Branches() == true), for example,
662 // because it modifies output names on its own.
663 if(!Branches()) {
664 // tell the truth
665 outputFile = realOut;
666 }
667 }
668 }
669 else if(!p_outputMod.isEmpty()) {
670 if(p_outputs.size() == usedBranchIndex) {
671 p_outputs.push_back(outputFile);
672 }
673
674 // If we're only run once, but we branch, we need to store the rest of these real output files...
675 // recursively call to get them stored away. Also we could be run twice, but really have 4 outputs,
676 // so always do this if we branch.
677 if(branch == 0 && Branches()) {
678 for(unsigned int i = 1; i < OutputBranches().size(); i++) {
680 }
681 }
682 }
683
684 return outputFile;
685 }
686
687
695 if(!Next() && !p_output.empty()) {
696 return true;
697 }
698 if(!Next() && p_output.empty()) {
699 return false;
700 }
701
702 // If any future app creates output, then I'm not last
703 return !Next()->FutureOutputFileCreated();
704 }
705
706
714 if(!p_output.empty()) {
715 return true;
716 }
717
718 if(!Next() && p_output.empty()) {
719 return false;
720 }
721
722 return Next()->FutureOutputFileCreated();
723 }
724
725
734 for(int i = 0; i < (int)p_input.size(); i++) {
735 if(p_input[i].AppliesToBranch(branch)) {
736 return p_input[i];
737 }
738 }
739
740 if(p_inBranches[0] != "") {
741 QString msg = "Application [" + Name() + "] in the pipeline does not have an input for branch [" + p_inBranches[branch] + "]";
742 throw IException(IException::Programmer, msg, _FILEINFO_);
743 }
744 else {
745 QString msg = "Application [" + Name() + "] in the pipeline does not have an input";
746 throw IException(IException::Programmer, msg, _FILEINFO_);
747 }
748 }
749
750
759 int PipelineApplication::FindBranch(QString name, bool input) {
760 int branchIndex = 0;
761 bool found = false;
762
763 if(input) {
764 while(!found && branchIndex < (int)p_inBranches.size()) {
765 if(p_inBranches[branchIndex] == name) {
766 found = true;
767 }
768 else {
769 branchIndex ++;
770 }
771 }
772 }
773 else {
774 while(!found && branchIndex < (int)p_outBranches.size()) {
775 if(p_outBranches[branchIndex] == name) {
776 found = true;
777 }
778 else {
779 branchIndex ++;
780 }
781 }
782 }
783
784 if(!found) {
785 QString msg = "Branch [" + name + "] does not exist in the pipeline application [" + Name() + "]";
786 throw IException(IException::Programmer, msg, _FILEINFO_);
787 }
788
789 return branchIndex;
790 }
791
792
800 vector<QString> tmp;
801
803 for(int i = 0; i < (int)p_outputs.size(); i++) {
804 tmp.push_back(p_outputs[i]);
805 }
806 }
807
808 for(int i = 0; i < (int)p_tempFiles.size(); i++) {
809 tmp.push_back(p_tempFiles[i]);
810 }
811
812 return tmp;
813 }
814
815
826 if(!skipOne) {
827 return GetOutputs()[GetOutputs().size()-1];
828 }
829
830 if(p_outputs.size() > 1) {
831 return GetOutputs()[GetOutputs().size()-2];
832 }
833
834 return Previous()->GetOutputs()[Previous()->GetOutputs().size()-1];
835 }
836
837
845 if(!Enabled()) return false;
847 }
848
849
856 void PipelineApplication::SetVirtualBands(vector<QString> bands) {
857 p_virtualBands = bands;
858 }
859
862 if(Enabled() && p_outputs.size() != 0) {
863 return p_outputs;
864 }
865 else if(Previous()) {
866 return Previous()->GetOutputs();
867 }
868 else {
869 // no outputs yet... not sure if an exception should be thrown, sometimes
870 // things such as list files will fail when this returns nothing.
871 return p_outputs;
872 }
873 }
874}; // end namespace Isis
static UserInterface & GetUserInterface()
Returns the UserInterface object.
File name manipulation and expansion.
Definition FileName.h:100
QString path() const
Returns the path of the file name.
Definition FileName.cpp:103
QString baseName() const
Returns the name of the file without the path and without extensions.
Definition FileName.cpp:145
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
This class represents one application in the pipeline.
void SetVirtualBands(std::vector< QString > bands)
Set the virtual bands that this application is to apply.
bool Merges()
Returns true if this application does merge branches (multiple input branches, one output)
std::vector< bool > p_enableBranch
Branch enabled/disabled.
const QString & Name() const
Get the name of this pipeline application.
Pipeline * GetPipeline()
Returns the pipeline.
NameModifierType
This is used for branches.
std::vector< QString > p_outBranches
Output branches.
QString p_outputExtension
Output file name extension.
PipelineApplication * Previous() const
This returns the last enabled pipeline application or null.
QString CalculateOutputFile(int branch)
This method calculates the output file for the specified branch.
bool p_supportsVirtualBands
This application supports virtual bands?
bool SupportsVirtualBands()
Returns true if virtual bands are supported.
QString p_outputMod
Output file name modifier.
std::vector< QString > p_virtualBands
Virtual bands string to add (empty if none)
Pipeline * p_pipeline
The pipeline.
QString GetRealLastOutput(bool skipOne=false)
This method is used to calculate the value for CustomParameterValue::LastOutput.
bool BranchEnabled(int branch)
Check whether a branch is enabled given branch index.
std::vector< QString > p_paramString
Built parameter strings.
bool p_enabled
This application enabled?
bool p_continue
Continue the pipeline execution even if an error is encountered by this app.
std::vector< PipelineParameter > p_input
Input parameters.
PipelineApplication * Next() const
This returns the next enabled pipeline application or null.
bool FutureOutputFileCreated()
Returns true if a future application creates output.
void AddParameter(const QString &inputParamName, const QString &appParamName)
This method adds knowledge of a parameter to the application.
void BuildParamString()
This method calculates the inputs, outputs and necessary calls to this program for the pipeline.
PipelineApplication * p_next
Next pipeline application.
std::vector< PipelineParameter > p_output
Output parameters.
CustomParameterValue
This is used to set custom values that must be calculated on the fly.
@ LastAppOutputListNoMerge
A list of files from the last run application's output.
@ LastOutput
The very last output file. Do not use this for input parameters if it's not necessary,...
@ LastAppOutputList
A list of files from the last run application's output.
QString CalculateInputFile(int branch)
This method calculates the input file for the specified branch.
PipelineApplication(QString appName, Pipeline *pipe)
Constructs the first pipeline application.
const bool & Enabled() const
Returns true if this program will be run.
void AddBranch(const QString &modString, NameModifierType type)
This method adds branch to this program.
std::vector< QString > & GetOutputs()
This returns this application's output files. Only valid after BuildParamString is called.
PipelineApplication * p_previous
Previous pipeline application.
PipelineParameter & GetInputParameter(int branch)
This gets the input parameter for the specified branch.
std::vector< PipelineParameter > p_params
Regular parameters.
QString p_name
Name of this application.
void AddConstParameter(const QString &appParamName, const QString &appParamValue)
This method adds a parameter to this application with a known value (does not get it from the user in...
bool Branches()
Return true is this application does branch (one input branch, multiple output)
void SetOutputParameter(const QString &outputParamName, const QString &outNameModifier, const QString &outFileExtension="cub")
Set the output parameter for this application and it's naming convention.
std::vector< QString > TemporaryFiles()
This method returns a list of the temporary files generated by this program.
bool LastApplicationWithOutput()
Returns true if this is the last application with output.
void SetNext(PipelineApplication *next)
Link to the next application in the pipeline.
int FindBranch(QString name, bool input=true)
The method, given a string, finds the index of a branch.
void SetInputParameter(const QString &inputParamName, bool supportsVirtualBands)
Set the input parameter for this application and whether or not this application supports the virtual...
bool StringStartsWith(QString from, QString compare)
String comparison helper, returns true if from starts with compare bool.
std::vector< QString > p_outputs
Actual output files.
std::vector< QString > p_inBranches
Input branches.
const std::vector< QString > & OutputBranches() const
Get the branches this program has as output.
std::vector< QString > p_tempFiles
Actial temporary files.
This class helps to call other Isis Applications in a Pipeline.
Definition Pipeline.h:151
int OriginalInputSize()
Returns the number of input files.
Definition Pipeline.h:212
int OriginalBranchesSize()
Returns the total number of input branches Original branches = Number of input files * Number of bran...
Definition Pipeline.h:224
QString FinalOutput(int branch=0, bool addModifiers=true)
This gets the final output for the specified branch; this is necessary for the PipelineApplications t...
Definition Pipeline.cpp:805
QString TemporaryFolder()
This method returns the user's temporary folder for temporary files.
Definition Pipeline.cpp:882
QString OriginalInput(unsigned int branch)
Returns the initial input file for the pipeline.
Definition Pipeline.h:207
std::vector< QString > OriginalBranches()
Returns the names of the original branches of the pipeline (input files * branches if any)
Definition Pipeline.h:233
This class represents a parameter of some type for the PipelineApplication.
QString Name()
Name of the parameter.
Command Line and Xml loader, validation, and access.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
bool IsSpecial(const double d)
Returns if the input pixel is special.
Namespace for the standard library.