#include"Prune.h"
/*****************************************************************/
void Prune :: initialize()
{
int i;
isRead();
ShollAnalysis();
npc=ncomp;
PruCom=new SWCData[npc];
for(i=0; i<npc; i++)
PruCom[i]=Comptmt[i];
delete(Comptmt);
getSoma();
getStems();
getBP();
getTP();
Children=new Subset[npc] ;
for(i=0; i<npc; i++){
Children[i].npts=0;
Children[i].Pts=new int [3]; // Maximum is trifurcation
}
findChildren();
//generateSpecs(); exit(1);
abpprune=new double[sdata.na]; bbpprune=new double[sdata.nb];
adlprune=new double[sdata.na]; bdlprune=new double[sdata.nb];
abpP =new double[sdata.na]; bbpP =new double[sdata.nb];
adlP =new double[sdata.na]; bdlP =new double[sdata.nb];
for(i=0; i<sdata.na; i++) // Amount of initial pruning is zero
adlprune[i]=abpprune[i]=0;
for(i=0; i<sdata.nb; i++)
bdlprune[i]=bbpprune[i]=0;
cmr=0; // Reduction in number of compartments
dlr=0; // Reduction in dl.
setZeta(basefilename);
//setBasalMaxZeta(basefilename);
setProbabilities();
/* findTPBP requires probabilities to be initialized and hence is called
* after setProbabilities() */
TPBP=new int[TP.npts];
bpPruneP=new double[TP.npts];
findTPBP();
}
/*****************************************************************/
void Prune :: PruneTree()
{
int i;
initialize();
prune();
// cerr << "\nNo. of Soma Pts: " << Soma.npts ;
// cerr << "\nNo. of Stems: " << Stems.npts ;
// cerr << "\nNo. of BP's: " << BP.npts ;
// cerr << "\nNo. of TP's: " << TP.npts << endl ;
char * filename=new char[35];
sprintf(filename,"%s_final.swc",outfilename);
cerr << "\nFinal save in " << filename << " after pruning "
<< dlr << " micron of length" << endl ;
saveSWC(filename);
//printStatus();
}
/*****************************************************************/
void Prune :: prune()
{
int i;
struct timeval tv;
struct timezone tz;
gettimeofday(&tv,&tz);
int SEED=tv.tv_usec;
srand48(SEED);
int count =0;
int scount = 1000; // Save for every 1000 um reduction in DL.
char * filename=new char[35];
//while(convmeasure()>0.05){
while(dlr<dlred){
//while(dlr<dlsum){
//while (count < 5000000){
if(TP.npts==0){
cerr << "\nNo more to Prune...\n";
break;
}
for(i=0; i<TP.npts; i++){
bpPrune(i);
tpPrune(i);
}
//cerr << count << "\t" << cmr << "\t" << dlr << "\t"
// << convmeasure() << endl ;
count ++;
if(dlr>scount){
sprintf(filename,"%s_%d.swc",outfilename,scount);
cerr << "\nSaving file " << filename << " after pruning "
<< dlr << " micron of length" << endl ;
saveSWC(filename);
scount += 1000;
}
}
//cerr << "\nReduction in DL: " << dlr ;
//cerr << "\nReduction in Cmptmt: " << cmr << endl ;
}
/*****************************************************************/
// Prunes TP[i]
void Prune :: tpPrune(int i)
{
double dist;
int l;
int sn; // Segment number
int cn; // Compartment number
int PRUNE;
/* BP has been pruned and the number of TP's has been reduced.
* So, the value of i will be greater than what is allowed. We
* just return back without bothering much as it does not mean
* anything */
if(i>(TP.npts-1)){
return;
}
cn = TP.Pts[i];
dist = 0.0;
dist += (somax-PruCom[cn].x)*(somax-PruCom[cn].x);
dist += (somay-PruCom[cn].y)*(somay-PruCom[cn].y);
dist += (somaz-PruCom[cn].z)*(somaz-PruCom[cn].z);
dist = sqrt(dist);
sn = (int)(dist/(double)STLENGTH); // Segment where TP[i] belongs
PRUNE=0;
if (PruCom[cn].tc==4){ // Apical
if(drand48()*maxdlP<adlP[sn]) PRUNE=1;
}
else if (PruCom[cn].tc==3){ // Basal
if(drand48()*maxdlP<bdlP[sn]) PRUNE=1;
}
else{
cerr << "\ntpP :: Terminal point is not dendrite!!!\n\n";
checkTPs();
cerr << i << endl << PruCom[cn] ;
cerr << Children[cn].npts << endl ;
for(l=0; l<Children[cn].npts; l++){
cerr << PruCom[Children[cn].Pts[l]];
}
exit(1);
}
if(PRUNE){
pruneTP(cn,sn);
//setProbabilities(); // Update probability
findChildren(); // Update children list
findTPBP(); // Update TPBP list
}
}
/*****************************************************************/
// Prunes TPBP[i]
void Prune :: bpPrune(int i)
{
double dist;
int sn; // Segment number
int cn; // Compartment number
int PRUNE;
cn = TPBP[i];
if(cn==-2) return; // Case where the TP does not end on a BP.
dist = 0.0;
dist += (somax-PruCom[cn].x)*(somax-PruCom[cn].x);
dist += (somay-PruCom[cn].y)*(somay-PruCom[cn].y);
dist += (somaz-PruCom[cn].z)*(somaz-PruCom[cn].z);
dist = sqrt(dist);
sn = (int)(dist/(double)STLENGTH); // Segment where TP[i] belongs
PRUNE=0;
if (PruCom[cn].tc==4){ // Apical
//if(drand48()*maxdlP<(bpPruneP[i]*abpP[sn])) PRUNE=1;
if(drand48()*maxdlP<bpPruneP[i]) PRUNE=1;
}
else if (PruCom[cn].tc==3){ // Basal
//if(drand48()*maxdlP<(bpPruneP[i]*bbpP[sn])) PRUNE=1;
if(drand48()*maxdlP<bpPruneP[i]) PRUNE=1;
}
else{
cerr << "\nBranching point is not dendrite!!!\n\n";
//cerr << j << " " << i << " "<< PruCom[cn] ;
exit(1);
}
if(PRUNE){
pruneBP(i);
//setProbabilities(); // Update probability
findChildren();
findTPBP();
}
}
/*****************************************************************/
// Convergence measure.
double Prune :: convmeasure()
{
double cm=0.0;
int i;
/* If the percentage reduction is negative it is not considered. Can be
* reviewed at a later stage. TEST */
for(i=0; i<sdata.na; i++){
if((adlzeta[i]-adlprune[i])/adlzeta[i]>cm)
cm=fabs((adlzeta[i]-adlprune[i])/adlzeta[i]);
if((abpzeta[i]-abpprune[i])/abpzeta[i]>cm)
cm=fabs((abpzeta[i]-abpprune[i])/abpzeta[i]);
}
for(i=0; i<sdata.nb; i++){
if((bdlzeta[i]-bdlprune[i])/bdlzeta[i]>cm)
cm=fabs((bdlzeta[i]-bdlprune[i])/bdlzeta[i]);
if((bbpzeta[i]-bbpprune[i])/bbpzeta[i]>cm)
cm=fabs((bbpzeta[i]-bbpprune[i])/bbpzeta[i]);
}
return cm;
}
/*****************************************************************/
void Prune :: saveSWC(char * filename)
{
char fname[35];
if(!filename) strcpy (fname,outfilename);
else strcpy(fname,filename);
ofstream outfile (fname);
for(int i=0; i<npc; i++)
outfile << PruCom[i] ;
outfile.close();
}
/*****************************************************************/
void Prune :: checkTPs()
{
int cn;
for (int i=0; i<TP.npts; i++){
cn=TP.Pts[i];
if((PruCom[cn].tc != 3) && (PruCom[cn].tc != 4)){
cerr << "\ncheckTPs :: TP not dendrite\n";
exit(1);
}
}
}
/*****************************************************************/