/**
Load climate data sets for the SBEII
Two text files are loaded into two arrays: RO_refr.txt and RO_temp.txt

KV, BCL, 02/2010
**/
(
q = q ?? ();
q.myPath = Document.current.dir; 
q.refracfile = q.myPath ++ "/RO_refr.txt";
q.tempfile = q.myPath ++ "/RO_temp.txt";
)
// CHOOSE:
q.myfile = q.refracfile;
q.myfile = q.tempfile;

// File.exists(q.myfile);
// g = File(q.myfile, "r")

(
a = Array.newFromFile(q.myfile, $ , $\n);
//a.printAll;

// header: a[0..19].printAll;

// latitudes north (18)
q.latitudes = a[20..22].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
//q.latitudes.size;

// header: a[23..24].printAll;
// height levels in m (9)
q.heightlevs = a[25..26].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
//q.heightlevs.size;

// header: a[27..28];
// time steps (julian time)
q.timejul = a[29..49].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
//q.timejul.size;

//header: a[50];
// time steps: calender time, YYYY-MM-DD
q.timecal = a[51..71].collect({|item, i| 
	var aii = Array.new; 
	item.do{|jtem| aii = aii ++ ([jtem.keep(4)++jtem[5..6]++jtem[8..9]]);}; 
	// 	change date to YYYYMMDD without "-"
	aii.asFloat;
}).flat.removeEvery([0.0]);
//q.timecal.size;

// header: a[72]
// first time step, 162 entries (18 latitudes x 9 heightlevs):
a[73..99].asFloat.collect({|item| item}).flat.removeEvery([0.0]);

q.blanks = (q.timejul.size).collect{|i| (73+(27*(i))+i-1) };
q.data = Array.fill(q.timejul.size);
//first entry:
//a[73..100].collect({|item| item.asFloat}).flat.removeEvery([0.0]);
// all the rest of data:
q.blanks.do{|bs, bi|
	if (bi < (q.timejul.size-1)) 
		{q.data[bi] = 
		(a[bs..(q.blanks[(bi+1)]-1)].collect({
			|item| item.asFloat
		}).flat.removeEvery([0.0])).clump(q.latitudes.size)}
		{// last data index
		q.data[bi] = 
		(a[bs..(a.lastIndex)].collect({
			|item| item.asFloat
		}).flat.removeEvery([0.0])).clump(q.latitudes.size)};
};
)
//q.data.shape
//q.blanks.last
q.data.flat.printAll
(
// eliminate the nans and replace them by -999s
q.data.do{|planes, p|
	planes.do{|rows, r|
		rows.do{|val, c|
			if (val>0) // thus not nan!
			{val}
			{q.data[p][r][c] = -999;};
		}
	}
};
)
//q.data = q.data.flop
q.data.shape

Ndef(\ro).play;

(
Ndef(\ro, {
	var exc, freqs, son, amps;
	amps = \amps.kr(1 ! 9).lag(0.1);
	exc = PinkNoise.ar(1);
	freqs = (0..8).linexp(0, 8, 100, 3000);
	freqs = freqs * amps.linlin(0, 1, 1 - 0.02, 1 + 0.02);
	son = BPF.ar(exc, freqs, 0.01) * amps;
	son = son.sum ! 2 * 60;
	Limiter.ar(son)
}).play;
)

// test: play random vectors on \ro
(
Tdef(\x, {
	loop {
		0.2.wait;
		Ndef(\ro).setn(\amps, { 1.0.rand } ! 9);
	}
}).play
);

// prepare all data files: remove NaN, remove mean, remove seasonal cycle
(
q.cleanAllData = 18.collect { |i|
	var all = q.data.slice(nil, nil, i).drop(8).keep(84);
	var prev = all.at(0);
	all.collect { |x| 
			if(x[0].isNaN) { prev }{ x }
	};
};

// remove seasonal cycle
q.cleanAllSeaFreeData = q.cleanAllData.collect{ | latdata | 
	latdata.flop.collect { | hdat |
		var mean = hdat.reshape(7,12).mean;
		(hdat.reshape(7,12) - [mean]).flat;
	}.flop;		
};
// remove mean
q.cleanAllDataMean = q.cleanAllData.collect { |monthDat| monthDat.mean };
q.cleanAllData.shape;

q.cleanAllDataMean0 = q.cleanAllData.collect { | monthheightdat, i | 
	monthheightdat - [q.cleanAllDataMean[i]];
};
q.cleanAllDataMean0[7].flop[0].plot
);

// synth for sound file recording 

Ndef(\record, { | bufnum |
	DiskOut.ar(bufnum, Limiter.ar(Ndef.ar(\ro)));
});
)

(
a = Ndef(\rho).record("test.wav", "wav", "int16").resume;
Tdef(\y).reset.play;
q.stopRec = { a.close };
)

// record directly using Server
s.recHeaderFormat =  "wav";
s.recSampleFormat = "int16";
q.docpath = Document.current.path.dirname
(
Tdef(\y, {
		var data, mean, mask;
		// mask = [0, 0, 0, 0, 0, 0, 0, 1, 1];
		s.prepareForRecord(q.docpath++"/test.wav");
		1.wait;
		s.record;
		// mask = [1, 1, 0, 0, 0, 0, 0, 0, 0];
		mask = 1 ! 9;
		// mask = [0.2, 0.3, 0.5, 0.7, 1, 1, 1, 1, 1];
		18.do{ | lat | 
			lat.linlin(0,17, -85, 85).postln;
			// data = q.cleanAllSeaFreeData;
			data = q.cleanAllDataMean0[lat];
			data.do { |dT|
				var amp;
					amp = dT.linexp(-6, 6, 0.01, 1);
					Ndef(\ro).setn(\amps, amp * mask);
					0.005.wait;
			};
			Ndef(\ro).setn(\amps, 0 ! 9);
			0.2.wait;		
		};
		s.stopRecording
}).play;
// q[\startRec].value( "Lat-Scan-85S_85N_2high.wav");
Ndef(\ro).reset.play;
);

/////////////////////////////////////////
(
q.breiten = { NodeProxy.audio(s, 2) } ! 18;

(
q.breiten.do { |px| px.source = { |pan|
	var exc, freqs, son, amps;
	amps = \amps.kr(1 ! 9);
	exc = PinkNoise.ar(1);
	freqs = (0..8).linexp(0, 8, 100, 3000);
	son = BPF.ar(exc, freqs, 0.01) * amps;
	
	Pan2.ar(son.sum * 5, pan)
	
} }
);
);

q.breiten.do(_.stop);
q.breiten.do(_.play);

(
(0..17).normalize(-1, 1).do { |pan, i| q.breiten[i].set(\pan, pan) };
);

(
Tdef(\x, {
		var data, mean;
		data = q.cleanAllData;
		mean = q.cleanAllDataMean;
		data = data - [mean];
		loop {
			data.do { |latData, i|
				latData.do { |dT|
					var amp;
						amp = dT.linexp(-5, 5, 0.01, 1);
						q.breiten[i].setn(\amps, amp);
				};
				0.07.wait;
			};
			q.breiten.do { |px| px.setn(\amps, 0 ! 9) };
			1.wait;
			
		};
}).play;
q.breiten.do(_.play);
);