5 // Created by Sarah Westcott on 5/21/12.
6 // Copyright (c) 2012 Schloss Lab. All rights reserved.
9 #include "removeotulabelscommand.h"
11 //**********************************************************************************************************************
12 vector<string> RemoveOtuLabelsCommand::setParameters(){
14 CommandParameter paccnos("accnos", "InputTypes", "", "", "none", "none", "none","",false,true,true); parameters.push_back(paccnos);
15 CommandParameter pconstaxonomy("constaxonomy", "InputTypes", "", "", "none", "FNGLT", "none","constaxonomy",false,false); parameters.push_back(pconstaxonomy);
16 CommandParameter potucorr("otucorr", "InputTypes", "", "", "none", "FNGLT", "none","otucorr",false,false); parameters.push_back(potucorr);
17 CommandParameter pcorraxes("corraxes", "InputTypes", "", "", "none", "FNGLT", "none","corraxes",false,false); parameters.push_back(pcorraxes);
18 CommandParameter plist("list", "InputTypes", "", "", "none", "FNGLT", "none","list",false,false, true); parameters.push_back(plist);
19 CommandParameter pshared("shared", "InputTypes", "", "", "none", "FNGLT", "none","shared",false,false, true); parameters.push_back(pshared);
20 CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
21 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
22 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
24 vector<string> myArray;
25 for (int i = 0; i < parameters.size(); i++) { myArray.push_back(parameters[i].name); }
29 m->errorOut(e, "RemoveOtuLabelsCommand", "setParameters");
33 //**********************************************************************************************************************
34 string RemoveOtuLabelsCommand::getHelpString(){
36 string helpString = "";
37 helpString += "The remove.otulabels command can be used to remove specific otus with the output from classify.otu, otu.association, or corr.axes. It can also be used to select a set of otus from a shared or list file.\n";
38 helpString += "The remove.otulabels parameters are: constaxonomy, otucorr, corraxes, shared, list, label and accnos.\n";
39 helpString += "The constaxonomy parameter is input the results of the classify.otu command.\n";
40 helpString += "The otucorr parameter is input the results of the otu.association command.\n";
41 helpString += "The corraxes parameter is input the results of the corr.axes command.\n";
42 helpString += "The label parameter is used to analyze specific labels in your input. \n";
43 helpString += "The remove.otulabels commmand should be in the following format: \n";
44 helpString += "remove.otulabels(accnos=yourListOfOTULabels, corraxes=yourCorrAxesFile)\n";
48 m->errorOut(e, "RemoveOtuLabelsCommand", "getHelpString");
52 //**********************************************************************************************************************
53 string RemoveOtuLabelsCommand::getOutputPattern(string type) {
57 if (type == "constaxonomy") { pattern = "[filename],pick,[extension]"; }
58 else if (type == "otucorr") { pattern = "[filename],pick,[extension]"; }
59 else if (type == "corraxes") { pattern = "[filename],pick,[extension]"; }
60 else if (type == "list") { pattern = "[filename],[distance],pick,[extension]"; }
61 else if (type == "shared") { pattern = "[filename],[distance],pick,[extension]"; }
62 else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true; }
67 m->errorOut(e, "RemoveOtuLabelsCommand", "getOutputPattern");
71 //**********************************************************************************************************************
72 RemoveOtuLabelsCommand::RemoveOtuLabelsCommand(){
74 abort = true; calledHelp = true;
76 vector<string> tempOutNames;
77 outputTypes["constaxonomy"] = tempOutNames;
78 outputTypes["otucorr"] = tempOutNames;
79 outputTypes["corraxes"] = tempOutNames;
80 outputTypes["shared"] = tempOutNames;
81 outputTypes["list"] = tempOutNames;
84 m->errorOut(e, "RemoveOtuLabelsCommand", "RemoveOtuLabelsCommand");
88 //**********************************************************************************************************************
89 RemoveOtuLabelsCommand::RemoveOtuLabelsCommand(string option) {
91 abort = false; calledHelp = false;
93 //allow user to run help
94 if(option == "help") { help(); abort = true; calledHelp = true; }
95 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
98 //valid paramters for this command
99 vector<string> myArray = setParameters();
101 OptionParser parser(option);
102 map<string,string> parameters = parser.getParameters();
104 ValidParameters validParameter;
105 map<string,string>::iterator it;
106 //check to make sure all parameters are valid for command
107 for (it = parameters.begin(); it != parameters.end(); it++) {
108 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) { abort = true; }
112 //if the user changes the input directory command factory will send this info to us in the output parameter
113 string inputDir = validParameter.validFile(parameters, "inputdir", false);
114 if (inputDir == "not found"){ inputDir = ""; }
117 //edit file types below to include only the types you added as parameters
120 it = parameters.find("constaxonomy");
121 //user has given a template file
122 if(it != parameters.end()){
123 path = m->hasPath(it->second);
124 //if the user has not given a path then, add inputdir. else leave path alone.
125 if (path == "") { parameters["constaxonomy"] = inputDir + it->second; }
128 it = parameters.find("accnos");
129 //user has given a template file
130 if(it != parameters.end()){
131 path = m->hasPath(it->second);
132 //if the user has not given a path then, add inputdir. else leave path alone.
133 if (path == "") { parameters["accnos"] = inputDir + it->second; }
136 it = parameters.find("corraxes");
137 //user has given a template file
138 if(it != parameters.end()){
139 path = m->hasPath(it->second);
140 //if the user has not given a path then, add inputdir. else leave path alone.
141 if (path == "") { parameters["corraxes"] = inputDir + it->second; }
144 it = parameters.find("otucorr");
145 //user has given a template file
146 if(it != parameters.end()){
147 path = m->hasPath(it->second);
148 //if the user has not given a path then, add inputdir. else leave path alone.
149 if (path == "") { parameters["otucorr"] = inputDir + it->second; }
152 it = parameters.find("list");
153 //user has given a template file
154 if(it != parameters.end()){
155 path = m->hasPath(it->second);
156 //if the user has not given a path then, add inputdir. else leave path alone.
157 if (path == "") { parameters["list"] = inputDir + it->second; }
160 it = parameters.find("shared");
161 //user has given a template file
162 if(it != parameters.end()){
163 path = m->hasPath(it->second);
164 //if the user has not given a path then, add inputdir. else leave path alone.
165 if (path == "") { parameters["shared"] = inputDir + it->second; }
169 vector<string> tempOutNames;
170 outputTypes["constaxonomy"] = tempOutNames;
171 outputTypes["otucorr"] = tempOutNames;
172 outputTypes["corraxes"] = tempOutNames;
173 outputTypes["shared"] = tempOutNames;
174 outputTypes["list"] = tempOutNames;
177 //check for parameters
178 accnosfile = validParameter.validFile(parameters, "accnos", true);
179 if (accnosfile == "not open") { abort = true; }
180 else if (accnosfile == "not found") {
181 accnosfile = m->getAccnosFile();
182 if (accnosfile != "") { m->mothurOut("Using " + accnosfile + " as input file for the accnos parameter."); m->mothurOutEndLine(); }
184 m->mothurOut("You have no valid accnos file and accnos is required."); m->mothurOutEndLine();
187 }else { m->setAccnosFile(accnosfile); }
189 constaxonomyfile = validParameter.validFile(parameters, "constaxonomy", true);
190 if (constaxonomyfile == "not open") { constaxonomyfile = ""; abort = true; }
191 else if (constaxonomyfile == "not found") { constaxonomyfile = ""; }
193 corraxesfile = validParameter.validFile(parameters, "corraxes", true);
194 if (corraxesfile == "not open") { corraxesfile = ""; abort = true; }
195 else if (corraxesfile == "not found") { corraxesfile = ""; }
197 otucorrfile = validParameter.validFile(parameters, "otucorr", true);
198 if (otucorrfile == "not open") { otucorrfile = ""; abort = true; }
199 else if (otucorrfile == "not found") { otucorrfile = ""; }
201 listfile = validParameter.validFile(parameters, "list", true);
202 if (listfile == "not open") { listfile = ""; abort = true; }
203 else if (listfile == "not found") { listfile = ""; }
204 else { m->setListFile(listfile); }
206 sharedfile = validParameter.validFile(parameters, "shared", true);
207 if (sharedfile == "not open") { sharedfile = ""; abort = true; }
208 else if (sharedfile == "not found") { sharedfile = ""; }
209 else { m->setSharedFile(sharedfile); }
211 //if the user changes the output directory command factory will send this info to us in the output parameter
212 outputDir = validParameter.validFile(parameters, "outputdir", false); if (outputDir == "not found"){ outputDir = ""; }
214 if ((constaxonomyfile == "") && (corraxesfile == "") && (otucorrfile == "") && (sharedfile == "") && (listfile == "")) { m->mothurOut("You must provide one of the following: constaxonomy, corraxes, otucorr, shared or list."); m->mothurOutEndLine(); abort = true; }
216 if ((sharedfile != "") || (listfile != "")) {
217 label = validParameter.validFile(parameters, "label", false);
218 if (label == "not found") { label = ""; m->mothurOut("You did not provide a label, I will use the first label in your inputfile."); m->mothurOutEndLine(); label=""; }
223 catch(exception& e) {
224 m->errorOut(e, "RemoveOtuLabelsCommand", "RemoveOtuLabelsCommand");
228 //**********************************************************************************************************************
230 int RemoveOtuLabelsCommand::execute(){
233 if (abort == true) { if (calledHelp) { return 0; } return 2; }
235 //get labels you want to keep
236 labels = m->readAccnos(accnosfile);
238 if (m->control_pressed) { return 0; }
240 //read through the correct file and output lines you want to keep
241 if (constaxonomyfile != "") { readClassifyOtu(); }
242 if (corraxesfile != "") { readCorrAxes(); }
243 if (otucorrfile != "") { readOtuAssociation(); }
244 if (listfile != "") { readList(); }
245 if (sharedfile != "") { readShared(); }
247 if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; }
249 //output files created by command
250 m->mothurOutEndLine();
251 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
252 for (int i = 0; i < outputNames.size(); i++) { m->mothurOut(outputNames[i]); m->mothurOutEndLine(); }
253 m->mothurOutEndLine();
256 itTypes = outputTypes.find("list");
257 if (itTypes != outputTypes.end()) {
258 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setListFile(current); }
261 itTypes = outputTypes.find("shared");
262 if (itTypes != outputTypes.end()) {
263 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setSharedFile(current); }
268 catch(exception& e) {
269 m->errorOut(e, "GetOtuLabelsCommand", "execute");
273 //**********************************************************************************************************************
274 int RemoveOtuLabelsCommand::readClassifyOtu(){
276 string thisOutputDir = outputDir;
277 if (outputDir == "") { thisOutputDir += m->hasPath(constaxonomyfile); }
278 map<string, string> variables;
279 variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(constaxonomyfile));
280 variables["[extension]"] = m->getExtension(constaxonomyfile);
281 string outputFileName = getOutputFileName("constaxonomy", variables);
283 m->openOutputFile(outputFileName, out);
286 m->openInputFile(constaxonomyfile, in);
288 bool wroteSomething = false;
289 int removedCount = 0;
292 string headers = m->getline(in);
293 out << headers << endl;
297 if (m->control_pressed) { break; }
299 string otu = ""; string tax = "unknown";
302 in >> otu >> size >> tax; m->gobble(in);
304 if (labels.count(otu) == 0) {
305 wroteSomething = true;
306 out << otu << '\t' << size << '\t' << tax << endl;
307 }else { removedCount++; }
312 if (wroteSomething == false) { m->mothurOut("Your file only contains labels from the .accnos file."); m->mothurOutEndLine(); }
313 outputNames.push_back(outputFileName); outputTypes["constaxonomy"].push_back(outputFileName);
315 m->mothurOut("Removed " + toString(removedCount) + " otus from your constaxonomy file."); m->mothurOutEndLine();
320 catch(exception& e) {
321 m->errorOut(e, "RemoveOtuLabelsCommand", "readClassifyOtu");
325 //**********************************************************************************************************************
326 int RemoveOtuLabelsCommand::readOtuAssociation(){
328 string thisOutputDir = outputDir;
329 if (outputDir == "") { thisOutputDir += m->hasPath(otucorrfile); }
330 map<string, string> variables;
331 variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(otucorrfile));
332 variables["[extension]"] = m->getExtension(otucorrfile);
333 string outputFileName = getOutputFileName("otucorr", variables);
335 m->openOutputFile(outputFileName, out);
338 m->openInputFile(otucorrfile, in);
340 bool wroteSomething = false;
341 int removedCount = 0;
344 string headers = m->getline(in);
345 out << headers << endl;
349 if (m->control_pressed) { break; }
354 string line = m->getline(in); m->gobble(in);
356 if ((labels.count(otu1) == 0) && (labels.count(otu2) == 0)){
357 wroteSomething = true;
359 out << otu1 << '\t' << otu2 << '\t' << line << endl;
360 }else { removedCount++; }
365 if (wroteSomething == false) { m->mothurOut("Your file only contains labels from the .accnos file."); m->mothurOutEndLine(); }
366 outputNames.push_back(outputFileName); outputTypes["otucorr"].push_back(outputFileName);
368 m->mothurOut("Removed " + toString(removedCount) + " lines from your otu.corr file."); m->mothurOutEndLine();
373 catch(exception& e) {
374 m->errorOut(e, "RemoveOtuLabelsCommand", "readOtuAssociation");
378 //**********************************************************************************************************************
379 int RemoveOtuLabelsCommand::readCorrAxes(){
381 string thisOutputDir = outputDir;
382 if (outputDir == "") { thisOutputDir += m->hasPath(corraxesfile); }
383 map<string, string> variables;
384 variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(corraxesfile));
385 variables["[extension]"] = m->getExtension(corraxesfile);
386 string outputFileName = getOutputFileName("corraxes", variables);
388 m->openOutputFile(outputFileName, out);
392 m->openInputFile(corraxesfile, in);
394 bool wroteSomething = false;
395 int removedCount = 0;
398 string headers = m->getline(in);
399 out << headers << endl;
403 if (m->control_pressed) { break; }
407 string line = m->getline(in); m->gobble(in);
409 if (labels.count(otu) == 0) {
410 wroteSomething = true;
412 out << otu << '\t' << line << endl;
413 }else { removedCount++; }
418 if (wroteSomething == false) { m->mothurOut("Your file only contains labels from the .accnos file."); m->mothurOutEndLine(); }
419 outputNames.push_back(outputFileName); outputTypes["corraxes"].push_back(outputFileName);
421 m->mothurOut("Removed " + toString(removedCount) + " lines from your corr.axes file."); m->mothurOutEndLine();
426 catch(exception& e) {
427 m->errorOut(e, "RemoveOtuLabelsCommand", "readCorrAxes");
431 //**********************************************************************************************************************
432 int RemoveOtuLabelsCommand::readShared(){
437 if (m->control_pressed) { for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; } return 0; }
439 vector<string> newLabels;
441 //create new "filtered" lookup
442 vector<SharedRAbundVector*> newLookup;
443 for (int i = 0; i < lookup.size(); i++) {
444 SharedRAbundVector* temp = new SharedRAbundVector();
445 temp->setLabel(lookup[i]->getLabel());
446 temp->setGroup(lookup[i]->getGroup());
447 newLookup.push_back(temp);
450 bool wroteSomething = false;
452 for (int i = 0; i < lookup[0]->getNumBins(); i++) {
454 if (m->control_pressed) { for (int j = 0; j < newLookup.size(); j++) { delete newLookup[j]; } for (int j = 0; j < lookup.size(); j++) { delete lookup[j]; } return 0; }
456 //is this otu on the list
457 if (labels.count(m->currentBinLabels[i]) == 0) {
458 wroteSomething = true;
459 newLabels.push_back(m->currentBinLabels[i]);
460 for (int j = 0; j < newLookup.size(); j++) { //add this OTU to the new lookup
461 newLookup[j]->push_back(lookup[j]->getAbundance(i), lookup[j]->getGroup());
463 }else { numRemoved++; }
466 string thisOutputDir = outputDir;
467 if (outputDir == "") { thisOutputDir += m->hasPath(sharedfile); }
468 map<string, string> variables;
469 variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(sharedfile));
470 variables["[extension]"] = m->getExtension(sharedfile);
471 variables["[distance]"] = lookup[0]->getLabel();
472 string outputFileName = getOutputFileName("shared", variables);
474 m->openOutputFile(outputFileName, out);
475 outputTypes["shared"].push_back(outputFileName); outputNames.push_back(outputFileName);
477 for (int j = 0; j < lookup.size(); j++) { delete lookup[j]; }
479 m->currentBinLabels = newLabels;
481 newLookup[0]->printHeaders(out);
483 for (int i = 0; i < newLookup.size(); i++) {
484 out << newLookup[i]->getLabel() << '\t' << newLookup[i]->getGroup() << '\t';
485 newLookup[i]->print(out);
489 for (int j = 0; j < newLookup.size(); j++) { delete newLookup[j]; }
491 if (wroteSomething == false) { m->mothurOut("Your file contains only OTUs from the .accnos file."); m->mothurOutEndLine(); }
493 m->mothurOut("Removed " + toString(numRemoved) + " OTUs from your shared file."); m->mothurOutEndLine();
497 catch(exception& e) {
498 m->errorOut(e, "RemoveOtuLabelsCommand", "readShared");
502 //**********************************************************************************************************************
503 int RemoveOtuLabelsCommand::readList(){
507 if (m->control_pressed) { delete list; return 0;}
510 newList.setLabel(list->getLabel());
511 int removedCount = 0;
512 bool wroteSomething = false;
513 string snumBins = toString(list->getNumBins());
515 for (int i = 0; i < list->getNumBins(); i++) {
517 if (m->control_pressed) { delete list; return 0;}
519 //create a label for this otu
520 string otuLabel = "Otu";
521 string sbinNumber = toString(i+1);
522 if (sbinNumber.length() < snumBins.length()) {
523 int diff = snumBins.length() - sbinNumber.length();
524 for (int h = 0; h < diff; h++) { otuLabel += "0"; }
526 otuLabel += sbinNumber;
528 if (labels.count(otuLabel) == 0) {
529 newList.push_back(list->get(i));
530 }else { removedCount++; }
533 string thisOutputDir = outputDir;
534 if (outputDir == "") { thisOutputDir += m->hasPath(listfile); }
535 map<string, string> variables;
536 variables["[filename]"] = thisOutputDir + m->getRootName(m->getSimpleName(listfile));
537 variables["[extension]"] = m->getExtension(listfile);
538 variables["[distance]"] = list->getLabel();
539 string outputFileName = getOutputFileName("list", variables);
541 m->openOutputFile(outputFileName, out);
544 //print new listvector
545 if (newList.getNumBins() != 0) {
546 wroteSomething = true;
551 if (wroteSomething == false) { m->mothurOut("Your file contains only OTUs from the .accnos file."); m->mothurOutEndLine(); }
552 outputNames.push_back(outputFileName); outputTypes["list"].push_back(outputFileName);
554 m->mothurOut("Removed " + toString(removedCount) + " OTUs from your list file."); m->mothurOutEndLine();
558 catch(exception& e) {
559 m->errorOut(e, "RemoveOtuLabelsCommand", "readList");
563 //**********************************************************************************************************************
564 int RemoveOtuLabelsCommand::getListVector(){
566 InputData input(listfile, "list");
567 list = input.getListVector();
568 string lastLabel = list->getLabel();
570 if (label == "") { label = lastLabel; return 0; }
572 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
573 set<string> labels; labels.insert(label);
574 set<string> processedLabels;
575 set<string> userLabels = labels;
577 //as long as you are not at the end of the file or done wih the lines you want
578 while((list != NULL) && (userLabels.size() != 0)) {
579 if (m->control_pressed) { return 0; }
581 if(labels.count(list->getLabel()) == 1){
582 processedLabels.insert(list->getLabel());
583 userLabels.erase(list->getLabel());
587 if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
588 string saveLabel = list->getLabel();
591 list = input.getListVector(lastLabel);
593 processedLabels.insert(list->getLabel());
594 userLabels.erase(list->getLabel());
596 //restore real lastlabel to save below
597 list->setLabel(saveLabel);
601 lastLabel = list->getLabel();
603 //get next line to process
604 //prevent memory leak
606 list = input.getListVector();
610 if (m->control_pressed) { return 0; }
612 //output error messages about any remaining user labels
613 set<string>::iterator it;
614 bool needToRun = false;
615 for (it = userLabels.begin(); it != userLabels.end(); it++) {
616 m->mothurOut("Your file does not include the label " + *it);
617 if (processedLabels.count(lastLabel) != 1) {
618 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
621 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
625 //run last label if you need to
626 if (needToRun == true) {
628 list = input.getListVector(lastLabel);
633 catch(exception& e) {
634 m->errorOut(e, "RemoveOtuLabelsCommand", "getListVector");
638 //**********************************************************************************************************************
639 int RemoveOtuLabelsCommand::getShared(){
641 InputData input(sharedfile, "sharedfile");
642 lookup = input.getSharedRAbundVectors();
643 string lastLabel = lookup[0]->getLabel();
645 if (label == "") { label = lastLabel; return 0; }
647 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
648 set<string> labels; labels.insert(label);
649 set<string> processedLabels;
650 set<string> userLabels = labels;
652 //as long as you are not at the end of the file or done wih the lines you want
653 while((lookup[0] != NULL) && (userLabels.size() != 0)) {
654 if (m->control_pressed) { return 0; }
656 if(labels.count(lookup[0]->getLabel()) == 1){
657 processedLabels.insert(lookup[0]->getLabel());
658 userLabels.erase(lookup[0]->getLabel());
662 if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
663 string saveLabel = lookup[0]->getLabel();
665 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
666 lookup = input.getSharedRAbundVectors(lastLabel);
668 processedLabels.insert(lookup[0]->getLabel());
669 userLabels.erase(lookup[0]->getLabel());
671 //restore real lastlabel to save below
672 lookup[0]->setLabel(saveLabel);
676 lastLabel = lookup[0]->getLabel();
678 //get next line to process
679 //prevent memory leak
680 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
681 lookup = input.getSharedRAbundVectors();
685 if (m->control_pressed) { return 0; }
687 //output error messages about any remaining user labels
688 set<string>::iterator it;
689 bool needToRun = false;
690 for (it = userLabels.begin(); it != userLabels.end(); it++) {
691 m->mothurOut("Your file does not include the label " + *it);
692 if (processedLabels.count(lastLabel) != 1) {
693 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
696 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
700 //run last label if you need to
701 if (needToRun == true) {
702 for (int i = 0; i < lookup.size(); i++) { if (lookup[i] != NULL) { delete lookup[i]; } }
703 lookup = input.getSharedRAbundVectors(lastLabel);
708 catch(exception& e) {
709 m->errorOut(e, "RemoveOtuLabelsCommand", "getShared");
713 //**********************************************************************************************************************