/**
 * Get the irradiance at the given point.
 * @param origin : the point where we want to know the irradiance.
 * @param irradiance : the computed irradiance will be placed into this spectrum.
 */
inline void MultispectralPhotonMap::getIrradiance(const Point& origin, Spectrum& irradiance)
{
  //Get the nearest photon
  MultispectralPhoton* irradianceValue =  _tree.getNearestElement(origin);

  if(irradianceValue==NULL)
  {
    irradiance.clear();
    return;
  }

  //Set the irradiance
  for(unsigned int l=0; l<GlobalSpectrum::nbWaveLengths(); l++)
    irradiance[l] = irradianceValue->radiance[l];
}
Пример #2
0
/**
 * Default constructor
 */
inline Medium::Medium()
: isOpaque(false), hasDispersion(false), hasPhotonDispersion(false), useLambertianModel(false), useFresnelModel(false), useKubelkaMunkModel(false)
{
  r.clear();
  t.clear();
  n.clear();
  k.clear();
  S.clear();
  K.clear();
}
Пример #3
0
	Spectrum Integrator::handleInfiniteLights(const Ray& in, const ShaderClosure& sc, RenderThreadContext* context, float& full_pdf)
	{
		Spectrum full_weight;
		full_pdf = 0;

		RandomSampler sampler(context->random());
		for(IInfiniteLight* e : context->renderer()->scene()->infiniteLights())
		{
			Spectrum semi_weight;
			float semi_pdf = 0;

			for(uint32 i = 0;
				i < context->renderer()->settings().maxLightSamples() && !std::isinf(semi_pdf);
				++i)
			{
				float pdf;
				PM::vec3 rnd = sampler.generate3D(i);
				PM::vec3 dir = e->sample(sc, rnd, pdf);

				if(pdf <= PM_EPSILON)
					continue;

				Spectrum weight;
				const float NdotL = PM::pm_Max(0.0f, PM::pm_Dot3D(dir, sc.N));

				if (NdotL > PM_EPSILON)
				{
					RenderEntity* entity;

					Ray ray = in.next(sc.P, dir);
					ray.setFlags(ray.flags() | RF_Light);

					weight = handleSpecularPath(ray, sc, context, entity);
					if (!entity)
						weight *= sc.Material->eval(sc, dir, NdotL) * e->apply(dir) * NdotL;
					else
						weight.clear();
				}

				MSI::power(semi_weight, semi_pdf, weight, pdf);
			}
			
			MSI::balance(full_weight, full_pdf, semi_weight, std::isinf(semi_pdf) ? 1 : semi_pdf);
		}

		return full_weight;
	}
