コード例 #1
0
void ConservationPlotWorkerFactory::init() {
    //init data path
    U2DataPath* dataPath = NULL;
    U2DataPathRegistry* dpr =  AppContext::getDataPathRegistry();
    if (dpr){
        U2DataPath* dp = dpr->getDataPathByName(CONSERVATION_DATA_NAME);
        if (dp && dp->isValid()){
            dataPath = dp;
        }
    }

    QList<PortDescriptor*> portDescs;

    //in port
    QMap<Descriptor, DataTypePtr> inTypeMap;
    Descriptor treatDesc(ANNOT_SLOT_ID,
        ConservationPlotWorker::tr("Input regions"),
        ConservationPlotWorker::tr("Regions (centered at peak summits for better performance)."));
    inTypeMap[treatDesc] = BaseTypes::ANNOTATION_TABLE_LIST_TYPE();

    Descriptor inPortDesc(IN_PORT_DESCR,
        ConservationPlotWorker::tr("conservation_plot data"),
        ConservationPlotWorker::tr("Regions to plot the PhastCons scores profiles."));

    DataTypePtr inTypeSet(new MapDataType(IN_TYPE_ID, inTypeMap));
    portDescs << new PortDescriptor(inPortDesc, inTypeSet, true);

    QList<Attribute*> attrs;
    {
         Descriptor outFile(OUTPUT_FILE,
             ConservationPlotWorker::tr("Output file"),
             ConservationPlotWorker::tr("File to store phastcons results (BMP)."));
         Descriptor titleDescr(TITLE,
             ConservationPlotWorker::tr("Title"),
             ConservationPlotWorker::tr("Title of the figure (--title)."));
         Descriptor labelDescr(LABEL,
             ConservationPlotWorker::tr("Label"),
             ConservationPlotWorker::tr("Label of data in the figure (--bed-label)."));
         Descriptor assemblyVersion(ASSEMBLY_VER,
             ConservationPlotWorker::tr("Assembly version"),
             ConservationPlotWorker::tr("The directory to store phastcons scores (--phasdb)."));
         Descriptor windowSizeDescr(WINDOW_S,
             ConservationPlotWorker::tr("Window width"),
             ConservationPlotWorker::tr("Window width centered at middle of regions (-w)."));
         Descriptor heightDescr(HEIGHT,
             ConservationPlotWorker::tr("Height"),
             ConservationPlotWorker::tr("Height of plot (--height)."));
         Descriptor widthDescr(WIDTH,
             ConservationPlotWorker::tr("Width"),
             ConservationPlotWorker::tr("Width of plot (--width)."));


        attrs << new Attribute(outFile, BaseTypes::STRING_TYPE(), true, QVariant(""));
        attrs << new Attribute(titleDescr, BaseTypes::STRING_TYPE(), true, QVariant("Average Phastcons around the Center of Sites"));
        attrs << new Attribute(labelDescr, BaseTypes::STRING_TYPE(), true, QVariant("Conservation_at_peak_summits"));
        Attribute* assemblyVerAttr = NULL;
        if (dataPath){
            const QList<QString>& dataNames = dataPath->getDataNames();
            if (!dataNames.isEmpty()){
                assemblyVerAttr = new Attribute(assemblyVersion, BaseTypes::STRING_TYPE(), true, dataPath->getPathByName(dataNames.first()));
            }else{
                assemblyVerAttr = new Attribute(assemblyVersion, BaseTypes::STRING_TYPE(), true);
            }
        }else{
            assemblyVerAttr = new Attribute(assemblyVersion, BaseTypes::STRING_TYPE(), true);
        }
        attrs << assemblyVerAttr;
        attrs << new Attribute(windowSizeDescr, BaseTypes::NUM_TYPE(), false, QVariant(1000));
        attrs << new Attribute(heightDescr, BaseTypes::NUM_TYPE(), false, QVariant(1000));
        attrs << new Attribute(widthDescr, BaseTypes::NUM_TYPE(), false, QVariant(1000));
    }

    QMap<QString, PropertyDelegate*> delegates;
    {
          delegates[OUTPUT_FILE] = new URLDelegate(DialogUtils::prepareFileFilter(ConservationPlotWorker::tr("Conservation plot file"), QStringList("bmp"), true), "", false, false);
         {
            QVariantMap vm;
            vm["minimum"] = QVariant(0);
            vm["maximum"] = INT_MAX;
            vm["singleStep"] = QVariant(1000);

            delegates[WINDOW_S] = new SpinBoxDelegate(vm);
            delegates[HEIGHT] = new SpinBoxDelegate(vm);
            delegates[WIDTH] = new SpinBoxDelegate(vm);
         }

         {
             QVariantMap vm;
             if (dataPath){
                 vm = dataPath->getDataItemsVariantMap();
             }
             delegates[ASSEMBLY_VER] = new ConservationPlotComboBoxWithUrlsDelegate(vm, true);
         }
    }

    Descriptor protoDesc(ConservationPlotWorkerFactory::ACTOR_ID,
    ConservationPlotWorker::tr("Build Conservation Plot"),
    ConservationPlotWorker::tr("Plots the PhastCons scores profiles."));

    ActorPrototype *proto = new IntegralBusActorPrototype(protoDesc, portDescs, attrs);
    proto->setPrompter(new ConservationPlotPrompter());
    proto->setEditor(new DelegateEditor(delegates));
    proto->addExternalTool(ET_CONSERVATION_PLOT);
    WorkflowEnv::getProtoRegistry()->registerProto(BaseActorCategories::CATEGORY_CHIP_SEQ(), proto);
    WorkflowEnv::getDomainRegistry()->getById(LocalDomainFactory::ID)->registerEntry(new ConservationPlotWorkerFactory());
}
コード例 #2
0
void KrakenBuildWorkerFactory::init() {
    QList<PortDescriptor *> ports;
    {
        const Descriptor outSlotDesc(BaseSlots::URL_SLOT().getId(), KrakenBuildPrompter::tr("Output URL"), KrakenBuildPrompter::tr("Output URL."));

        QMap<Descriptor, DataTypePtr> outType;
        outType[outSlotDesc] = BaseTypes::STRING_TYPE();

        const Descriptor outPortDesc(OUTPUT_PORT_ID, KrakenBuildPrompter::tr("Output Kraken database"), KrakenBuildPrompter::tr("URL to the folder with the Kraken database."));
        ports << new PortDescriptor(outPortDesc, DataTypePtr(new MapDataType(ACTOR_ID + "-out", outType)), false /*input*/, true /*multi*/);
    }

    QList<Attribute *> attributes;
    {
        const Descriptor modeDesc(MODE_ATTR_ID, KrakenBuildPrompter::tr("Mode"),
                                  KrakenBuildPrompter::tr("Select \"Build\" to create a new database from a genomic library (--build).<br><br>"
                                                          "Select \"Shrink\" to shrink an existing database to have only specified number of k-mers (--shrink)."));

        const Descriptor inputDatabaseNameDesc(INPUT_DATABASE_NAME_ATTR_ID, KrakenBuildPrompter::tr("Input database"),
                                               KrakenBuildPrompter::tr("Name of the input database that should be shrunk (corresponds to --db that is used with --shrink)."));

        const Descriptor newDatabaseNameDesc(NEW_DATABASE_NAME_ATTR_ID, KrakenBuildPrompter::tr("Database"),
                                             KrakenBuildPrompter::tr("Name of the output Kraken database (corresponds to --db that is used with --build, and to --new-db that is used with --shrink)."));

        const Descriptor genomicLibraryDesc(GENOMIC_LIBRARY_ATTR_ID, KrakenBuildPrompter::tr("Genomic library"),
                                            KrakenBuildPrompter::tr("Genomes that should be used to build the database.<br><br>"
                                                                    "The genomes should be specified in FASTA format. The sequence IDs must contain either a GI number or a taxonomy ID (see documentation for details)."));

        const Descriptor numberOfKmersDesc(NUMBER_OF_K_MERS_ATTR_ID, KrakenBuildPrompter::tr("Number of k-mers"),
                                           KrakenBuildPrompter::tr("The new database will contain the specified number of k-mers selected from across the input database."));

        const Descriptor kMerLengthDesc(K_MER_LENGTH_ATTR_ID, KrakenBuildPrompter::tr("K-mer length"),
                                        KrakenBuildPrompter::tr("K-mer length in bp (--kmer-len)."));

        const Descriptor minimizerLengthDesc(MINIMIZER_LENGTH_ATTR_ID, KrakenBuildPrompter::tr("Minimizer length"),
                                             KrakenBuildPrompter::tr("Minimizer length in bp (--minimizer-len).<br><br>"
                                                                     "The minimizers serve to keep k-mers that are adjacent in query sequences close to each other in the database, which allows Kraken to exploit the CPU cache.<br><br>"
                                                                     "Changing the value of the parameter can significantly affect the speed of Kraken, and neither increasing nor decreasing of the value will guarantee faster or slower speed."));

        const Descriptor maximumDatabaseSizeDesc(MAXIMUM_DATABASE_SIZE_ATTR_ID, KrakenBuildPrompter::tr("Maximum database size"),
                                                 KrakenBuildPrompter::tr("By default, a full database build is done.<br><br>"
                                                                         "To shrink the database before the full build, input the size of the database in Mb "
                                                                         "(this corresponds to the --max-db-size parameter, but Mb is used instead of Gb). "
                                                                         "The size is specified together for the database and the index."));

        const Descriptor shrinkBlockOffsetDesc(SHRINK_BLOCK_OFFSET_ATTR_ID, KrakenBuildPrompter::tr("Shrink block offset"),
                                               KrakenBuildPrompter::tr("When shrinking, select the k-mer that is NUM positions from the end of a block of k-mers (--shrink-block-offset)."));

        const Descriptor cleanDesc(CLEAN_ATTR_ID, KrakenBuildPrompter::tr("Clean"),
                                   KrakenBuildPrompter::tr("Remove unneeded files from a built database to reduce the disk usage (--clean)."));

        const Descriptor workOnDiskDesc(WORK_ON_DISK_ATTR_ID, KrakenBuildPrompter::tr("Work on disk"),
                                        KrakenBuildPrompter::tr("Perform most operations on disk rather than in RAM (this will slow down build in most cases)."));

        const Descriptor jellyfishHashSizeDesc(JELLYFISH_HASH_SIZE_ATTR_ID, KrakenBuildPrompter::tr("Jellyfish hash size"),
                                               KrakenBuildPrompter::tr("The \"kraken-build\" tool uses the \"jellyfish\" tool. This parameter specifies the hash size for Jellyfish.<br><br>"
                                                                       "Supply a smaller hash size to Jellyfish, if you encounter problems with allocating enough memory during the build process (--jellyfish-hash-size).<br><br>"
                                                                       "By default, the parameter is not used."));

        const Descriptor threadNumberDesc(THREADS_NUMBER_ATTR_ID, KrakenBuildPrompter::tr("Number of threads"),
                                          KrakenBuildPrompter::tr("Use multiple threads (--threads)."));

        Attribute *modeAttribute = new Attribute(modeDesc, BaseTypes::STRING_TYPE(), false, KrakenBuildTaskSettings::BUILD);
        Attribute *inputDatabaseNameAttribute = new Attribute(inputDatabaseNameDesc, BaseTypes::STRING_TYPE(), true);
        Attribute *newDatabaseName = new Attribute(newDatabaseNameDesc, BaseTypes::STRING_TYPE(), true);
        Attribute *genomicLibraryAttribute = new Attribute(genomicLibraryDesc, BaseTypes::URL_DATASETS_TYPE(), true);
        Attribute *numberOfKmersAttribute = new Attribute(numberOfKmersDesc, BaseTypes::NUM_TYPE(), true, 10000);
        Attribute *kMerLengthAttribute = new Attribute(kMerLengthDesc, BaseTypes::NUM_TYPE(), false, 31);
        Attribute *minimizerLengthAttribute = new Attribute(minimizerLengthDesc, BaseTypes::NUM_TYPE(), false, 15);;
        Attribute *maximumDatabaseSizeAttribute = new Attribute(maximumDatabaseSizeDesc, BaseTypes::NUM_TYPE(), false, 0);
        Attribute *shrinkBlockOffsetAttribute = new Attribute(shrinkBlockOffsetDesc, BaseTypes::NUM_TYPE(), false, 1);
        Attribute *cleanAttribute = new Attribute(cleanDesc, BaseTypes::BOOL_TYPE(), false, true);
        Attribute *workOnDiskAttribute = new Attribute(workOnDiskDesc, BaseTypes::BOOL_TYPE(), false, false);
        Attribute *jellyfishHashSizeAttribute = new Attribute(jellyfishHashSizeDesc, BaseTypes::NUM_TYPE(), false, 0);
        Attribute *threadNumberAttribute = new Attribute(threadNumberDesc, BaseTypes::NUM_TYPE(), false, AppContext::getAppSettings()->getAppResourcePool()->getIdealThreadCount());

        attributes << modeAttribute;
        attributes << inputDatabaseNameAttribute;
        attributes << newDatabaseName;
        attributes << genomicLibraryAttribute;
        attributes << numberOfKmersAttribute;
        attributes << kMerLengthAttribute;
        attributes << minimizerLengthAttribute;
        attributes << maximumDatabaseSizeAttribute;
        attributes << shrinkBlockOffsetAttribute;
        attributes << cleanAttribute;
        attributes << workOnDiskAttribute;
        attributes << jellyfishHashSizeAttribute;
        attributes << threadNumberAttribute;

        inputDatabaseNameAttribute->addRelation(new VisibilityRelation(MODE_ATTR_ID, KrakenBuildTaskSettings::SHRINK));
        genomicLibraryAttribute->addRelation(new VisibilityRelation(MODE_ATTR_ID, KrakenBuildTaskSettings::BUILD));
        numberOfKmersAttribute->addRelation(new VisibilityRelation(MODE_ATTR_ID, KrakenBuildTaskSettings::SHRINK));
        maximumDatabaseSizeAttribute->addRelation(new VisibilityRelation(MODE_ATTR_ID, KrakenBuildTaskSettings::BUILD));
        shrinkBlockOffsetAttribute->addRelation(new VisibilityRelation(MODE_ATTR_ID, KrakenBuildTaskSettings::SHRINK));
        cleanAttribute->addRelation(new VisibilityRelation(MODE_ATTR_ID, KrakenBuildTaskSettings::BUILD));
        jellyfishHashSizeAttribute->addRelation(new VisibilityRelation(MODE_ATTR_ID, KrakenBuildTaskSettings::BUILD));
    }

    QMap<QString, PropertyDelegate *> delegates;
    {
        QVariantMap modeValues;
        modeValues[KrakenSupport::tr("Build")] = KrakenBuildTaskSettings::BUILD;
        modeValues[KrakenSupport::tr("Shrink")] = KrakenBuildTaskSettings::SHRINK;
        delegates[MODE_ATTR_ID] = new ComboBoxDelegate(modeValues);
        delegates[INPUT_DATABASE_NAME_ATTR_ID] = new URLDelegate("", "kraken/database", false, true, false);

        const URLDelegate::Options options = URLDelegate::AllowSelectOnlyExistingDir |
                                             URLDelegate::SelectFileToSave |
                                             URLDelegate::DoNotUseWorkflowOutputFolder;
        delegates[NEW_DATABASE_NAME_ATTR_ID] = new URLDelegate("", "kraken/database", options);
        delegates[GENOMIC_LIBRARY_ATTR_ID] = new GenomicLibraryDelegate();

        QVariantMap numberOfKmersProperties;
        numberOfKmersProperties["minimum"] = 1;
        numberOfKmersProperties["maximum"] = std::numeric_limits<int>::max();
        numberOfKmersProperties["accelerated"] = true;
        delegates[NUMBER_OF_K_MERS_ATTR_ID] = new SpinBoxDelegate(numberOfKmersProperties);

        QVariantMap kMerLengthProperties;
        kMerLengthProperties["minimum"] = 3;
        kMerLengthProperties["maximum"] = 31;
        delegates[K_MER_LENGTH_ATTR_ID] = new SpinBoxDelegate(kMerLengthProperties);

        QVariantMap minimizerLengthProperties;
        minimizerLengthProperties["minimum"] = 1;
        minimizerLengthProperties["maximum"] = 30;
        delegates[MINIMIZER_LENGTH_ATTR_ID] = new SpinBoxDelegate(minimizerLengthProperties);

        QVariantMap maximumDatabaseSizeProperties;
        maximumDatabaseSizeProperties["minimum"] = 0;
        maximumDatabaseSizeProperties["maximum"] = std::numeric_limits<int>::max();
        maximumDatabaseSizeProperties["suffix"] = " Mb";
        maximumDatabaseSizeProperties["specialValueText"] = KrakenBuildPrompter::tr("No limit");
        maximumDatabaseSizeProperties["accelerated"] = true;
        delegates[MAXIMUM_DATABASE_SIZE_ATTR_ID] = new SpinBoxDelegate(maximumDatabaseSizeProperties);

        QVariantMap shrinkBlockOffsetProperties;
        shrinkBlockOffsetProperties["minimum"] = 1;
        shrinkBlockOffsetProperties["maximum"] = std::numeric_limits<int>::max();
        delegates[SHRINK_BLOCK_OFFSET_ATTR_ID] = new SpinBoxDelegate(shrinkBlockOffsetProperties);

        delegates[CLEAN_ATTR_ID] = new ComboBoxWithBoolsDelegate();
        delegates[WORK_ON_DISK_ATTR_ID] = new ComboBoxWithBoolsDelegate();

        QVariantMap jelyfishHashSizeProperties;
        jelyfishHashSizeProperties["minimum"] = 0;
        jelyfishHashSizeProperties["maximum"] = std::numeric_limits<int>::max();
        jelyfishHashSizeProperties["suffix"] = " M";
        jelyfishHashSizeProperties["specialValueText"] = KrakenBuildPrompter::tr("Skip");
        delegates[JELLYFISH_HASH_SIZE_ATTR_ID] = new SpinBoxDelegate(jelyfishHashSizeProperties);

        QVariantMap threadsNumberProperties;
        threadsNumberProperties["minimum"] = 1;
        threadsNumberProperties["maximum"] = QThread::idealThreadCount();
        delegates[THREADS_NUMBER_ATTR_ID] = new SpinBoxDelegate(threadsNumberProperties);
    }

    const Descriptor desc(ACTOR_ID, KrakenBuildPrompter::tr("Build Kraken Database"),
                          KrakenBuildPrompter::tr("Build a Kraken database from a genomic library or shrink a Kraken database."));

    ActorPrototype *proto = new IntegralBusActorPrototype(desc, ports, attributes);
    proto->setEditor(new DelegateEditor(delegates));
    proto->setPrompter(new KrakenBuildPrompter(NULL));
    proto->addExternalTool(KrakenSupport::BUILD_TOOL);
    proto->setValidator(new KrakenBuildValidator());
    WorkflowEnv::getProtoRegistry()->registerProto(NgsReadsClassificationPlugin::WORKFLOW_ELEMENTS_GROUP, proto);

    DomainFactory *localDomain = WorkflowEnv::getDomainRegistry()->getById(LocalDomainFactory::ID);
    localDomain->registerEntry(new KrakenBuildWorkerFactory());
}
コード例 #3
0
void KrakenClassifyWorkerFactory::init() {
    QList<PortDescriptor *> ports;
    {
        const Descriptor inSlotDesc(INPUT_SLOT,
                                       KrakenClassifyPrompter::tr("Input URL 1"),
                                       KrakenClassifyPrompter::tr("Input URL 1."));

        const Descriptor inPairedSlotDesc(PAIRED_INPUT_SLOT,
                                          KrakenClassifyPrompter::tr("Input URL 2"),
                                          KrakenClassifyPrompter::tr("Input URL 2."));

        QMap<Descriptor, DataTypePtr> inType;
        inType[inSlotDesc] = BaseTypes::STRING_TYPE();
        inType[inPairedSlotDesc] = BaseTypes::STRING_TYPE();

        QMap<Descriptor, DataTypePtr> outType;
        outType[TaxonomySupport::TAXONOMY_CLASSIFICATION_SLOT()] = TaxonomySupport::TAXONOMY_CLASSIFICATION_TYPE();

        const Descriptor inPortDesc(INPUT_PORT_ID,
                                    KrakenClassifyPrompter::tr("Input sequences"),
                                    KrakenClassifyPrompter::tr("URL(s) to FASTQ or FASTA file(s) should be provided.\n\n"
                                                               "In case of SE reads or contigs use the \"Input URL 1\" slot only.\n\n"
                                                               "In case of PE reads input \"left\" reads to \"Input URL 1\", \"right\" reads to \"Input URL 2\".\n\n"
                                                               "See also the \"Input data\" parameter of the element."));
        const Descriptor outPortDesc(OUTPUT_PORT_ID, KrakenClassifyPrompter::tr("Kraken Classification"), KrakenClassifyPrompter::tr("A map of sequence names with the associated taxonomy IDs, classified by Kraken."));

        ports << new PortDescriptor(inPortDesc, DataTypePtr(new MapDataType(ACTOR_ID + "-in", inType)), true /*input*/);
        ports << new PortDescriptor(outPortDesc, DataTypePtr(new MapDataType(ACTOR_ID + "-out", outType)), false /*input*/, true /*multi*/);
    }

    QList<Attribute *> attributes;
    {
        const Descriptor inputDataDesc(INPUT_DATA_ATTR_ID, KrakenClassifyPrompter::tr("Input data"),
                                             KrakenClassifyPrompter::tr("To classify single-end (SE) reads or contigs, received by reads de novo assembly, set this parameter to \"SE reads or contigs\".<br><br>"
                                                                        "To classify paired-end (PE) reads, set the value to \"PE reads\".<br><br>"
                                                                        "One or two slots of the input port are used depending on the value of the parameter. Pass URL(s) to data to these slots.<br><br>"
                                                                        "The input files should be in FASTA or FASTQ formats."));

        const Descriptor databaseDesc(DATABASE_ATTR_ID, KrakenClassifyPrompter::tr("Database"),
                                      KrakenClassifyPrompter::tr("A path to the folder with the Kraken database files."));

        const Descriptor outputUrlDesc(OUTPUT_URL_ATTR_ID, KrakenClassifyPrompter::tr("Output file"),
                                       KrakenClassifyPrompter::tr("Specify the output file name."));

        const Descriptor quickOperationDesc(QUICK_OPERATION_ATTR_ID, KrakenClassifyPrompter::tr("Quick operation"),
                                            KrakenClassifyPrompter::tr("Stop classification of an input read after the certain number of hits.<br><br>"
                                                                       "The value can be specified in the \"Minimum number of hits\" parameter."));

        const Descriptor minHitsDesc(MIN_HITS_NUMBER_ATTR_ID, KrakenClassifyPrompter::tr("Minimum number of hits"),
                                     KrakenClassifyPrompter::tr("The number of hits that are required to declare an input sequence classified.<br><br>"
                                                                "This can be especially useful with custom databases when testing to see if sequences either do or do not belong to a particular genome."));

        const Descriptor threadsDesc(THREADS_NUMBER_ATTR_ID, KrakenClassifyPrompter::tr("Number of threads"),
                                     KrakenClassifyPrompter::tr("Use multiple threads (--threads)."));

        const Descriptor preloadDatabaseDesc(PRELOAD_DATABASE_ATTR_ID, KrakenClassifyPrompter::tr("Load database into memory"),
                                             KrakenClassifyPrompter::tr("Load the Kraken database into RAM (--preload).<br><br>"
                                                                        "This can be useful to improve the speed. The database size should be less than the RAM size.<br><br>"
                                                                        "The other option to improve the speed is to store the database on ramdisk. Set this parameter to \"False\" in this case."));

        const Descriptor classifyToolDesc(NgsReadsClassificationPlugin::WORKFLOW_CLASSIFY_TOOL_ID,
                                          WORKFLOW_CLASSIFY_TOOL_KRAKEN,
                                          "Classify tool. Hidden attribute");

        Attribute *inputDataAttribute = new Attribute(inputDataDesc, BaseTypes::STRING_TYPE(), false, KrakenClassifyTaskSettings::SINGLE_END);
        inputDataAttribute->addSlotRelation(new SlotRelationDescriptor(INPUT_PORT_ID, PAIRED_INPUT_SLOT, QVariantList() << KrakenClassifyTaskSettings::PAIRED_END));
        attributes << inputDataAttribute;

        QString minikrakenPath;
        U2DataPath *minikrakenDataPath = AppContext::getDataPathRegistry()->getDataPathByName(NgsReadsClassificationPlugin::MINIKRAKEN_4_GB_DATA_ID);
        if (NULL != minikrakenDataPath && minikrakenDataPath->isValid()) {
            minikrakenPath = minikrakenDataPath->getPathByName(NgsReadsClassificationPlugin::MINIKRAKEN_4_GB_ITEM_ID);
        }
        Attribute *databaseAttribute = new Attribute(databaseDesc, BaseTypes::STRING_TYPE(), Attribute::Required | Attribute::NeedValidateEncoding, minikrakenPath);
        attributes << databaseAttribute;

        attributes << new Attribute(quickOperationDesc, BaseTypes::BOOL_TYPE(), Attribute::None, false);

        Attribute *minHitsAttribute = new Attribute(minHitsDesc, BaseTypes::NUM_TYPE(), Attribute::None, 1);
        attributes << minHitsAttribute;

        attributes << new Attribute(preloadDatabaseDesc, BaseTypes::BOOL_TYPE(), Attribute::None, true);
        attributes << new Attribute(threadsDesc, BaseTypes::NUM_TYPE(), Attribute::None, AppContext::getAppSettings()->getAppResourcePool()->getIdealThreadCount());
        attributes << new Attribute(outputUrlDesc, BaseTypes::STRING_TYPE(), Attribute::Required | Attribute::NeedValidateEncoding | Attribute::CanBeEmpty);

        attributes << new Attribute(classifyToolDesc, BaseTypes::STRING_TYPE(),
                                    static_cast<Attribute::Flags>(Attribute::Hidden),
                                    WORKFLOW_CLASSIFY_TOOL_KRAKEN);

        minHitsAttribute->addRelation(new VisibilityRelation(QUICK_OPERATION_ATTR_ID, "true"));
        databaseAttribute->addRelation(new DatabaseSizeRelation(PRELOAD_DATABASE_ATTR_ID));
    }

    QMap<QString, PropertyDelegate *> delegates;
    {
        QVariantMap inputDataMap;
        inputDataMap[SINGLE_END_TEXT] = KrakenClassifyTaskSettings::SINGLE_END;
        inputDataMap[PAIRED_END_TEXT] = KrakenClassifyTaskSettings::PAIRED_END;
        delegates[INPUT_DATA_ATTR_ID] = new ComboBoxDelegate(inputDataMap);

        delegates[DATABASE_ATTR_ID] = new DatabaseDelegate(ACTOR_ID,
                                                           DATABASE_ATTR_ID,
                                                           NgsReadsClassificationPlugin::MINIKRAKEN_4_GB_DATA_ID,
                                                           NgsReadsClassificationPlugin::MINIKRAKEN_4_GB_ITEM_ID,
                                                           "kraken/database",
                                                           true);

        DelegateTags outputUrlTags;
        outputUrlTags.set(DelegateTags::PLACEHOLDER_TEXT, "Auto");
        outputUrlTags.set(DelegateTags::FILTER, DialogUtils::prepareDocumentsFileFilter(BaseDocumentFormats::PLAIN_TEXT, true, QStringList()));
        outputUrlTags.set(DelegateTags::FORMAT, BaseDocumentFormats::PLAIN_TEXT);
        delegates[OUTPUT_URL_ATTR_ID] = new URLDelegate(outputUrlTags, "kraken/output");

        delegates[QUICK_OPERATION_ATTR_ID] = new ComboBoxWithBoolsDelegate();

        QVariantMap threadsProperties;
        threadsProperties["minimum"] = 1;
        threadsProperties["maximum"] = QThread::idealThreadCount();
        delegates[THREADS_NUMBER_ATTR_ID] = new SpinBoxDelegate(threadsProperties);

        delegates[PRELOAD_DATABASE_ATTR_ID] = new ComboBoxWithBoolsDelegate();
    }

    const Descriptor desc(ACTOR_ID, KrakenClassifyPrompter::tr("Classify Sequences with Kraken"),
                          KrakenClassifyPrompter::tr("Kraken is a taxonomic sequence classifier that assigns taxonomic labels to short DNA reads. "
                                                     "It does this by examining the k-mers within a read and querying a database with those."));
    ActorPrototype *proto = new IntegralBusActorPrototype(desc, ports, attributes);
    proto->setEditor(new DelegateEditor(delegates));
    proto->setPrompter(new KrakenClassifyPrompter(NULL));
    proto->addExternalTool(KrakenSupport::CLASSIFY_TOOL);
    proto->setValidator(new KrakenClassifyValidator());
    proto->setPortValidator(INPUT_PORT_ID, new PairedReadsPortValidator(INPUT_SLOT, PAIRED_INPUT_SLOT));
    WorkflowEnv::getProtoRegistry()->registerProto(NgsReadsClassificationPlugin::WORKFLOW_ELEMENTS_GROUP, proto);

    DomainFactory *localDomain = WorkflowEnv::getDomainRegistry()->getById(LocalDomainFactory::ID);
    localDomain->registerEntry(new KrakenClassifyWorkerFactory());
}