def customRandConvFactory(
        poolings=[(3, 3, Const.POOLING_AGGREG_AVG)],
        nbSubwindows=10,
        subwindowMinSizeRatio=0.5, subwindowMaxSizeRatio=1.,
        subwindowTargetWidth=16, subwindowTargetHeight=16,
        subwindowInterpolation=SubWindowExtractor.INTERPOLATION_BILINEAR,
        includeOriginalImage=False,
        nbJobs=-1, verbosity=10, tempFolder=None,
        random=True):
    """
    Factory method to create :class:`RandConvCoordinator` tuned for RGB images
    using predefined well-known filters

    Parameters
    ----------
    poolings : iterable of triple (height, width, policy) (default :
    [(3, 3, Const.POOLING_AGGREG_AVG)])
        A list of parameters to instanciate the according :class:`Pooler`
        height : int > 0
            the height of the neighborhood window
        width : int > 0
            the width of the neighborhood window
        policy : int in {Const.POOLING_NONE, Const.POOLING_AGGREG_MIN,
    Const.POOLING_AGGREG_AVG, Const.POOLING_AGGREG_MAX,
    Const.POOLING_CONV_MIN, Const.POOLING_CONV_AVG, Const.POOLING_CONV_MAX}

    nbSubwindows : int >= 0 (default : 10)
        The number of subwindow to extract
    subwindowMinSizeRatio : float > 0 (default : 0.5)
        The minimum size of a subwindow expressed as the ratio of the size
        of the original image
    subwindowMaxSizeRatio : float : subwindowMinSizeRatio
    <= subwindowMaxSizeRatio <= 1 (default : 1.)
        The maximim size of a subwindow expressed as the ratio of the size
        of the original image
    subwindowTargetWidth : int > 0 (default : 16)
        The width of the subwindows after reinterpolation
    subwindowTargetHeight : int > 0 (default : 16)
        The height of the subwindows after reinterpolation
    subwindowInterpolation : int (default :
    SubWindowExtractor.INTERPOLATION_BILINEAR)
        The subwindow reinterpolation algorithm. For more information, see
        :class:`SubWindowExtractor`

    includeOriginalImage : boolean (default : False)
        Whether or not to include the original image in the subwindow
        extraction process

    nbJobs : int >0 or -1 (default : -1)
        The number of process to spawn for parallelizing the computation.
        If -1, the maximum number is selected. See also :mod:`Joblib`.
    verbosity : int >= 0 (default : 10)
        The verbosity level
    tempFolder : string (directory path) (default : None)
            The temporary folder used for memmap. If none, some default folder
            will be use (see the :class:`ParallelCoordinator`)

    random : bool (default : True)
        Whether to use randomness or use a predefined seed

    Return
    ------
        coordinator : :class:`Coordinator`
            The RandConvCoordinator corresponding to the
            set of parameters

    Notes
    -----
    - Convolver
        Base instance of :class:`RGBConvolver`
    - Subwindow random generator
        The subwindow random generator is a :class:`NumberGenerator` base
        instance (generate real nubers uniformly).
    - Feature extractor
        Base instance of :class:`ImageLinearizationExtractor`
    """
    #RANDOMNESS
    swngSeed = 0
    if random is None:
        swngSeed = None

    #CONVOLUTIONAL EXTRACTOR
    filterGenerator = customFinite3sameFilter()

    #Convolver
    convolver = RGBConvolver()

    #Aggregator
    poolers = []
    for height, width, policy in poolings:
        if policy == Const.POOLING_NONE:
            poolers.append(IdentityPooler())
        elif policy == Const.POOLING_AGGREG_AVG:
            poolers.append(AverageAggregator(width, height,
                                             subwindowTargetWidth,
                                             subwindowTargetHeight))
        elif policy == Const.POOLING_AGGREG_MAX:
            poolers.append(MaximumAggregator(width, height,
                                             subwindowTargetWidth,
                                             subwindowTargetHeight))
        elif policy == Const.POOLING_AGGREG_MIN:
            poolers.append(MinimumAggregator(width, height,
                                             subwindowTargetWidth,
                                             subwindowTargetHeight))
        elif policy == Const.POOLING_CONV_MIN:
            poolers.append(ConvMinPooler(height, width))
        elif policy == Const.POOLING_CONV_AVG:
            poolers.append(ConvAvgPooler(height, width))
        elif policy == Const.POOLING_CONV_MAX:
            poolers.append(ConvMaxPooler(height, width))

    multiPooler = getMultiPoolers(subwindowTargetHeight, subwindowTargetWidth)

    #SubWindowExtractor
    swNumGenerator = NumberGenerator(seed=swngSeed)
    swExtractor = SubWindowExtractor(subwindowMinSizeRatio,
                                     subwindowMaxSizeRatio,
                                     subwindowTargetWidth,
                                     subwindowTargetHeight,
                                     subwindowInterpolation, swNumGenerator)

    multiSWExtractor = MultiSWExtractor(swExtractor, nbSubwindows, False)

    #ConvolutionalExtractor
    convolutionalExtractor = ConvolutionalExtractor(filterGenerator,
                                                    convolver,
                                                    multiSWExtractor,
                                                    multiPooler,
                                                    includeOriginalImage)
    #FEATURE EXTRACTOR
    featureExtractor = ImageLinearizationExtractor()

    #LOGGER
    autoFlush = verbosity >= 45
    logger = ProgressLogger(StandardLogger(autoFlush=autoFlush,
                                           verbosity=verbosity))
    #COORDINATOR
    coordinator = RandConvCoordinator(convolutionalExtractor, featureExtractor,
                                      logger, verbosity)

    if nbJobs != 1:
        coordinator.parallelize(nbJobs, tempFolder)
    return coordinator
