/**
 * @fileoverview
 * This script defines a service class for retrieving data from flyatlas.
 * @author <a href="http://purl.org/net/aliman">Alistair Miles</a> and Jun Zhao
 * @version $Revision:100 $ on $Date: 2009-11-17 10:10:41 +0100 (Tue, 17 Nov 2009) $ by $Author: zhaoj $
 * @requires flykit.util
 * @requires flykit.sparql.Service
 * @requires YAHOO.util.Connect
 * For license terms see http://code.google.com/p/open-biomed/
 */


flykit.namespace("flykit.flyatlas");




flykit.flyatlas.provenance = "retrieved on 2009-05-19";





/**
 * @class
 * @extends flykit.sparql.Service
 */
flykit.flyatlas.Service = function() {};


// extend
flykit.flyatlas.Service.prototype = new flykit.sparql.Service();


/**
 * @param {String} affyId
 * @param {Function} success callback will be passed an array of flykit.flyatlas.AssayGroup objects
 * @param {Function} failure callback will be passed a YUI failure case response object
 * @member flykit.flyatlas.Service
 * @throws flykit.UnexpectedException
 */
flykit.flyatlas.Service.prototype.getAssaysByAffyProbeId = function( affyId, success, failure ) {
    var _context = "flykit.flyatlas.Service.prototype.getAssaysByAffyProbeId";
    try {
        flykit.info("request: "+affyId, _context);
        var chain = flykit.chain(flykit.flyatlas.Service.responseToAssayGroups, success);
        var query = this._buildQueryForGetAssaysByProbeId(affyId);
        flykit.debug("query: "+query, _context);
        this.postQuery(query, chain, failure);
    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};


/**
 * @param {String} flybaseId
 * @param {Function} success callback will be passed an array of flykit.flyatlas.AssayGroup objects
 * @param {Function} failure callback will be passed a YUI failure case response object
 * @member flykit.flyatlas.Service
 */
flykit.flyatlas.Service.prototype.getAssaysByFlybaseGeneId = function( flybaseId, success, failure ) {
    var _context = "flykit.flyatlas.Service.prototype.getAssaysByFlybaseGeneId";
    try {
        flykit.info("request: "+flybaseId, _context);
        var chain = flykit.chain(flykit.flyatlas.Service.responseToAssayGroups, success);
        var query = this._buildQueryForGetAssaysByFlybaseGeneId(flybaseId);
        flykit.debug("query: "+query, _context);
        this.postQuery(query, chain, failure);
    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
}


/**
 * @param {Object} response a YUI success case response object
 * @type Array<flykit.flyatlas.AssayGroup>
 * @throws flykit.UnexpectedException
 * @static
 */
flykit.flyatlas.Service.responseToAssayGroups = function( response ) {   
    var _context = "flykit.flyatlas.Service.responseToAssayGroups";   
    try {
        flykit.debug("response status: "+response.status, _context); 
        flykit.debug("parsing response as json: "+response.responseText, _context);
        var resultSet = YAHOO.lang.JSON.parse(response.responseText);
        flykit.debug("convert result set to an array of genes", _context);
        var groups = flykit.flyatlas.AssayGroup.newInstancesFromResultSet(resultSet);
        return groups;
    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};


/**
 * @private
 * @param {String} query
 * @type String
 * @throws flykit.UnexpectedException
 */
flykit.flyatlas.Service.prototype._buildQueryForGetAssaysByProbeId = function( affyId ) {
    var _context = "flykit.flyatlas.Service.prototype._buildQueryForGetAssaysByProbeId";
    try {
        
        var head =          "PREFIX xs: <http://www.w3.org/2001/XMLSchema#> \n" + 
                            "PREFIX : <http://purl.org/NET/flyatlas/schema#> \n" +
                            "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> ";
                    
        var body_start =    "SELECT distinct *\n"+
                            //"FROM <http://purl.org/net/dataset/flyatlas-latest> " +
                            "WHERE { \n" +
                            "?affy_id rdfs:label \""+affyId+"\"@en  ; a :ProbeData ; \n" +
                            "  :fly_present ?whole_present ; \n" +
                            "  :fly_mean ?whole_mean ; \n" +
                            "  :fly_sem ?whole_sem ; \n" +
                            "  :testis_to_all ?testis_to_all ; \n";
    
        var body_end =      " . }";
        
        var query = head;
        query += body_start;
        
        body_temp = "?tissue [ \n " +
                        ":call ?tissue_change ; \n " + 
                        ":mean ?tissue_mean ; \n " + 
                        ":sem ?tissue_sem ; \n " + 
                        ":present ?tissue_present ; \n " + 
                        ":ratio ?tissue_ratio ; \n " +
                    "] \n";
        
        query += body_temp;
        query += body_end;
        flykit.debug("query: "+query, _context);
        return query;

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
}

/**
 * @private
 * @param {String} query
 * @type String
 * @throws flykit.UnexpectedException
 */
flykit.flyatlas.Service.prototype._buildQueryForGetAssaysByFlybaseGeneId = function( flybaseId ) {
    var _context = "flykit.flyatlas.Service.prototype._buildQueryForGetAssaysByFlybaseGeneId";
    try {
        var head =          "PREFIX xs: <http://www.w3.org/2001/XMLSchema#> \n" + 
                            "PREFIX : <http://purl.org/NET/flyatlas/schema#> \n" +
                            "PREFIX fb: <http://purl.org/net/open-biomed/id/flybase/feature/Drosophila_melanogaster/SO_0000704/> \n";
                    
        var body_start =    "SELECT distinct *\n"+ 
                            //"FROM <http://purl.org/net/dataset/flyatlas-latest> " +
                            "WHERE { \n" +
                            "?affy_id :gene fb:"+flybaseId+"; \n" +
                            "  a :ProbeData ; \n" +                            
                            "  :fly_present ?whole_present ; \n" +
                            "  :fly_mean ?whole_mean ; \n" +
                            "  :fly_sem ?whole_sem ; \n" +
                            "  :testis_to_all ?testis_to_all ; \n";
        var body_end =      " . }";
        
        var query = head;
        query += body_start;
        
        query_temp = "  ?tissue [ \n" + 
    						"    :call ?tissue_change ; \n" +
    						"    :mean ?tissue_mean ; \n" +
    						"    :sem ?tissue_sem ; \n" +
    						"    :present ?tissue_present ; \n" +
    						"    :ratio ?tissue_ratio ; \n" +
    						"    :to_testis ?tissue_testis_ratio \n" +
    						"  ]  \n";
        query += query_temp;
        query += body_end;
        return query;

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};







/**
 * @public
 */
flykit.flyatlas.Service.prototype.getAssaysByFlybaseGeneIdBatch = function( flybaseIDs, success, failure ) {
    var _context = "flykit.flyatlas.Service.prototype.getAssaysByFlybaseGeneIdBatch";
    try {
        
        flykit.info("request: "+flybaseIDs, _context);
        if (flybaseIDs.length == 0) {
            success({});
        }
        else {
            var map = {};
            for (var i=0; i<flybaseIDs.length; i++) {
                flykit.debug ("create map for key " + flybaseIDs[i]);
                map[flybaseIDs[i]] = [];
                //map[flybaseIDs[i]] = new Array();
                
            }
            var chain = flykit.chain(flykit.flyatlas.Service.transformResponseForGetAssaysByFlybaseGeneIdBatch(map), success);
            var query = this._buildQueryForGetAssaysByFlybaseGeneIdBatch(flybaseIDs);
            flykit.debug("query: "+query, _context);
            this.postQuery(query, chain, failure);        
        }
    } 
    catch (unexpected) {
        flykit.debug("rethrowing "+unexpected.name+", "+unexpected.message, _context);
        throw unexpected;    
    }    
};





 

/**
 * @private
 */
flykit.flyatlas.Service.prototype._buildQueryForGetAssaysByFlybaseGeneIdBatch = function( flybaseIDs ) {
    var _context = "flykit.flyatlas.Service.prototype._buildQueryForGetAssaysByFlybaseGeneIdBatch";
    try {
        
        var head =          "PREFIX xs: <http://www.w3.org/2001/XMLSchema#> \n" + 
                            "PREFIX : <http://purl.org/NET/flyatlas/schema#> \n" +
                            "PREFIX fb: <http://purl.org/net/open-biomed/id/flybase/feature/Drosophila_melanogaster/SO_0000704/> \n";
                    
        var body_start =    "SELECT distinct *\n"+ 
                            //"FROM <http://purl.org/net/dataset/flyatlas-latest> " +
                            "WHERE { \n";
        
        if (flybaseIDs.length==1) {
            var body_union = "{\n" +
                                  "?affy_id :gene fb:"+flybaseIDs[0]+" . \n" +
                             "}\n";
                                                              
        }else {
            
            var body_union = "{\n" +
                                 "{\n" +
                                      "?affy_id :gene fb:"+flybaseIDs[0]+" . \n" +
                                        
                                  "}\n";
             for (var i = 1; i < flybaseIDs.length; i ++) {
                 body_union += "union \n"+
                                 "{\n" +
                                      "?affy_id :gene fb:"+flybaseIDs[i]+" . \n" +
                                 "}\n";
             }                           
             body_union += "}\n";
            
        }
        
        function body () {
            var body_main = "{\n" +
                            "?affy_id \n" +
                            "  :gene ?gene ; \n" +
                            "  a :ProbeData ; \n" +                            
                            "  :fly_present ?whole_present ; \n" +
                            "  :fly_mean ?whole_mean ; \n" +
                            "  :fly_sem ?whole_sem  ;\n" +
                            "  :testis_to_all ?testis_to_all ; \n";
            
            body_main += "?tissue [ \n" + 
    						"    :call ?tissue_change ; \n" +
    						"    :mean ?tissue_mean ; \n" +
    						"    :sem ?tissue_sem ; \n" +
    						"    :present ?tissue_present ; \n" +
    						"    :ratio ?tissue_ratio ; \n" +
    						"    :to_testis ?tissue_testis_ratio \n" +
    						"  ]  }}\n";
            
            return body_main;
                        
        }
        
        
        var query = head + body_start+ body_union + body() ;
        
        flykit.debug("trace query " + query + _context);
        
        return query;
        
    } 
    catch (unexpected) {
        flykit.debug("rethrowing "+unexpected.name+", "+unexpected.message, _context);
        throw unexpected;    
    }
};







/**
 * @private
 */
flykit.flyatlas.Service.transformResponseForGetAssaysByFlybaseGeneIdBatch = function( map ) {
    var _context = "flykit.flyatlas.Service.transformResponseForGetAssaysByFlybaseGeneIdBatch";
    return function( response ) {
        try {
            
            flykit.debug("response status: "+response.status, _context);
            flykit.debug("try parsing response text as json", _context);
            flykit.debug("parsing response: "+response.responseText, _context);

            var resultSet = YAHOO.lang.JSON.parse(response.responseText);
            
            flykit.debug("convert result set to a map of names to assay groups", _context);
    
            var bindings = resultSet.results.bindings;
            
            var binding_group = new flykit.maputil.MapUtils();
            
            for (var i=0; i<bindings.length; i++) {
                
                var geneuri = bindings[i].gene.value;
                var flybaseID = geneuri.split("/")[geneuri.split("/").length-1];
                
                if (binding_group.get(flybaseID) != null){
                    var sub_bindings = binding_group.get(flybaseID);
                    sub_bindings[sub_bindings.length] = bindings[i];
                    binding_group.put(flybaseID, sub_bindings);
                }else {
                    var sub_bindings = [];
                    sub_bindings[sub_bindings.length] = bindings[i];
                    binding_group.put(flybaseID, sub_bindings);
                }
            }
            
            
           
            if (binding_group.size() > 0) {
                // the keys are flybaseIDs
                var keys = binding_group.keySet();
                for (var i = 0; i < keys.length; i ++){
                    
                    var key = keys[i];
                    // bindings for a given flybaseID
                    var perbindings = binding_group.get(key);
                    
                    var group = null;
                    // sort the bindings by affyIDs: map affyid to record
                    var affyIDs = new flykit.maputil.MapUtils();
                	for (var j=0; j<perbindings.length; j++) {
                		var binding = perbindings[j];
                		
                		var probeID = binding["affy_id"].value;
                		flykit.debug("trace affyid " + probeID, _context);
                		if (affyIDs.get(probeID) != null) {
                		    var bidnings = affyIDs.get(probeID);
                		    bindings[bindings.length] = binding;
                		    affyIDs.put(probeID, bindings);
                		} else {
                		    var bindings = [];
                		    bindings[bindings.length] = binding;
                		    affyIDs.put(probeID, bindings);
                		}
                	}
                	
                	if (affyIDs.size() > 0 ) {
                	    var affykeys = affyIDs.keySet();
                	    for (var k = 0; k < affykeys.length; k ++) {
                	         
                	        var affykey = affykeys[k];
                	        flykit.debug("trace affykey " + affykey, _context);
                	        var affyrecord = affyIDs.get(affykey);
                	        flykit.debug("trace affy record " + affyrecord.length, _context);
                	        group = flykit.flyatlas.AssayGroup.newInstanceFromBinding(affyrecord, affykey);
                	        flykit.debug("breaks here? " + key, _context);
                	        if (map[key]){
                	            var groups = map[key];
                                groups[groups.length] = group;
                            }
                	    }
                	}
                	flykit.debug("convert result set to a map of names to assay groups " + affyIDs.size(), _context);
                	
                    
                }
            }
                
            return map;
            
        } 
        catch (unexpected) {
            flykit.debug("rethrowing "+unexpected.name+", "+unexpected.message, _context);
            throw unexpected;    
        }
    };
};







/**
 * @class
 */
flykit.flyatlas.AssayGroup = function() {

    /**
     * @type String
     */
    this.affy_id = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.whole = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.brain = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.head = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.crop = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.midgut = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.hindgut = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.tubule = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.ovary = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.testis = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.acc = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.l_tubule = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.l_fatbody = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.ta_ganglion = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.carcass = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.sgland = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.l_sgland = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.l_midgut = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.l_hindgut = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.sptv = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.sptm = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.lncs = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.afb = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.lcar = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.eye = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.heart = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.lftrachea = null;
    
    /**
     * @type flykit.flyatlas.Assay
     */
    this.s2cells = null;
    
};


/**
 * @param {Object} resultSet
 * @type Array<flykit.flyatlas.AssayGroup>
 * @throws flykit.UnexpectedException
 */
flykit.flyatlas.AssayGroup.newInstancesFromResultSet = function( resultSet ) {
    var _context = "flykit.flyatlas.AssayGroup.newInstancesFromResultSet";
    try {
    	var groups = [];
    	var affyIDs = new flykit.maputil.MapUtils();
    	for (var i=0; i<resultSet.results.bindings.length; i++) {
    		var binding = resultSet.results.bindings[i];
    		
    		var probeID = binding["affy_id"].value;
    		
    		if (affyIDs.get(probeID) != null) {
    		    var bidnings = affyIDs.get(probeID);
    		    bindings[bindings.length] = binding;
    		    affyIDs.put(probeID, bindings);
    		} else {
    		    var bindings = [];
    		    bindings[bindings.length] = binding;
    		    affyIDs.put(probeID, bindings);
    		}
    	}
    	
    	
    	if (affyIDs.size() > 0 ) {
    	    var keys = affyIDs.keySet();
    	    for (var i = 0; i < keys.length; i ++) {
    	        groups[groups.length] = flykit.flyatlas.AssayGroup.newInstanceFromBinding(affyIDs.get(keys[i]), keys[i]);       
    	    }
    	}
    	
    	return groups;
        
    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};


/**
 * @param {Object} binding
 * @type flykit.flyatlas.AssayGroup
 * @throws flykit.UnexpectedException
 */
flykit.flyatlas.AssayGroup.newInstanceFromBinding = function( bindings, key ) {
    var _context = "flykit.flyatlas.AssayGroup.newInstanceFromBinding with tissue key";
    try {
        
    	var group = new flykit.flyatlas.AssayGroup();
    	
    	var affy_uri = key;
    	
    	group.affy_id = key.substring(63, key.length);
    	
    	flykit.debug("trace group affyid " + group.affy_id, _context);
    	
    	group["whole"] = flykit.flyatlas.Assay.newInstanceFromBinding(bindings[0], "whole");
    	
    	//group["testis"] = flykit.flyatlas.Assay.newInstanceFromBinding(bindings[0], "testis");
    	
    	for (var i =0; i < bindings.length; i ++) {
    	    var binding = bindings[i];
    	    var tissue_uri = binding["tissue"].value;
    	    
        	tissue = tissue_uri.split("/")[tissue_uri.split("/").length-1].split("#")[1];
        	
        	group[tissue] = flykit.flyatlas.Assay.newInstanceFromBinding(binding, tissue);
    	}
    	
        return group;	
    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};


/**
 * @class
 */
flykit.flyatlas.Assay = function() {

    /**
     * @type String
     */
    this.mean = null;
    
    /**
     * @type String
     */
    this.present = null;
    
    /**
     * @type String
     */
    this.sem = null;
    
    /**
     * @type String
     */
    this.change = null;
    
    /**
     * @type String
     */
    this.ratio = null;
    
    /**
     * @type String
     */
     
    this.pairwise = 0;
    
    /**
     * @type String
     */
     
    this.testis_ratio = 0;
    
};

/**
 * @param {Object} binding
 * @param {String} tissue
 * @type flykit.flyatlas.Assay
 * @static
 * @throws flykit.UnexpectedException
 */
flykit.flyatlas.Assay.newInstanceFromBinding = function( binding, tissue ) {
    var _context = "flykit.flyatlas.Assay.newInstanceFromBinding";
    try {
        flykit.debug("create assay for tissue " + tissue + " " + binding );
    	var assay = new flykit.flyatlas.Assay();
    	
    	var sharedProps = ["mean", "sem", "present"];
    	
    	// populate shared props
    	
    	if (tissue == "whole") {
    	     for (var i=0; i<sharedProps.length; i++) {
        		var p = sharedProps[i];
        		assay[p] = binding["whole_"+p].value;
        	}  
        	assay.pairwise = binding["testis_to_all"].value;
        	
    	}else {

        	for (var i=0; i<sharedProps.length; i++) {
        		var p = sharedProps[i];
        		assay[p] = binding["tissue_"+p].value;
        	}
        }
    
        var otherProps = ["ratio", "change"];
        
        if (tissue == "whole") {
        	// force prop values for whole fly
            assay.ratio = 1;
            assay.change = "None";  
        }
        else {
    	    for (var i=0; i<otherProps.length; i++) {
    	        var op = otherProps[i];
    	        if (binding["tissue_"+op]) {
    	            assay[op] = binding["tissue_"+op].value;
    	        }
    	    }
        }
        
        var pairwiseProps = ["testis_ratio"];
        
        if (tissue == "whole") {
        	// force prop values for whole fly
            assay.testis_ratio = 0;
        }
        else {
    	    for (var i=0; i<pairwiseProps.length; i++) {
    	        var op = pairwiseProps[i];
    	        if (binding["tissue_"+op]) {
    	            flykit.debug("the ratio value of "+ tissue + " :" + binding["tissue_"+op].value, _context);
    	            assay[op] = binding["tissue_"+op].value;
    	        }
    	    }
        }
    
        return assay;
    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};


/**
 * @type Array<String>
 */
flykit.flyatlas.tissues = [
    "whole",
    "brain",
    "head",
    "crop",
    "midgut",
    "hindgut",
    "tubule",
    "ovary",
    "testis",
    "acc",
    "l_tubule",
    "l_fatbody",
    "ta_ganglion",
    "carcass",
    "sgland",
    "l_sgland",
    "l_midgut",
    "l_hindgut",
    "sptv",
    "sptm",
    "lcns",
    "afb",
    "lcar",
    "eye",
    "heart",
    "lftrachea",
    "s2cells"
];








flykit.flyatlas.Service.prototype.getProbesAndGenesByExpressionProfile = function( profile, success, failure, limit ) {
    var _context = "flykit.flyatlas.Service.prototype.getProbesAndGenesByExpressionProfile";
    try {
        
        flykit.info("request: "+profile, _context);
        var chain = flykit.chain(flykit.flyatlas.Service.transformResponseForGetProbesAndGenesByExpressionProfile, success);
        var query = this._buildQueryForGetProbesAndGenesByExpressionProfile(profile, limit);
        flykit.debug("query: "+query, _context);
        this.postQuery(query, chain, failure);        

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};




flykit.flyatlas.Service.prototype.getProbesAndGenesByNumericalExpressionProfile = function( profile, success, failure, limit ) {
    var _context = "flykit.flyatlas.Service.prototype.getProbesAndGenesByNumericalExpressionProfile";
    try {
        
        flykit.info("request: "+profile, _context);
        var chain = flykit.chain(flykit.flyatlas.Service.transformResponseForGetProbesAndGenesByNumericalExpressionProfile, success);
        var query = this._buildQueryForGetProbesAndGenesByNumericalExpressionProfile(profile, limit);
        flykit.debug("query: "+query, _context);
        this.postQuery(query, chain, failure);        

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
};


flykit.flyatlas.Service.prototype._buildQueryForGetProbesAndGenesByExpressionProfile = function( profile, limit ) {
    var _context = "flykit.flyatlas.Service.prototype._buildQueryForGetProbesAndGenesByExpressionProfile";
    try {

        /*
        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
        PREFIX : <http://purl.org/NET/flyatlas/schema#> 
        SELECT ?probe ?gene WHERE { 
            ?probedata  
              :brain_call "Up"^^xsd:string ; 
              :head_call "Down"^^xsd:string ; 
              ..
              :affy_id ?probe ; 
              :gene ?gene ; 
              a :ProbeData ; 
            .
        }
         */        

        var query =         "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" +
                            "PREFIX : <http://purl.org/NET/flyatlas/schema#>\n" +
                            "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
                            "SELECT DISTINCT ?probe ?gene \n" +
                            //"FROM <http://purl.org/net/dataset/flyatlas-latest> " +
                            "WHERE {\n" +
                            "  ?probedata\n";
                        
        for (var i=1;i<flykit.flyatlas.tissues.length;i++) {
            var tissue = flykit.flyatlas.tissues[i];
            flykit.debug("looking for clauses for tissue "+tissue+" given profile "+profile, _context);
            var change = profile[tissue];       
            flykit.debug("found change "+change+" for tissue "+tissue, _context);
            if (change == "Up" || change == "Down" || change == "None") {

                flykit.debug("adding query clause", _context);
                query +=    "    :"+tissue+"_call \""+change+"\"^^xsd:string ;\n"
            }
        }  
        
        query +=            "    rdfs:label ?probe ;\n" +
                            "    :gene ?gene ;\n" +
                            "    a :ProbeData .\n" +
                            "} LIMIT "+limit;

        flykit.debug("query: "+query, _context);
        return query;

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
    
};




flykit.flyatlas.Service.prototype._buildQueryForGetProbesAndGenesByNumericalExpressionProfile = function( profile, limit ) {
    var _context = "flykit.flyatlas.Service.prototype._buildQueryForGetProbesAndGenesByNumericalExpressionProfile";
    try {

        /*
        PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
        PREFIX : <http://purl.org/NET/flyatlas/schema#> 
        SELECT ?probe ?gene WHERE { 
            ?brain  a :BrainAssay; :mean ?brainmean .
            filter (?brainmean>xx && ?brainmean<yy)
            ?head  a :HeadAssay; :mean ?headmean .
            filter (?headmean>xx && ?headmean<yy)
            
            ?probedata
              :brain [ 
                :mean "1016.2"^^xsd:decimal ;
                a :Assay ; 
              ] ; 
              :head [ 
                :mean "1874.6"^^xsd:decimal ;
                a :Assay ; 
              ] ; 
              :affy_id ?probe ; 
              :gene ?gene ; 
              a :ProbeData ; 
            .
        }
         */        

        var query =         "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n" +
                            "PREFIX : <http://purl.org/NET/flyatlas/schema#>\n" +
                            "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
                            "SELECT DISTINCT ?probe ?gene \n" +
                            //"FROM <http://purl.org/net/dataset/flyatlas-latest> " +
                            "WHERE {\n" ;
                            //"  ?probedata\n";
                            
       
                        
        /*for (var i=1;i<flykit.flyatlas.tissues.length;i++) {
            var tissue = flykit.flyatlas.tissues[i];
            flykit.debug("looking for clauses for tissue "+tissue+" given profile "+profile, _context);
            var expression = profile[tissue];       
            flykit.debug("found expression "+expression+" for tissue "+tissue, _context);
            //if (change == "Up" || change == "Down" || change == "None") {

            flykit.debug("adding query clause", _context);
            query +=    "    :"+tissue+" [\n" +
                        "      :mean \""+change+"\"^^xsd:string ;\n" +
                        "      a :Assay ;\n" +
                        "    ] ;\n";

            //}
        }  */
        
        for (var i = 0; i < profile.length; i++){
            var tissue = profile[i].get("tissue");
            var min = profile[i].get("min");
            var max = profile[i].get("max");
            
            query += "?probedata :" + tissue + "[:mean ?" + tissue + "mean] .\n" +
                     "filter (?" + tissue + "mean>" + min + " && ?" + tissue + "mean<" + max + ") .\n";
        }
        
        query +=            "?probedata    rdfs:label ?probe ;\n" +
                            "    :gene ?gene ;\n" +
                            "    a :ProbeData .\n" +
                            "} LIMIT "+limit;

        
        return query;

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
    
};





flykit.flyatlas.Service.transformResponseForGetProbesAndGenesByExpressionProfile = function( response ) {
    var _context = "flykit.flyatlas.Service.transformResponseForGetProbesAndGenesByExpressionProfile";
    try {
        
        flykit.debug("response status: "+response.status, _context);
        flykit.debug("try parsing response text as json", _context);
        flykit.debug("parsing response: "+response.responseText, _context);

        var resultSet = YAHOO.lang.JSON.parse(response.responseText);
        
        flykit.debug("convert result set", _context);

        var probes = [];
        var genes = [];
        var pairs = [];
        
        var bindings = resultSet.results.bindings;
        
        for (var i=0;i<bindings.length;i++) {
            var probeid = bindings[i].probe.value;
            var geneuri = bindings[i].gene.value;
            var flybaseid = geneuri.split("/")[geneuri.split("/").length-1];
            flykit.util.appendIfNotMember(probes, probeid);
            flykit.util.appendIfNotMember(genes, flybaseid);
            pairs[pairs.length] = [probeid, flybaseid];
        }
        
        return {"probes":probes,"genes":genes,"pairs":pairs};

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
    
};

flykit.flyatlas.Service.transformResponseForGetProbesAndGenesByNumericalExpressionProfile = function( response ) {
    var _context = "flykit.flyatlas.Service.transformResponseForGetProbesAndGenesByExpressionProfile";
    try {
        
        flykit.debug("response status: "+response.status, _context);
        flykit.debug("try parsing response text as json", _context);
        flykit.debug("parsing response: "+response.responseText, _context);

        var resultSet = YAHOO.lang.JSON.parse(response.responseText);
        
        flykit.debug("convert result set", _context);

        var probes = [];
        var genes = [];
        var pairs = [];
        
        var bindings = resultSet.results.bindings;
        
        for (var i=0;i<bindings.length;i++) {
            var probeid = bindings[i].probe.value;
            var geneuri = bindings[i].gene.value;
            var flybaseid = geneuri.split("/")[geneuri.split("/").length-1];
            flykit.util.appendIfNotMember(probes, probeid);
            flykit.util.appendIfNotMember(genes, flybaseid);
            pairs[pairs.length] = [probeid, flybaseid];
        }
        
        return {"probes":probes,"genes":genes,"pairs":pairs};

    } catch (error) {
        throw new flykit.UnexpectedException(_context, error);
    }
    
};



