public void ProcessData(IMatrixData mdata, Parameters param, ref IMatrixData[] supplTables, ProcessInfo processInfo)
 {
     string[][] col = mdata.CategoryColumns[param.GetSingleChoiceParam("Indicator column").Value];
     string term = param.GetStringParam("Value").Value;
     List<int> inds = new List<int>();
     for (int i = 0; i < col.Length; i++){
         if (Contains(col[i], term)){
             inds.Add(i);
         }
     }
     float[][] profiles = new float[inds.Count][];
     for (int i = 0; i < profiles.Length; i++){
         profiles[i] = mdata.GetExpressionRow(inds[i]);
         float mean = (float) ArrayUtils.Mean(profiles[i]);
         for (int j = 0; j < profiles[i].Length; j++){
             profiles[i][j] -= mean;
         }
     }
     float[] totalProfile = new float[mdata.ExpressionColumnCount];
     for (int i = 0; i < totalProfile.Length; i++){
         List<float> vals = new List<float>();
         foreach (float[] t in profiles){
             float val = t[i];
             if (float.IsNaN(val) || float.IsInfinity(val)){
                 continue;
             }
             vals.Add(val);
         }
         totalProfile[i] = vals.Count > 0 ? ArrayUtils.Median(vals) : float.NaN;
     }
     for (int i = 0; i < mdata.RowCount; i++){
         for (int j = 0; j < mdata.ExpressionColumnCount; j++){
             mdata[i, j] -= totalProfile[j];
         }
     }
 }