Пример #4
0
bool CNoiseReduction::DeNoiseD(Spectrum& sp){

  Spectrum tmpSpec;  
  vector<int> v;

  sp.clear();

  if(pos==0){
    if(cs.scan.iLower>0) {
      if(!NewScanAverage(sp,cs.inFile,(int)(cs.boxcar/2),0.1f,cs.scan.iLower)) return false;
    } else {
      NewScanAverage(sp,cs.inFile,(int)(cs.boxcar/2),0.1f);
    }
    pos=1;
  } else {
    NewScanAverage(sp,NULL,(int)(cs.boxcar/2),0.1f);
  }

  if(sp.getScanNumber()==0) return false;
  FirstDerivativePeaks(sp,1);
  return true;

}
Пример #5
0
bool CNoiseReduction::NewScanAverage(Spectrum& sp, char* file, int width, float cutoff, int scanNum){
  
  Spectrum ts;

  vector<int> vPos;
   
  int i;
  int j;
  int k;
  int m;
  int widthCount=0;
  int numScans=1;
  double dif;
  double prec;
  double dt;
  double c;

  bool bLeft=true;
  int posLeft;
  int posRight;
  int index;
  char cFilter1[256];
  //char cFilter2[256];

  //double slope;
  //double intercept;

  sp.clear();
  Spectrum* specs;
  specs = new Spectrum[width*2+1];

  //if file is not null, create new buffer
  if(file!=NULL){
    strcpy(lastFile,file);
    bs.clear();
    if(scanNum>0) r->readFile(file,ts,scanNum);
    else r->readFile(file,ts);
    if(ts.getScanNumber()==0) {
      delete [] specs;
      return false;
    }
    bs.push_back(ts);
    specs[0]=bs[0];
    c=CParam(specs[0],3);
    posA=0;
  } else {
    posA++;
    if(posA>=(int)bs.size()) { //end of buffer, no more data
      delete [] specs;
      return false; 
    }
    specs[0]=bs[posA];
    c=CParam(specs[0],3);
  }

  specs[0].getRawFilter(cFilter1,256);

  posLeft=posA;
  posRight=posA;
  while(widthCount<(width*2)){

    index=-1;

    //Alternate looking left and right
    if(bLeft){
      bLeft=false;
      widthCount++;
      
      while(true){
        posLeft--;
        if(posLeft<0) { //buffer is too short on left, add spectra
          i=bs[0].getScanNumber();
          while(true){
            i--;
            if(i==0) break;
            r->readFile(lastFile,ts,i);
            if(ts.getScanNumber()==0) continue;
            else break;
          }
          if(i==0) break;
          bs.push_front(ts);
          posA++;
          posRight++;
          posLeft=0;
          //ts.getRawFilter(cFilter2,256);
          if(ts.getMsLevel()==cs.msLevel) {
            index=posLeft;
            break;
          }
        } else {
          //bs[posLeft].getRawFilter(cFilter2,256);
          if(bs[posLeft].getMsLevel()==cs.msLevel) {
            index=posLeft;
            break;
          }
        }
      }

    } else {
      bLeft=true;
      widthCount++;

      while(true){
        posRight++;
        if(posRight>=(int)bs.size()) { //buffer is too short on right, add spectra
          r->readFile(lastFile,ts,bs[bs.size()-1].getScanNumber());
          r->readFile(NULL,ts);
          if(ts.getScanNumber()==0) {
            posRight--;
            break;
          }
          bs.push_back(ts);
          //ts.getRawFilter(cFilter2,256);
          if(ts.getMsLevel()==cs.msLevel) {
            index=posRight;
            break;
          }
        } else {
          //bs[posRight].getRawFilter(cFilter2,256);
          if(bs[posRight].getMsLevel()==cs.msLevel) {
            index=posRight;
            break;
          }
        }
      }
    }

    if(index==-1)  continue;
    specs[numScans++]=bs[index];

  }
  
  double tmz;
  int mzcount=0;

  /* Ledford equation correction
  double freq;
  double conA=0.0;
  double conB=0.0;

  for(m=0;m<numScans;m++){
    conA+=specs[m].getConversionA();
    conB+=specs[m].getConversionB();
  }
  conA/=numScans;
  conB/=numScans;

  printf("%.10lf, %.10lf\n",conA,conB);
  for(k=0;k<numScans;k++){
    for(j=0;j<specs[k].size();j++){
      freq = sqrt(specs[k].getConversionA()*specs[k].getConversionA() - (4*specs[k].at(j).mz*(-specs[k].getConversionB())));
      freq += specs[k].getConversionA();
      freq /= (2*specs[k].at(j).mz);

      specs[k].at(j).mz = conA/freq + conB/(freq*freq);
    }
  }
  */

  //Match peaks between pivot scan (0) and neighbors (the rest)
  for(m=0;m<numScans;m++){
    
    vPos.clear();
    for(i=0;i<numScans;i++) vPos.push_back(0);

    for(i=0;i<specs[m].size();i++){ //iterate all points
      if(specs[m].at(i).intensity<0.1) continue;
      tmz=specs[m].at(i).mz;
      mzcount=1;
      prec = c * tmz * tmz / 2;
      
      for(k=m+1;k<numScans;k++){ //iterate all neighbors
        dif=100000.0;

        for(j=vPos[k];j<specs[k].size();j++){ //check if point is a match
          if(specs[k].at(j).intensity<0.1) continue; //skip meaningless datapoints to speed along
          dt=fabs(tmz-specs[k].at(j).mz);

          if(dt<=dif) {
            if(dt<prec) {
              //linear interpolate
              //if(specs[k].at(j).mz<tmz && j<specs[k].size()-1){
              //  slope=(specs[k].at(j+1).intensity-specs[k].at(j).intensity)/(specs[k].at(j+1).mz-specs[k].at(j).mz);
              //  intercept=specs[k].at(j).intensity-specs[k].at(j).mz*slope;
              //  specs[m].at(i).intensity+=(tmz*slope+intercept);
              //} else if(specs[k].at(j).mz>tmz && j>0) {
              //  slope=(specs[k].at(j).intensity-specs[k].at(j-1).intensity)/(specs[k].at(j).mz-specs[k].at(j-1).mz);
              //  intercept=specs[k].at(j).intensity-specs[k].at(j).mz*slope;
              //  specs[m].at(i).intensity+=(tmz*slope+intercept);
              //} else {
              specs[m].at(i).intensity += specs[k].at(j).intensity;
              //}

              //Averaging the mz values appears equivalent to realigning all spectra against
              //an average Ledford correction.
              specs[m].at(i).mz += specs[k].at(j).mz;
              vPos[k]=j+1;
              specs[k].at(j).intensity=-1.0;
              mzcount++;
              break;
            }
            dif=dt;
          } else {
            vPos[k]=j-1;
            break;
          }
        }
      }//for k

      sp.add(specs[m].at(i).mz/mzcount,specs[m].at(i).intensity/numScans);

    } //next i
  } //next m

  if(sp.size()>0) sp.sortMZ();
  sp.setScanNumber(specs[0].getScanNumber());
  sp.setScanNumber(specs[0].getScanNumber(true),true);
  sp.setRTime(specs[0].getRTime());
  sp.setRawFilter(cFilter1);

  if(posLeft>0){
    while(posLeft>0){
      bs.pop_front();
      posLeft--;
      posA--;
    }
  }
  delete [] specs;
  return true;
}
Пример #6
0
bool CNoiseReduction::ScanAverage(Spectrum& sp, char* file, int width, float cutoff){
  
  Spectrum ts;
  Spectrum ps=sp;
  MSReader r;
 
  int i;
  int j;
  int k;
  int widthCount=0;
  int numScans=1;
  double dif;
  double prec;
  double dt;
  double c=CParam(ps,3);

  bool bLeft=true;
  int posLeft=ps.getScanNumber()-1;
  int posRight=ps.getScanNumber()+1;
  char cFilter1[256];
  char cFilter2[256];

  ps.getRawFilter(cFilter1,256);

  while(widthCount<(width*2)){

    //Alternate looking left and right
    if(bLeft){
      bLeft=false;
      widthCount++;
      while(posLeft>0){
        r.readFile(file,ts,posLeft);
        if(ts.getScanNumber()==0) break;
        ts.getRawFilter(cFilter2,256);
        if(strcmp(cFilter1,cFilter2)==0) break;
        posLeft--;
      }
    } else {
      bLeft=true;
      widthCount++;
      while(true){
        r.readFile(file,ts,posRight);
        if(ts.getScanNumber()==0) break;
        ts.getRawFilter(cFilter2,256);
        if(strcmp(cFilter1,cFilter2)==0) break;
        posRight++;
      }
    }
    if(ts.getScanNumber()==0) continue;

    numScans++;

    //Match peaks between pivot scan and temp scan
    k=0;
    for(i=0;i<ps.size();i++){
      dif=100000.0;
      prec = c * ps.at(i).mz * ps.at(i).mz / 2;

      for(j=k;j<ts.size();j++){
        dt=fabs(ps.at(i).mz-ts.at(j).mz);
        if(dt<=dif) {
          if(dt<prec) {
            ps.at(i).intensity+=ts.at(j).intensity;
            ts.at(j).mz=-1.0;
            k=j+1;
            break;
          }
          dif=dt;
        } else {
          k=j-1;
          break;
        }
      }
    }

    //Add unmatched peaks from temp scan
    for(i=0;i<ts.size();i++){
      if(ts.at(i).mz>-1.0) ps.add(ts.at(i));
    }

    //Sort pivot scan peaks for fast traversal against next temp scan
    ps.sortMZ();

  }

  //Average points and apply cutoff
  sp.clear();
  for(i=0;i<ps.size();i++) {
    ps.at(i).intensity/=numScans;
    if(ps.at(i).intensity>=cutoff) sp.add(ps.at(i));
  }

  sp.setScanNumber(ps.getScanNumber());
  sp.setScanNumber(ps.getScanNumber(true),true);
  sp.setRTime(ps.getRTime());

  return true;
}
Пример #7
0
bool CNoiseReduction::DeNoise(Spectrum& sp){

  double ppm;
  int i,j,k;
  int index;
  int matchCount;
  char cFilter1[256];
  char cFilter2[256];

  Spectrum tmpSpec;  
  vector<int> v;

  sp.clear();

  if(pos==0){
    if((cs.scan.iLower>0)) {
      k=cs.scan.iLower; 
      r->readFile(&cs.inFile[0],tmpSpec,cs.scan.iLower);
    } else {
      r->readFile(&cs.inFile[0],tmpSpec);
      k=tmpSpec.getScanNumber();
    }
    if(tmpSpec.getScanNumber()==0) return false;
    tmpSpec.getRawFilter(cFilter1,256);
      
    //Gather left side of scan
    i=1;
    j=0;
    while( k-i > 0){
      r->readFile(&cs.inFile[0],tmpSpec,cs.scan.iLower-i);
      if(tmpSpec.getScanNumber()==0) {
        i++;
        continue;
      }
      tmpSpec.getRawFilter(cFilter2,256);
      
      //Assume High resolution data at all times
      if(!cs.centroid) {
        FirstDerivativePeaks(tmpSpec,1);
        tmpSpec.setRawFilter(cFilter2);
      }

      s.push_front(tmpSpec);
      if(strcmp(cFilter1,cFilter2)==0){
        j++;
				if(j==(int)(cs.boxcar/2)) break;
      }
      i++;
    }

    //cout << "Done left " << s.size() << " " << cs.rawAvgWidth << endl;

    //Get our position again
    r->readFile(&cs.inFile[0],tmpSpec,k);

    //Assume High resolution data at all times
    if(!cs.centroid) {
      FirstDerivativePeaks(tmpSpec,1);
      tmpSpec.setRawFilter(cFilter1);
    }
    
    //Add first target scan
    s.push_back(tmpSpec);
    pos=s.size()-1; 
    
    //Add right side of scan
    i=1;
    j=0;
    while(true){
      r->readFile(NULL,tmpSpec);
      if(tmpSpec.getScanNumber()==0) break;
      tmpSpec.getRawFilter(cFilter2,256);

      //Assume High resolution data at all times
      if(!cs.centroid) {
        FirstDerivativePeaks(tmpSpec,1);
        tmpSpec.setRawFilter(cFilter2);
      }

      s.push_back(tmpSpec);
      //cout << tmpSpec.getScanNumber() << " " << cFilter1 << " xx " << cFilter2 << endl;
      if(strcmp(cFilter1,cFilter2)==0){  
        j++;
				if(j==(int)(cs.boxcar/2)) break;
      }
      i++;
    }

  }

  //return false if we reached the end
  if(pos>=(int)s.size()) return false;

  //Because Deque may have mixed spectra, create list of Deque indexes to compare
  //Shrink Deque on the left if some spectra are not needed
  //Expand Deque to the right if needed and possible
  //cout << "Checking scan " << s[pos].getScanNumber() << endl;
  v.clear();
  s[pos].getRawFilter(cFilter1,256);

  //look left
  for(i=pos-1;i>=0;i--){
    s[i].getRawFilter(cFilter2,256);
    if(strcmp(cFilter1,cFilter2)==0) {
      v.push_back(i);
			if(v.size()==(int)(cs.boxcar/2)) break;
    }
  }

  //erase unneeded left items
  while(i>0){
    s.pop_front();
    i--;
    for(j=0;j<(int)v.size();j++) v[j]--;
    pos--;
  }

  //look right
  j=0;
  for(i=pos+1;i<(int)s.size();i++){
    s[i].getRawFilter(cFilter2,256);
    if(strcmp(cFilter1,cFilter2)==0) {
      v.push_back(i);
      j++;
      if(j==(int)(cs.boxcar/2)) break;
    }
  }

  //extend right side if needed
  while(j<(int)(cs.boxcar/2)){
    r->readFile(NULL,tmpSpec);
    if(tmpSpec.getScanNumber()==0) break;    
    tmpSpec.getRawFilter(cFilter2,256);

    //Assume High resolution data at all times
    if(!cs.centroid) {
      FirstDerivativePeaks(tmpSpec,1);
      tmpSpec.setRawFilter(cFilter2);
    }

    s.push_back(tmpSpec);
    if(strcmp(cFilter1,cFilter2)==0) {
      v.push_back(s.size()-1);
      j++;
    }
  }

  //if there is nothing to compare to, exit now
  if(v.size()==0) return false;

  //compare peaks
  //cout << "Checking " << s[pos].size() << " peaks." << endl;
  for(i=0;i<s[pos].size();i++){
    matchCount=1;
    for(j=0;j<(int)v.size();j++){
      if(s[v[j]].size()<1) continue;
      index = NearestPeak(s[v[j]],s[pos].at(i).mz);
      ppm=fabs( (s[v[j]].at(index).mz-s[pos].at(i).mz)/s[pos].at(i).mz * 1000000);
      if(ppm<cs.ppm) matchCount++;
    }
		if(matchCount>=cs.boxcarFilter || matchCount==v.size()) sp.add(s[pos].at(i));
  }
  sp.setScanNumber(s[pos].getScanNumber());
  sp.setScanNumber(s[pos].getScanNumber(true),true);
  sp.setRTime(s[pos].getRTime());
  pos++;

  //cout << sp.getScanNumber() << endl;

  //cout << "Done! " << sp.size() << " " << pos << endl;
  return true;

}
Пример #8
0
bool CNoiseReduction::NewScanAveragePlusDeNoise(Spectrum& sp, char* file, int width, float cutoff, int scanNum){
  
  Spectrum ts;

  vector<int> vPos;
 
  int i;
  int j;
  int k;
  int m;
  int widthCount=0;
  int numScans=1;
  int match;
  double dif;
  double prec;
  double dt;
  double c;

  bool bLeft=true;
  int posLeft;
  int posRight;
  int index;
  char cFilter1[256];
  char cFilter2[256];

  sp.clear();

  Spectrum* specs;
  specs = new Spectrum[width*2+1];

  //if file is not null, create new buffer
  if(file!=NULL){
    strcpy(lastFile,file);
    bs.clear();
    if(scanNum>0) r->readFile(file,ts,scanNum);
    else r->readFile(file,ts);
    if(ts.getScanNumber()==0) {
      delete [] specs;
      return false;
    }
    bs.push_back(ts);
    specs[0]=bs[0];
    c=CParam(specs[0],3);
    posA=0;
  } else {
    posA++;
    if(posA>=(int)bs.size()) { //end of buffer, no more data
      delete [] specs;
      return false; 
    }
    specs[0]=bs[posA];
    c=CParam(specs[0],3);
  }

  //set our pivot spectrum
  specs[0].getRawFilter(cFilter1,256);

  posLeft=posA;
  posRight=posA;
  while(widthCount<(width*2)){

    index=-1;

    //Alternate looking left and right
    if(bLeft){
      bLeft=false;
      widthCount++;
      
      while(true){
        posLeft--;
        if(posLeft<0) { //buffer is too short on left, add spectra
          i=bs[0].getScanNumber();
          while(true){
            i--;
            if(i==0) break;
            r->readFile(lastFile,ts,i);
            if(ts.getScanNumber()==0) continue;
            else break;
          }
          if(i==0) break;
          bs.push_front(ts);
          posA++;
          posRight++;
          posLeft=0;
          ts.getRawFilter(cFilter2,256);
          if(strcmp(cFilter1,cFilter2)==0) {
            index=posLeft;
            break;
          }
        } else {
          bs[posLeft].getRawFilter(cFilter2,256);
          if(strcmp(cFilter1,cFilter2)==0) {
            index=posLeft;
            break;
          }
        }
      }

    } else {
      bLeft=true;
      widthCount++;

      while(true){
        posRight++;
        if(posRight>=(int)bs.size()) { //buffer is too short on right, add spectra
          r->readFile(lastFile,ts,bs[bs.size()-1].getScanNumber());
          r->readFile(NULL,ts);
          if(ts.getScanNumber()==0) {
            posRight--;
            break;
          }
          bs.push_back(ts);
          ts.getRawFilter(cFilter2,256);
          if(strcmp(cFilter1,cFilter2)==0) {
            index=posRight;
            break;
          }
        } else {
          bs[posRight].getRawFilter(cFilter2,256);
          if(strcmp(cFilter1,cFilter2)==0) {
            index=posRight;
            break;
          }
        }
      }
    }

    if(index==-1)  continue;
   
    //ts=bs[index];
    specs[numScans++]=bs[index];

    //cout << "NumScans: " << numScans << endl;

  }

  //Match peaks between pivot scan (0) and neighbors (the rest)
  //for(m=0;m<cs.ppMatch && m<numScans;m++){
  for(m=0;m<1;m++){

    //cout << "m " << m << " = " << specs[m].getScanNumber() << endl;
    
    vPos.clear();
    for(i=0;i<numScans;i++) vPos.push_back(0);
    //cout << "Checking " << m << " of " << numScans << " points remaining: " << specs[m].size() << endl;

    for(i=0;i<specs[m].size();i++){ //iterate all points
      if(specs[m].at(i).intensity<0.1) continue;
      prec = c * specs[m].at(i).mz * specs[m].at(i).mz / 2;
      match=1;

      for(k=m+1;k<numScans;k++){ //iterate all neighbors
        dif=100000.0;

        for(j=vPos[k];j<specs[k].size();j++){ //check if point is a match
          //cout << "Checking " << j << " of " << specs[k].size() << endl;
          if(specs[k].at(j).intensity<0.1) continue; //skip meaningless datapoints to speed along
          dt=fabs(specs[m].at(i).mz-specs[k].at(j).mz);
          //dt=specs[m].at(i).mz-specs[k].at(j).mz;
          //if(dt<0.0)dt=-dt;
          if(dt<=dif) {
            if(dt<prec) {
              specs[m].at(i).intensity+=specs[k].at(j).intensity;
              vPos[k]=j+1;
              specs[k].at(j).intensity=-1.0;
              match++;
              break;
            }
            dif=dt;
          } else {
            vPos[k]=j-1;
            break;
          }
        }

      }//for k

      //if data point was not visible across enough scans, set it to 0
			if(match<cs.boxcarFilter && match<numScans) {
        //ignore point
        //cout << "BAH! " << specs[m].at(i).mz << " has " << match << " matches." << endl;
      } else {
        //add to temp spectrum
        //cout << specs[m].at(i).mz << " has " << match << " matches." << endl;
        //sp.add(specs[m].at(i).mz,specs[m].at(i).intensity/numScans);
        sp.add(specs[m].at(i).mz,specs[m].at(i).intensity/match);
      }

    } //next i

  } //next m

  //sort
  //cout << "Done " << sp.size() << endl;
  if(sp.size()>0) sp.sortMZ();
  sp.setScanNumber(specs[0].getScanNumber());
  sp.setScanNumber(specs[0].getScanNumber(true),true);
  sp.setRTime(specs[0].getRTime());
  sp.setRawFilter(cFilter1);

  //clear unused buffer
  if(posLeft>0){
    while(posLeft>0){
      bs.pop_front();
      posLeft--;
      posA--;
    }
  }

  delete [] specs;

  return true;
}
Пример #9
0
bool CNoiseReduction::ScanAveragePlusDeNoise(Spectrum& sp, char* file, int width, float cutoff, int scanNum){
  
  Spectrum ts;
  Spectrum ps;
  //MSReader r;

  vector<int> v;
  vector<int> vPos;
 
  int i;
  int j;
  int k;
  int widthCount=0;
  int numScans=1;
  int match;
  double dif;
  double prec;
  double dt;
  double c;

  bool bLeft=true;
  int posLeft=ps.getScanNumber()-1;
  int posRight=ps.getScanNumber()+1;
  int index;
  char cFilter1[256];
  //char cFilter2[256];

  sp.clear();

  //if file is not null, create new buffer
  if(file!=NULL){
    strcpy(lastFile,file);
    bs.clear();
    if(scanNum>0) r->readFile(file,ts,scanNum);
    else r->readFile(file,ts);
    if(ts.getScanNumber()==0) return false;
    bs.push_back(ts);
    ps=bs[0];
    c=CParam(ps,3);
    posA=0;
  } else {
    posA++;
    //cout << "ER: " << posA << " " << bs.size() << endl;
    if(posA>=(int)bs.size()) return false; //end of buffer, no more data
    ps=bs[posA];
    c=CParam(ps,3);
  }

  //set our pivot spectrum
  //ps=bs[posA];
  ps.getRawFilter(cFilter1,256);
  //cout << "Averaging: " << ps.getScanNumber() << endl;

  posLeft=posA;
  posRight=posA;
  while(widthCount<(width*2)){

    index=-1;

    //Alternate looking left and right
    if(bLeft){
      bLeft=false;
      widthCount++;
      
      while(true){
        posLeft--;
        //cout << posLeft << endl;
        if(posLeft<0) { //buffer is too short on left, add spectra
          i=bs[0].getScanNumber();
          while(true){
            i--;
            //cout << "I: " << i << endl;
            if(i==0) break;
            r->readFile(lastFile,ts,i);
            if(ts.getScanNumber()==0) continue;
            else break;
          }
          if(i==0) break;
          bs.push_front(ts);
          for(i=0;i<(int)v.size();i++)v[i]++;
          posA++;
          posRight++;
          posLeft=0;
          //ts.getRawFilter(cFilter2,256);
          if(ts.getMsLevel()==cs.msLevel) {
            index=posLeft;
            break;
          }
        } else {
          //bs[posLeft].getRawFilter(cFilter2,256);
          if(bs[posLeft].getMsLevel()==cs.msLevel) {
            index=posLeft;
            break;
          }
        }
      }

    } else {
      bLeft=true;
      widthCount++;

      while(true){
        posRight++;
        if(posRight>=(int)bs.size()) { //buffer is too short on right, add spectra
          r->readFile(lastFile,ts,bs[bs.size()-1].getScanNumber());
          r->readFile(NULL,ts);
          if(ts.getScanNumber()==0) {
            posRight--;
            break;
          }
          bs.push_back(ts);
          //ts.getRawFilter(cFilter2,256);
          if(ts.getMsLevel()==cs.msLevel) {
            index=posRight;
            break;
          }
        } else {
          //bs[posRight].getRawFilter(cFilter2,256);
          if(bs[posRight].getMsLevel()==cs.msLevel) {
            index=posRight;
            break;
          }
        }
      }
    }

    if(index==-1)  continue;
   
    //ts=bs[index];
    v.push_back(index);

    numScans++;
  }

  //cout << "Still Averaging: " << ps.getScanNumber() << endl;
  //cout << " with: ";
  //for(i=0;i<v.size();i++) cout << bs[v[i]].getScanNumber() << " ";
  //cout << endl;

  //cout << numScans << " " << v.size() << endl;

  //Match peaks between pivot scan and neighbors
  for(i=0;i<(int)v.size();i++) vPos.push_back(0);
  for(i=0;i<(int)ps.size();i++){ //iterate all points
    prec = c * ps.at(i).mz * ps.at(i).mz / 2;
    match=1;

    for(k=0;k<(int)v.size();k++){ //iterate all neighbors
      dif=100000.0;
      //cout << "Checking " << bs[v[k]].getScanNumber() << " pos " << vPos[k] << endl;

      for(j=vPos[k];j<bs[v[k]].size();j++){ //check if point is a match
        dt=fabs(ps.at(i).mz-bs[v[k]].at(j).mz);
        if(dt<=dif) {
          if(dt<prec) {
            ps.at(i).intensity+=bs[v[k]].at(j).intensity;
            vPos[k]=j+1;
            match++;
            break;
          }
          dif=dt;
        } else {
          vPos[k]=j-1;
          break;
        }
      }

    }

    //if data point was not visible across enough scans, set it to 0
		if(match<cs.boxcarFilter && match<(int)v.size()) ps.at(i).intensity=0.0;

  }


  //Average points and apply cutoff
  for(i=0;i<ps.size();i++) {
    ps.at(i).intensity/=numScans;
    sp.add(ps.at(i));
    //if(ps.at(i).intensity>=cutoff) sp.add(ps.at(i));
  }

  sp.setScanNumber(ps.getScanNumber());
  sp.setScanNumber(ps.getScanNumber(true),true);
  sp.setRTime(ps.getRTime());
  sp.setRawFilter(cFilter1);

  //clear unused buffer
  if(posLeft>0){
    while(posLeft>0){
      bs.pop_front();
      posLeft--;
      posA--;
    }
  }

  //cout << "Done averaging" << endl;

  return true;
}