bool IVSCC_smoothing_swc::dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & callback,  QWidget * parent)
{
    if (func_name == tr("smooth_swc"))
    {
        cout<<"Welcome to resample_swc"<<endl;
        vector<char*>* inlist = (vector<char*>*)(input.at(0).p);
        vector<char*>* outlist = NULL;
        vector<char*>* paralist = NULL;

        if(input.size() != 2)
        {
            printf("Please specify both input file and step length parameter.\n");
            return false;
        }
        paralist = (vector<char*>*)(input.at(1).p);
        if (paralist->size()!=1)
        {
            printf("Please specify only two parameters.\n");
            return false;
        }
        double length = atof(paralist->at(0));

        QString fileOpenName = QString(inlist->at(0));
        QString fileSaveName;
        if (output.size()==0)
        {
            printf("No outputfile specified.\n");
            fileSaveName = fileOpenName + QString("_Z_T%1.swc").arg(length);
        }
        else if (output.size()==1)
        {
            outlist = (vector<char*>*)(output.at(0).p);
            fileSaveName = QString(outlist->at(0));
        }
        else
        {
            printf("You have specified more than 1 output file.\n");
            return false;
        }

        vector<MyMarker*> inswc;
        if (fileOpenName.toUpper().endsWith(".SWC") || fileOpenName.toUpper().endsWith(".ESWC"))
            inswc = readSWC_file(fileOpenName.toStdString());

        unsigned char* inimg1d = 0;
        vector<HierarchySegment*> topo_segs;
        swc2topo_segs(inswc, topo_segs, 1, inimg1d, 0, 0, 0);

        cout<<"Smooth the final curve"<<endl;
        for(int i = 0; i < topo_segs.size(); i++)
        {
            HierarchySegment * seg = topo_segs[i];
            MyMarker * leaf_marker = seg->leaf_marker;
            MyMarker * root_marker = seg->root_marker;
            vector<MyMarker*> seg_markers;
            MyMarker * p = leaf_marker;
            while(p != root_marker)
            {
                seg_markers.push_back(p);
                p = p->parent;
            }
            seg_markers.push_back(root_marker);
            smooth_curve_Z(seg_markers, length);
           // smooth_curve_XY(seg_markers, length);
        }
        inswc.clear();

        topo_segs2swc(topo_segs, inswc, 0);
        saveSWC_file(fileSaveName.toStdString(), inswc);
        for(int i = 0; i < inswc.size(); i++) delete inswc[i];

        return true;
    }
	else if (func_name == tr("help"))
	{
		v3d_msg("To be implemented.");
	}
	else return false;

	return true;
}
bool consensus_swc_func(const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 &callback)
{
    if(input.size()==0 || output.size() != 1) return false;
    char * paras = NULL;

    //parsing input
    vector<char *> * inlist =  (vector<char*> *)(input.at(0).p);
    if (inlist->size()==0)
    {
        cerr<<"You must specify input linker or swc files"<<endl;
        return false;
    }

    //parsing output
    vector<char *> * outlist = (vector<char*> *)(output.at(0).p);
    if (outlist->size()>1)
    {
        cerr << "You cannot specify more than 1 output files"<<endl;
        return false;
    }

    //parsing parameters

    int method_code = 1; //adj matrix
    int cluster_distance_threshold = 5; // ignore nodes that far away for clustering
    if (input.size()==2)
    {
        vector<char*> * paras = (vector<char*> *)(input.at(1).p);
        if (paras->size() >= 1)
        {
            method_code = atoi(paras->at(0));
            cout<<"method_code = "<<method_code<<endl;
            if (paras->size() == 2) {
                cluster_distance_threshold =  atoi(paras->at(1));
                cout<<"clustering distance threshold = "<<cluster_distance_threshold<<endl;
            }
        }
        else
        {
            cerr<<"Too many parameters"<<endl;
            return false;
        }
    }

    vector<NeuronTree> nt_list;
    QStringList nameList;
    QString qs_linker;
    char * dfile_result = NULL;
    V3DLONG neuronNum = 0;

    for (int i=0; i<inlist->size(); i++)
    {
        qs_linker = QString(inlist->at(i));
        if (qs_linker.toUpper().endsWith(".ANO"))
        {
            cout<<"(0). reading a linker file."<<endl;
            P_ObjectFileType linker_object;
            if (!loadAnoFile(qs_linker,linker_object))
            {
                fprintf(stderr,"Error in reading the linker file.\n");
                return 1;
            }
            nameList = linker_object.swc_file_list;
            neuronNum += nameList.size();
            for (V3DLONG i=0; i<neuronNum; i++)
            {
                NeuronTree tmp = readSWC_file(nameList.at(i));
                nt_list.push_back(tmp);
            }
        }
        else if (qs_linker.toUpper().endsWith(".SWC"))
        {
            cout<<"(0). reading an swc file"<<endl;
            NeuronTree tmp = readSWC_file(qs_linker);
            nt_list.push_back(tmp);
            neuronNum++;
            if (outlist->size()==0)
            {
                cerr<<"You must specify outfile name if you input a list of swcs"<<endl;
                return false;
            }
        }
    }

    QString outfileName;
    if (outlist->size()==0)
        outfileName = qs_linker + "_consensus.swc";
    else
        outfileName = QString(outlist->at(0));

    QList<NeuronSWC> merge_result;
    if (!consensus_skeleton(nt_list, merge_result, method_code,cluster_distance_threshold, callback))
    {
        cerr<<"error in consensus_skeleton"<<endl;
        return false;
    }

    export_listNeuron_2swc(merge_result,qPrintable(outfileName));
    printf("\t %s has been generated successfully, size:%d.\n",qPrintable(outfileName), merge_result.size());

    return true;
}
예제 #3
0
bool standardize::dofunc(const QString & func_name, const V3DPluginArgList & input, V3DPluginArgList & output, V3DPluginCallback2 & callback,  QWidget * parent)
{
	vector<char*> infiles, inparas, outfiles;
	if(input.size() >= 1) infiles = *((vector<char*> *)input.at(0).p);
	if(input.size() >= 2) inparas = *((vector<char*> *)input.at(1).p);
	if(output.size() >= 1) outfiles = *((vector<char*> *)output.at(0).p);

    if (func_name == tr("standardize"))
	{
        cout<<"This is standardize_swc plugin"<<endl;
        if(infiles.size() <2)
        {
            cerr<<"Need  both the reference swc file ( to seed the soma) and the input swc file."<<endl;
            cerr<<"You can use the input swc file as the reference swc file, if no particular soma location is required." <<endl;
            return false;
        }

        QString  ref_swc_file =  infiles[0];
        QString  inputswc_file = infiles[1];
        if(inputswc_file.isEmpty() || ref_swc_file.isEmpty())
        {
            cerr<<"please check both input swc files"<<endl;
            return false;
        }

        if (inparas.size() <1)
        {
            printf("Please specify two parameters - 1)the gap size for bridging during the sorting step; 2) the type to be assgined.\n");
            return false;
        }


        double dis_th = atof(inparas.at(0));


        int type = -1;//use the old type
        if (inparas.size() ==2)
           type =  atof(inparas.at(1));

        double sort_th = dis_th ; //the parameter in sort_neuron_swc plugin, specifying the length threshold to bridge the gap

        QString  outswc_file =  outfiles[0];

        cout<<"ref_swc_file = "<<ref_swc_file.toStdString().c_str()<<endl;
        cout<<"inswc_file = "<<inputswc_file.toStdString().c_str()<<endl;
        cout<<"gap threshold = "<<dis_th<<endl;
        cout<<"outswc_file = "<<outswc_file.toStdString().c_str()<<endl;
        cout<<"new type code = "<<type<<endl;

        NeuronTree nt_input = readSWC_file(inputswc_file);
//        cout<<" Standardize: 1) resample"<<endl;
//        NeuronTree nt_input_rs = resample(nt_input, dis_th);

        NeuronTree nt_ref = readSWC_file(ref_swc_file);
        double soma_x, soma_y, soma_z, soma_r;
        for (V3DLONG i = 0; i < nt_ref.listNeuron.size(); i++)
        {
            if(nt_ref.listNeuron[i].pn<0)
            {
                soma_x = nt_ref.listNeuron.at(i).x;
                soma_y = nt_ref.listNeuron.at(i).y;
                soma_z = nt_ref.listNeuron.at(i).z;
                soma_r = nt_ref.listNeuron.at(i).r;
                break;
            }
        }

        V3DLONG neuronNum = nt_input.listNeuron.size();
        QVector<QVector<V3DLONG> > children_list = QVector< QVector<V3DLONG> >(neuronNum, QVector<V3DLONG>() );

        for (V3DLONG i = 0; i < neuronNum; i++)
        {
            V3DLONG parent = nt_input.listNeuron[i].pn;
            if (parent < 0)
                continue;
            children_list[nt_input.hashNeuron.value(parent)].push_back(i);
        }

        double Dist = INT_MAX;
        double Dist_inrange = INT_MAX;
        V3DLONG soma_ID = -1;
        V3DLONG dist_ID = -1;
        int child_num = 0;

        cout<<" standardize: 1) matching soma roots"<<endl;
       // set the distance threshold to searching for matching soma node

        QList<NeuronSWC> list_neurons = nt_input.listNeuron;
        double search_distance_th = soma_r * 5 ;// choose the bigger value between soma_r*5 and search_distance_th*5
        if (search_distance_th < sort_th *5)
         {
             search_distance_th = sort_th *5;
         }

        for (V3DLONG i=0;i<list_neurons.size();i++)
        {
            NeuronSWC curr = list_neurons.at(i);
            double nodedist = sqrt(pow2(curr.x - soma_x) + pow2(curr.y - soma_y) + pow2(curr.z - soma_z));
            if(nodedist <= search_distance_th && curr.pn <0)
            {
                soma_ID = curr.n;
                child_num = 1;
                break;
            }

            if(nodedist <= search_distance_th  && children_list[i].size() > child_num)
            {
                soma_ID = curr.n;
                child_num = children_list[i].size();
                Dist_inrange = nodedist;
            }

            if(nodedist <= search_distance_th && children_list[i].size() == child_num && nodedist < Dist_inrange)
            {
                soma_ID = curr.n;
                Dist_inrange = nodedist;
            }

            if(nodedist < Dist)
            {
                dist_ID = curr.n;
                Dist = nodedist;
            }
        }

        if(child_num < 1 || soma_ID == -1) soma_ID = dist_ID;


        cout<<" Standardize: 2) sort"<<endl;
        QList<NeuronSWC> result;
        if (!SortSWC(nt_input.listNeuron, result ,soma_ID, sort_th))
        {
            v3d_msg("fail to call swc sorting function.",0);
            return false;
        }

        cout<<" Standardize: 3) only keep the first tree(identified by the soma from the reference."<<endl;

        //skip the first root
        for (V3DLONG i = 1;i<result.size();i++)
        {
            if (result[i].pn == -1)
            {//remove other trees, only keep the first one
                cout<< "remove "<<result.size()-i<<" nodes"<<endl;
                result.erase(result.begin()+i, result.end());

            }
        }


        cout<<" Standardize: 4) reset type for soma and neurites"<<endl;
        //1-soma
        //2-axon
        //3-dendrite
        //4-apical dendrite

        export_list2file_retype(result,outswc_file,0,type);
	}
	else if (func_name == tr("help"))
	{
        cout << "This super-plugin  is used to post-processing auto reconstructions for comparisons. "<<endl;
        cout << "It will identify the soma for each input reconstruction " <<endl;
        cout << "based on the reference SWC file, and sort SWC nodes based on the soma root while bridging" <<endl;
        cout << "all disconneted components when the gap is less then the specified gap_threshold. The search range "<<endl;
        cout << "for the matching soma  is  5*soma_radius." <<endl;
        cout << "Usage : <vaa3d> -x standardize -f standardize -i <reference_swc_file> <inswc_file> -o <outswc_file> -p <gap_threshold>  <new_neurite_type> "<<endl;
	}
    else
        return false;

	return true;
}