#include"Prune.h"
/*****************************************************************/
void Prune :: pruneTP(int cn, int sn)
{
double tx1,ty1,tz1;
double tx2,ty2,tz2;
double ipdist;
createLine(PruCom[PruCom[cn].ppi-1],PruCom[cn]);
if(ls -> num==2){ // Current pt is last pt in comptmt.
tx1=PruCom[PruCom[cn].ppi-1].x;
ty1=PruCom[PruCom[cn].ppi-1].y;
tz1=PruCom[PruCom[cn].ppi-1].z;
removeCompartment(cn,sn);
cmr++;
}
else{
// Remove Last Pt.
tx1=ls->x[ls->num-2];
ty1=ls->y[ls->num-2];
tz1=ls->z[ls->num-2];
PruCom[cn].x = ls -> x[ls->num-2];
PruCom[cn].y = ls -> y[ls->num-2];
PruCom[cn].z = ls -> z[ls->num-2];
}
tx2=ls -> x[ls->num-1];
ty2=ls -> y[ls->num-1];
tz2=ls -> z[ls->num-1];
ipdist=sqrt((tx1-tx2)*(tx1-tx2)+ (ty1-ty2)*(ty1-ty2)+
(tz1-tz2)*(tz1-tz2));
if(PruCom[cn].tc==4) // Apical
adlprune[sn] += ipdist/RESLN;
else if (PruCom[cn].tc==3) // Basal
bdlprune[sn] += ipdist/RESLN;
dlr += ipdist/RESLN;
}
/*****************************************************************/
// If the removed compartment's parent is BP, remove the point
// from the TP list, from the BP list (if it is not a
// trifurcation), and update the BP prune numbers and
// probabilities.
/*****************************************************************/
void Prune :: rcParentBP(int cn, int sn)
{
int i,j;
if (PruCom[cn].tc==3) // Basal
bbpprune[sn]++;
else if (PruCom[cn].tc==4) // Apical
abpprune[sn]++;
// Remove pt from TP list
int SET=0;
for(i=0; i<TP.npts; i++)
if(TP.Pts[i]==cn){
SET=1;
break;
}
if(!SET){
cerr <<"\nrcParentBP :: Error, TP not found\n\n";
exit(1);
}
for(j=i;j<TP.npts-1;j++)
TP.Pts[j]=TP.Pts[j+1];
TP.npts--;
// Remove parent from bp list if that point is a bifurcation
if(Children[PruCom[cn].ppi-1].npts==2){
for(i=0; i<BP.npts; i++)
if(BP.Pts[i]==(PruCom[cn].ppi-1)) break;
for(j=i;j<BP.npts-1;j++)
BP.Pts[j]=BP.Pts[j+1];
BP.npts--;
}
}
/*****************************************************************/
// If removed compartment's parent is soma, remove the
// compartment from the TP list and from the Stems list
/*****************************************************************/
void Prune :: rcParentSoma(int cn)
{
int i,j;
// Remove pt from tp list
for(i=0; i<TP.npts; i++)
if(TP.Pts[i]==cn) break;
for(j=i;j<TP.npts-1;j++)
TP.Pts[j]=TP.Pts[j+1];
TP.npts--;
// Remove pt from stems list
for(i=0; i<Stems.npts; i++)
if(Stems.Pts[i]==cn) break;
for(j=i;j<Stems.npts-1;j++)
Stems.Pts[j]=Stems.Pts[j+1];
Stems.npts--;
}
/*****************************************************************/
// The case where the parent is neither soma nor BP
// Implies parent is also dendrite. So, update the TP to the current
// compartment's parent.
/*****************************************************************/
void Prune :: rcParentDendrite(int cn)
{
int i,j;
for(i=0; i<TP.npts; i++)
if(TP.Pts[i]==cn) break;
TP.Pts[i]=PruCom[cn].ppi-1;
// If parent (which is the current TP) has an undefined TC (-1),
// remove that from TP list.
if(PruCom[TP.Pts[i]].tc!=3 && PruCom[TP.Pts[i]].tc!=4){
for(j=i;j<TP.npts-1;j++)
TP.Pts[j]=TP.Pts[j+1];
TP.npts--;
cerr << "\nWarning: Undefined compartment removed from TP list.\n\n";
}
}
/*****************************************************************/
// Remove comptmt cn from PruCom.
// Update the indices of the SWC file to accomodate the
// removal of the compartment number cn. Also updates the parents'
// indices, the TP, BP, Soma list.
/*****************************************************************/
void Prune :: rmcmpt (int cn)
{
int i;
if((PruCom[cn].tc != 3) && (PruCom[cn].tc != 4)){
cerr << "\nrmcmpt :: GRAVE ERROR\n";
exit(1);
}
for(i=cn; i<npc-1; i++){
PruCom[i]=PruCom[i+1];
PruCom[i].pi --; // One comptmt is removed.
}
npc--;
// Update Parent Indices to accomodate above update.
for(i=0; i<npc; i++){
if((PruCom[i].ppi-1)>cn)
PruCom[i].ppi--; // One Comptmt is removed.
}
// Update lists of TP, BP, Stems, Soma to accomodate above.
for(i=0; i<TP.npts; i++)
if(TP.Pts[i]>cn) TP.Pts[i]--;
for(i=0; i<BP.npts; i++)
if(BP.Pts[i]>cn) BP.Pts[i]--;
for(i=0; i<Stems.npts; i++)
if(Stems.Pts[i]>cn) Stems.Pts[i]--;
for(i=0; i<Soma.npts; i++)
if(Soma.Pts[i]>cn) Soma.Pts[i]--;
}
/*****************************************************************/
// Remove the current compartment totally.
// If the parent to this compartment were a BP, then,
// remove that BP from the list of BP's and update BP
// probability; sn stands for the sholl's segment number
/*****************************************************************/
void Prune :: removeCompartment(int cn, int sn)
{
if(isParentBP(cn)) // If parent is BP
rcParentBP(cn,sn);
else if(isParentSoma(cn)) // If parent is Soma
rcParentSoma(cn);
else // If parent is dendrite
rcParentDendrite(cn);
rmcmpt(cn);
}
/*****************************************************************/
//**************** BPPrune starts here **************************/
/*****************************************************************/
void Prune :: findTPBP()
{
int i;
double dist;
int sn;
int trgt;
for(i=0; i<TP.npts; i++){
trgt=TP.Pts[i];
bpPruneP[i]=1.0;
while((isParentBP(trgt)==0) && (isParentSoma(trgt)==0)){
dist = 0.0;
dist += (somax-PruCom[trgt].x)*(somax-PruCom[trgt].x);
dist += (somay-PruCom[trgt].y)*(somay-PruCom[trgt].y);
dist += (somaz-PruCom[trgt].z)*(somaz-PruCom[trgt].z);
dist = sqrt(dist);
sn = (int)(dist/(double)STLENGTH);
if(PruCom[trgt].tc==3) // Basal
bpPruneP[i]*=pow(bdlP[sn], disttoParent(trgt));
else if(PruCom[trgt].tc==4) // Apical
bpPruneP[i]*=pow(adlP[sn], disttoParent(trgt));
trgt=PruCom[trgt].ppi-1;
}
if(isParentBP(trgt))
TPBP[i]=PruCom[trgt].ppi-1;
else if (isParentSoma(trgt))
TPBP[i]=-2;
else{
cerr << "\nTPBP :: There exists some error...\n";
cerr << PruCom[trgt] ;
cerr << PruCom[PruCom[trgt].ppi-1] ;
exit(1);
}
}
}
/*****************************************************************/
// Remove BP which has its TP as ntp'th TP. This is accomplished by
// continually pruning TP[ntp] until a BP is encountered.
/*****************************************************************/
void Prune :: pruneBP(int ntp)
{
int trgt;
// Actually remove the part connecting the TP to the BP by
// recursively pruning TP[ntp] until a branching point is
// encountered.
int ret=0;
int cmcnt=0;
while(!ret){
trgt=TP.Pts[ntp];
ret=removeCmprtmnt(trgt);
cmcnt++;
}
}
/*****************************************************************/
int Prune :: removeCmprtmnt(int cn)
{
double 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);
// Segment where current compartment belongs to
int sn = (int)(dist/(double)STLENGTH);
if (PruCom[cn].tc==3)
bdlprune[sn]+=disttoParent(cn);
else if (PruCom[cn].tc==4)
adlprune[sn]+=disttoParent(cn);
else{
cerr << "\nGravest error\n";
exit(1);
}
int ret=0;
if(isParentBP(cn)){
ret=1;
rcParentBP(cn, sn);
}
else if (isParentSoma(cn)){
cerr << "\nrC :: Grave Error!\n";
}
else
rcParentDendrite(cn);
rmcmpt(cn); // Removing comptmt cn from PruCom.
return ret;
}
/*****************************************************************/