def getFilterGenerator(policy, parameters, nbFilters, random=False):
    if policy == Const.FGEN_ORDERED:
        #Parameters is a list of tuples (policy, parameters)
        ls = []
        subNbFilters = int(math.ceil(nbFilters/len(parameters)))

        for subPolicy, subParameters in parameters:
            ls.append(getFilterGenerator(subPolicy, subParameters,
                                         subNbFilters, random))
        return OrderedMFF(ls, nbFilters)

    if policy is Const.FGEN_CUSTOM:
        print "Custom filters"
        return customFinite3sameFilter()

    #Parameters is a dictionary
    valSeed = None
    sizeSeed = None
    shufflingSeed = None
    perturbationSeed = None
    cellSeed = None
    sparseSeed = 5
    if random:
        valSeed = 1
        sizeSeed = 2
        shufflingSeed = 3
        perturbationSeed = 4
        cellSeed = 5
        sparseSeed = 6

    minSize = parameters["minSize"]
    maxSize = parameters["maxSize"]
    sizeGenerator = OddUniformGenerator(minSize, maxSize, seed=sizeSeed)

    minVal = parameters["minVal"]
    maxVal = parameters["maxVal"]
    valGen = parameters["valGen"]
    valGenerator = getNumberGenerator(valGen, minVal, maxVal,
                                      valSeed, **parameters)

    normalization = None
    if "normalization" in parameters:
        normalization = parameters["normalization"]

    if policy is Const.FGEN_ZEROPERT:
        print "Zero perturbation filters"
        baseFilterGenerator = FilterGenerator(valGenerator, sizeGenerator,
                                              normalisation=normalization)

    elif policy is Const.FGEN_IDPERT:
        print "Id perturbation filters"
        baseFilterGenerator = IdPerturbatedFG(valGenerator, sizeGenerator,
                                              normalisation=normalization)
    elif policy is Const.FGEN_IDDIST:
        print "Id distance filters"
        maxDist = parameters["maxDist"]
        baseFilterGenerator = IdMaxL1DistPerturbFG(valGenerator, sizeGenerator,
                                                   maxDist,
                                                   normalisation=normalization,
                                                   shufflingSeed=shufflingSeed)
    elif policy is Const.FGEN_STRAT:
        print "Stratified filters"
        nbCells = parameters["strat_nbCells"]
        minPerturbation = 0
        if "minPerturbation" in parameters:
            minPerturbation = parameters["minPerturbation"]
        maxPerturbation = 1
        if "maxPerturbation" in parameters:
            maxPerturbation = parameters["maxPerturbation"]
        perturbationGenerator = getNumberGenerator(valGen,
                                                   minPerturbation,
                                                   maxPerturbation,
                                                   perturbationSeed)
        baseFilterGenerator = StratifiedFG(minVal, maxVal, nbCells,
                                           perturbationGenerator,
                                           sizeGenerator,
                                           normalisation=normalization,
                                           cellSeed=cellSeed)

    if "sparseProb" in parameters:
        print "Adding sparcity"
        sparseProb = parameters["sparseProb"]
        baseFilterGenerator = SparsityDecoratorFG(baseFilterGenerator,
                                                  sparseProb,
                                                  sparseSeed)

    print "Returning filters"
    return Finite3SameFilter(baseFilterGenerator, nbFilters)