All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nextflow.extension.MixOp.groovy Maven / Gradle / Ivy

Go to download

A DSL modelled around the UNIX pipe concept, that simplifies writing parallel and scalable pipelines in a portable manner

There is a newer version: 24.11.0-edge
Show newest version
/*
 * Copyright 2013-2024, Seqera Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package nextflow.extension

import static nextflow.extension.DataflowHelper.*

import java.util.concurrent.atomic.AtomicInteger

import groovy.transform.CompileStatic
import groovyx.gpars.dataflow.DataflowReadChannel
import groovyx.gpars.dataflow.DataflowWriteChannel
import nextflow.Channel

/**
 * Implements Nextflow Mix operator
 *
 * @author Paolo Di Tommaso 
 */
@CompileStatic
class MixOp {

    private DataflowReadChannel source
    private List others
    private DataflowWriteChannel target

    MixOp(DataflowReadChannel source, DataflowReadChannel other) {
        this.source = source
        this.others = List.of(other)
    }

    MixOp(DataflowReadChannel source, DataflowReadChannel[] others) {
        this.source = source
        this.others = others.toList()
    }

    MixOp(List channels) {
        if( channels.size()<2 )
            throw new IllegalArgumentException("Mix operator requires at least 2 source channels")
        this.source = channels.get(0)
        this.others = channels.subList(1, channels.size())
    }

    MixOp withTarget(DataflowWriteChannel target) {
        this.target = target
        return this
    }

    DataflowWriteChannel apply() {
        if( target == null )
            target = CH.create()
        def count = new AtomicInteger( others.size()+1 )
        def handlers = [
                onNext: { target << it },
                onComplete: { if(count.decrementAndGet()==0) { target << Channel.STOP } }
        ]

        subscribeImpl(source, handlers)
        for( def it : others ) {
            subscribeImpl(it, handlers)
        }

        final allSources = [source]
        allSources.addAll(others)
        return target
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy