Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement worker #5

Open
lpatiny opened this issue Oct 6, 2015 · 0 comments
Open

Implement worker #5

lpatiny opened this issue Oct 6, 2015 · 0 comments

Comments

@lpatiny
Copy link
Member

lpatiny commented Oct 6, 2015

We would need couple of methods methods

This could be done in the init script of the visualizer

var mfProcessor = new CCE.MFProcessorWorrker ({ -- options for max process --})

mfProcessor would be a new class

/* --------------------------------------------
// Beginning of the worker
-------------------------------------------------*/
require(['worker-manager'], function(WorkerManager) {
    function insideWorker() {
        var processor;
        worker.on('init', function(send, exp, options) {
            processor = new chemcalcExtended.MfProcessor(exp, options);
            send();
        });
        worker.on('data', function(send, data){
            send(processor.process(data));
        });
    }

    var manager = new WorkerManager(insideWorker, {
        deps: [require.toUrl('chemcalc-extended') + '.js']
    });
})


API.cache('MFprocessor', mfProcessor);

Methods available on mfProcessor

process(mfs, experimental, options)

options:

  • processing = function
init

var mfProcessor = API.cache('MFprocessor');
mfProcessor.init(experimental, calculationOptions);

// should return a promise

var manager=API.cache('MFprocessor');
manager.postAll('init', [experimental, calculationOptions]).then(
    function() {
        console.log('All workers responded to init');
    },
    function(e) {
        console.log('Workers init error: ',e);
    }
);

reset

// would kill all the running process and recreate the workers
API.cache('MFprocessor').reset()
;

Example of code in the visualizer

In the init script:

var mfProcessor = new CCE.MFProcessor ({ -- options for max process --})
API.cache('MFprocessor', mfProcessor);

In an executor:

setAsync();
var mfProcessor = API.cache('MFprocessor');

var options={};
options.progress=function(current, total) {
   API.doAction("incrementProgress");
}

mfProcessor.process(mfs, experimental, options).then(
    function(results) {
        API.createData("results",results);
        done();
    }
);

Current code in the code executor

The part 'in the worker' should be replaced by the new methods

// SAME CODE AS MF FROM MM (All elements)

var elements=API.getData("elementTable");


var options=API.getData("preferences");

var modification=options.modification;

var experimental=API.getData("experimental");
if (experimental) {
    experimental=experimental.get();
}


if (! elements) {
    return;
}

function getSymbol(element) {
    var symbol=element.symbol;
    if (! symbol.match(/^[A-Z][a-z]?$/)) {
        symbol="{"+symbol+"}";
    }
    return symbol;
}



var baseRange="("+modification+")";
for (var i=0; i<elements.length; i++) {
    var element=elements[i];
    if (element.many==true && element.min>=0 && element.max>0 && element.max>=element.min) {
        baseRange+=getSymbol(element);
        if (element.max!=element.min) {
            baseRange+=element.min+"-"+element.max;
        } else {
            baseRange+=element.min;
        }
        baseRange+=" ";
    }
}

// we will combine all the elements with all the one where only one is present
var resultsMM=getResult(baseRange, options.mass, options).results;
var start=Date.now();


for (var i=0; i<elements.length; i++) {
    var element=elements[i];
    if (element.one==true && element.min>=0 && element.max>0 && element.max>=element.min) {
        var symbol=getSymbol(element);
        if (element.min==0) {
            var range=symbol+"1-"+element.max;
        } else {
            var range=symbol+element.min+"-"+element.max;
        }
        resultsMM=resultsMM.concat(getResult(baseRange+range, options.mass, options).results);
    }
}

function getCalculationOptions(userOptions, mfRange, targetMass) {
    var options=JSON.parse(JSON.stringify(userOptions));
    options.mfRange=mfRange;
    options.typedResult=true;
    options.useUnsaturation=false;
    options.maxNumberRows=100;
    options.decimalsMass=4;
    options.decimalsPPM=3;
    options.gaussianWidth=0;
    options.addExperimentalExtract=true;
    options.bestOf=0;

    if (userOptions.resolution) {
        options.massRange=Math.min(0.5,targetMass/userOptions.resolution*4);
        options.fwhm=targetMass/userOptions.resolution;
    }
    return options;
}


function getResult(mfRange, targetMass) {
    var calculationOptions=getCalculationOptions(options, mfRange, targetMass);
    var result=CE.mfFromMonoisotopicMass(targetMass, calculationOptions);
    return result;
}

// we will create UNIQUE MF
var existingMF={};
var mfs=[];
var uniqueResults=[];
for (var i=0; i<resultsMM.length; i++) {
    var mf=resultsMM[i].mf.value;
    if (!existingMF[mf]) {
        uniqueResults.push(resultsMM[i]);
        existingMF[mf]=true;
        mfs.push({mf:mf});
    }
}

uniqueResults.sort(function (a,b) {
    return Math.abs(a.error)-Math.abs(b.error);
});

// we could already display the results ... and make the detailed analysis

// we add the abs ppm
uniqueResults=uniqueResults.map(function(a) {
    a.absppm=Math.abs(a.ppm*100)/100;
    return a;
})

API.createData("results",uniqueResults);

if (options.calculateSimilarity!=true || ! experimental) {
    return;
}

setAsync(); // we will do tehe calculations in workers


var results=[];
/* --------------------------------------------
// Beginning of the worker
-------------------------------------------------*/


var calculationOptions=getCalculationOptions(options);

var manager=API.cache('MFprocessor');
manager.postAll('init', [experimental, calculationOptions]).then(
    function() {
        console.log('All workers responded to init');
    },
    function(e) {
        console.log('Workers init error: ',e);
    }
);


API.createData("totalMFs", mfs.length);

var processedMFs=0;
mfs.forEach(function (mf) {
    manager.post('data', [mf.mf]).then(
        function(result) {
            addResult(mf, result);
        },
        function(error) {
            console.log(error);
        }
    ).then( // in all the cases we increment
        function() {
            processedMFs++;
            API.doAction("incrementProgress");
            if (processedMFs === mfs.length) { // finish
                finish();
            }
        }
    );
});



function addResult(mf, result) {
    results.push(result);
    result.parts = mf;
    if (results.length > options.maxResults * 2) {
        results = CE.bestResults(results, options.bestOf, options.maxResults, options.minSimilarity);
    }
}


function finish() {
    results = CE.bestResults(results, options.bestOf, options.maxResults, options.minSimilarity);
    results=results.map(function(a) {
        var ppm=((a.msem-options.mass)/(a.msem))*1e6;
        a.ppm=Math.round(ppm*100)/100;
        a.absppm=Math.abs(a.ppm*100)/100;
        return a;
    })

    API.createData("results",results);
    console.log("Calculation time: "+(Date.now()-start));
    done();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant