- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# C:/AngioLocalizeNoAuto/MevisLabNoAutoReg/STUMevisApp/General/Sources/ML/STUCSODCMHdrToRTStructure/mlCSODCMHdrToRTStructure.cpp

Go to the documentation of this file.

    00001 /*
    00002 * Copyright (c) 2009 Stanford University, School of Medicine All rights reserved.
    00003 *
    00004 * STANFORD ACADEMIC SOFTWARE LICENSE AGREEMENT
    00005 * FOR AngioLocalize SOURCE CODE:
    00006 *
    00007 * 1.  This is a legal agreement between you, RECIPIENT, and STANFORD UNIVERSITY.
    00008 *       By accepting, receiving, and using AngioLocalize.including any accompanying information, materials or
    00009 *       manuals (Program), you are agreeing to be bound by the terms of this Agreement.
    00010 *       If you do not agree to the terms of this Agreement, promptly return the Program to the STANFORD.
    00011
    00012 * 2.  STANFORD grants to RECIPIENT a royalty-free, nonexclusive, and nontransferable license to use the Program
    00013 *       and accompanying source code furnished hereunder, upon the terms and conditions set out below.
    00014 *       documentation and/or other materials provided with the distribution.
    00015 * 3.  RECIPIENT acknowledges that the Program is a research tool still in the development stage and that
    00016 *       it is being supplied as is, without any accompanying services, support or improvements from STANFORD.
    00017 * 4.  RECIPIENT agrees to use the Program solely for internal non-commercial purposes.
    00018 * 5.  RECIPIENT may create derivatives and further transfer the Program under the following terms and conditions:
    00019 *        A) Recipient agrees to not commercially exploit the Program and agrees all uses will be for non-commercial purposes; and,
    00020 *        B) Recipient may not mark any derivatives with the title of Program and may not to use iPad mark for any derivatives; and,
    00021 *        C) Recipient agrees to mark and acknowledge all derivatives as follows: "This is a derivative work based on AngioLocalize:
    00022 *           Frameless AVM localization with 2D Digital Subtraction Angiography (DSA) and 3D Rotational Angiography (DRA) Images developed
    00023 *           by Dimitre Hristov, Lina Liu.
    00024 *        D) Recipient agrees to make all improvements, enhancements and derivatives available under
    00025 *           similar terms and conditions to the research community.
    00026 * 6.   RECIPIENT warrants that RECIPIENT will not remove or export any part of the software or Program from the United
    00027 *       States except in full compliance with all United States and other applicable laws and regulations.
    00028 * 7.  RECIPIENT will use the Program in compliance with all applicable laws, policies and regulations including, but not
    00029 *       limited to, any approvals, informed consent and patient confidentiality principles.
    00030 * 8.   RECIPIENT will indemnify, hold harmless, and defend Stanford against any claim of any kind arising out of or
    00031 *       related to the exercise of any rights granted under this Agreement or the breach of this Agreement by RECIPIENT.
    00032 * 9.  Title and copyright to the Program and any associated documentation shall at all times remain with STANFORD,
    00033 *       and RECIPIENT agrees to preserve same.
    00034 */
    00035 //----------------------------------------------------------------------------------
    00037
    00044 //----------------------------------------------------------------------------------
    00045
    00046 // Local includes
    00047 #include "mlCSODCMHdrToRTStructure.h"
    00048
    00049 ML_START_NAMESPACE
    00050
    00051
    00053 ML_BASEOP_CLASS_SOURCE(CSODCMHdrToRTStructure, BaseOp);
    00054
    00055 //----------------------------------------------------------------------------------
    00057 //----------------------------------------------------------------------------------
    00058 CSODCMHdrToRTStructure::CSODCMHdrToRTStructure ()
    00059   : BaseOp(0, 0)
    00060 {
    00061   ML_TRACE_IN("CSODCMHdrToRTStructure::CSODCMHdrToRTStructure ()");
    00062
    00063         // Suppress calls of handleNotification on field changes to
    00064   // avoid side effects during initialization phase.
    00065   handleNotificationOff();
    00066
    00068   FieldContainer &fields = *getFieldContainer();
    00069
    00070   _inputCSOs = NULL;
    00071
    00072   ML_CHECK(&fields);
    00073
    00074   (_inListFld = fields.addBase("inCSOList"))->setBaseValue(NULL);
    00075   _dcmObjFld = fields.addBase("inputBase");
    00076   _exportFld = fields.addNotify("export");
    00077   _exportDestinationFld = fields.addString("exportDestination");
    00078   _inputList = NULL;
    00079
    00080   // Connect input fields with output field to update connected
    00081   // modules if input images change.
    00082   for (int inIdx=0; inIdx < 0; ++inIdx){
    00083     for (int outIdx=0; outIdx < 0; ++outIdx){
    00084       getInField(inIdx)->attachField(getOutField(outIdx));
    00085     }
    00086   }
    00087   // Reactivate calls of handleNotification on field changes.
    00088   handleNotificationOn();
    00089 }
    00090
    00091 //----------------------------------------------------------------------------------
    00093 //----------------------------------------------------------------------------------
    00094 void CSODCMHdrToRTStructure::handleNotification (Field *field)
    00095 {
    00096   ML_TRACE_IN("CSODCMHdrToRTStructure::handleNotification ()");
    00097
    00098   // Handle changes of module parameters and connectors here.
    00099         // Handle changes of module parameters and connectors here.
    00100   // check input values
    00101   if (field == _inListFld) {
    00102            Base *csoListB = _inListFld->getBaseValue();
    00103        _inputCSOs = mlbase_cast<CSOList*>(csoListB);
    00104            if (_inputCSOs == NULL) return;
    00105   } else if (field == _dcmObjFld) {
    00106             Base *dcmTreeObj = _dcmObjFld->getBaseValue();
    00107         RTStructure *_RTStructure = mlbase_cast<RTStructure*>(dcmTreeObj);
    00108                 if(_RTStructure == NULL)
    00109                         return;
    00110                 DCMTree::TreePtr _tree(new DCMTree::Tree());
    00111         _tree->fromStream(_RTStructure->stream, true);
    00112                 if (_tree->tagsSize() == 0)
    00113                         return;
    00114                 else
    00115                         _inputTree = _tree;
    00116                 combineCSOs();
    00117   } else if (field == _exportFld) {
    00118           if(_inputCSOs == NULL || _inputTree->tagsSize() == 0 || _exportDestinationFld->getStringValue().empty())
    00119                   return;
    00120           if (!checkCSOList())
    00121                    return;
    00122           combineCSOs();
    00123
    00124           DCMTree::TagPtr SOPInstUIDTag = _inputTree->getTag_rw(DCMTree::TagId(0x0002,0x0003));
    00125                 if (!DCMTree_Utils::UIDGenerator::isInitialized()) {
    00126                         DCMTree_Utils::UIDGenerator::initialize("1.2.276.0.28","3","42");
    00127                 }
    00128           std::string generatedUID = DCMTree_Utils::UIDGenerator::uid();
    00129           SOPInstUIDTag->setValue(generatedUID);
    00130           DCMTree::TagPtr SOPInstUIDTag2 = _inputTree->getTag_rw(DCMTree::TagId(0x0008,0x0018));
    00131           SOPInstUIDTag2->setValue(generatedUID);
    00132           std::ifstream ifile(_exportDestinationFld->getStringValue().c_str());
    00133           if (ifile) {
    00134                   ifile.close();
    00135                   remove(_exportDestinationFld->getStringValue().c_str());
    00136           }
    00137       writeToDCMFile(_inputTree, _exportDestinationFld->getStringValue());
    00138   }
    00139 }
    00140
    00141 //----------------------------------------------------------------------------------
    00143 //----------------------------------------------------------------------------------
    00144 bool CSODCMHdrToRTStructure::writeToDCMFile(DCMTree::TreePtr tree, std::string dest) {
    00145
    00146         try {
    00147
    00148         DCMTree::MessagePtr messagePtr = DCMTree::MessagePtr(
    00149       new DCMTree::Message(DCMTree_Unicode::UTF8CharacterSet(), DCMTree::IMPLICIT_LITTLE_ENDIAN));
    00150     messagePtr->setTags(tree);
    00151
    00152     // Create writer object
    00153         DCMTree::WriterPtr writer = DCMTree::Writer::create(DCMTree::Dict::singleton());
    00154
    00155     // Write message
    00156         DCMTree::IOParameterPtr param(DCMTree::IOParameter::create(dest));
    00157    writer->write(param, messagePtr);
    00158         } catch(DCMTree::Exception& ex){
    00159                 ML_PRINT_ERROR("CSODCMHdrToRTStructure::_HandleNotification",ML_BAD_PARAMETER, ex.toString().c_str());
    00160                 return false;
    00161         }
    00162         return true;
    00163 }
    00164
    00165 //----------------------------------------------------------------------------------
    00167 //----------------------------------------------------------------------------------
    00168 void CSODCMHdrToRTStructure::combineCSOs() {
    00169         insertCSOGroup();
    00170         insertCSOList();
    00171         insertObservation();
    00172
    00173 }
    00174 //----------------------------------------------------------------------------------
    00176 //----------------------------------------------------------------------------------
    00177 bool CSODCMHdrToRTStructure::checkCSOList(){
    00178         unsigned int totalCSOs = 0;
    00179
    00180         for(unsigned int i = 0; i < _inputCSOs->numGroups(); i++){
    00181            CSOGroup * group = _inputCSOs->getGroupAt(i);
    00182            if (group->getLabel().length() == 0) {
    00183                    //warning
    00184                    ML_PRINT_WARNING("mlCSOToRTStructure::_checkCSOList",ML_BAD_PARAMETER, "group label is missing");
    00185                    return false;
    00186            }
    00187            totalCSOs += group->numCSO();
    00188         }
    00189         if (totalCSOs != _inputCSOs->numCSO()) {
    00190                 //give warning!
    00191                 ML_PRINT_ERROR("mlCSOToRTStructure::_checkCSOList",ML_BAD_PARAMETER, "CSO must belong to a group.");
    00192                 return false;
    00193         }
    00194         // check if each CSO has a ReferenceID
    00195         for(unsigned int i = 0; i < _inputCSOs->numGroups(); i++){
    00196            CSOGroup * group = _inputCSOs->getGroupAt(i);
    00197            for (unsigned int csoInd = 0; csoInd < group->numCSO(); csoInd ++) {
    00198                    std::string desc = group->getCSOAt(csoInd)->getDescription();
    00199                    if (desc.empty() || desc.find_first_of(":") ==  desc.length()-1){
    00200                                 ML_PRINT_ERROR("mlCSOToRTStructure::_checkCSOList",ML_BAD_PARAMETER, "CSO must have a desc including ReferencedSOPClassUID and ReferencedSOPInstanceUID, otherwise the program cannot proceed.");
    00201                    }
    00202            }
    00203         }
    00204    return true;
    00205 }
    00206 //----------------------------------------------------------------------------------
    00208 //----------------------------------------------------------------------------------
    00209 void CSODCMHdrToRTStructure::insertCSOGroup() {
    00210    if(_inputCSOs == NULL)
    00211            return;
    00212     DCMTree::Const_TagPtr sopTagPtr = _inputTree->getTag(DCMTree::TagId(0x0008,0x0018));
    00213    //get a handle of groupID in DCM file
    00214    DCMTree::TagPtr groupTagPtr = _inputTree->getTag_rw(DCMTree::TagId(0x3006,0x0020));
    00215    if (!groupTagPtr->isSequence())
    00216            return;
    00217    unsigned int seqNum = groupTagPtr->numberOfSequenceItems();
    00218    unsigned int groupNum = _inputCSOs->numGroups();
    00219    if (seqNum == groupNum) {
    00220    // get the group from CSO list
    00221            copyCSOGroups(groupTagPtr, groupNum);
    00222    }else if(seqNum > groupNum) {
    00223       copyCSOGroups(groupTagPtr, groupNum);
    00224           groupTagPtr->sequenceItems().erase(groupTagPtr->sequenceItems().begin() + groupNum,
    00225                   groupTagPtr->sequenceItems().begin() + seqNum);
    00226    } else {
    00227           DCMTree::TreePtr embeddedTreePtr = groupTagPtr->sequenceItems()[seqNum -1];
    00228           for (unsigned int rest = seqNum; rest < groupNum; rest++) {
    00229                         groupTagPtr->addSequenceItem(embeddedTreePtr->copy());
    00230           }
    00231       copyCSOGroups(groupTagPtr, groupNum);
    00232    }
    00233 }
    00234
    00235 //----------------------------------------------------------------------------------
    00237 //----------------------------------------------------------------------------------
    00238 void  CSODCMHdrToRTStructure::copyCSOGroups(DCMTree::TagPtr groupTagPtr, unsigned int num) {
    00239         if(_inputCSOs == NULL)
    00240                         return;
    00241         for (unsigned int i = 0; i < num; i ++ ){
    00242                    CSOGroup * aGroup = _inputCSOs->getGroupAt(i);
    00243                    DCMTree::TreePtr embeddedTreePtr = groupTagPtr->sequenceItems()[i];
    00244                    int groupId = (int) aGroup->getId();
    00245                    std::string ROIName = aGroup->getLabel();
    00246                    std::string desc = aGroup->getDescription();
    00247                    std::string uid = desc.substr(0, desc.find_first_of(":"));
    00248            std::string alg("");
    00249                    if (desc.find_first_of(":") < desc.length()-1)
    00250                           alg = desc.substr(desc.find_first_of(":") + 1, desc.length()-1);
    00251                    DCMTree::TagPtr ROINumTagPtr = embeddedTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0022));
    00252                    ROINumTagPtr->dropValues();
    00253                    ROINumTagPtr->addValue(groupId);
    00254                    DCMTree::TagPtr ROILabelTagPtr = embeddedTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0026));
    00255                    ROILabelTagPtr->setValue(ROIName);
    00256                    DCMTree::TagPtr ROIUIDTagPtr  = embeddedTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0024));
    00257                          ROIUIDTagPtr->setValue(uid);
    00258                    DCMTree::TagPtr ROIAlgTagPtr = embeddedTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0036));
    00259                    ROIAlgTagPtr->dropValues();
    00260                    if (alg.length() != 0)
    00261                          ROIAlgTagPtr->addValue(alg);
    00262                 }
    00263 }
    00264
    00265 //----------------------------------------------------------------------------------
    00267 //----------------------------------------------------------------------------------
    00268 void  CSODCMHdrToRTStructure::insertCSOList() {
    00269         if(_inputCSOs == NULL)
    00270                         return;
    00271     tagPtr = _inputTree->getTag_rw(DCMTree::TagId(0x3006,0x0039));
    00272     if (tagPtr == NULL || !tagPtr->isSequence())
    00273                 return;
    00274     unsigned int seqNum = tagPtr->numberOfSequenceItems();
    00275
    00276     unsigned int groupNum = _inputCSOs->numGroups();
    00277         if (seqNum > groupNum) {
    00278                 tagPtr->sequenceItems().erase(tagPtr->sequenceItems().begin()+groupNum,
    00279            tagPtr->sequenceItems().begin()+seqNum);
    00280         }else if (seqNum < groupNum) {
    00281                     DCMTree::TreePtr seq(tagPtr->sequenceItems()[0]);
    00282                         tagPtr->addSequenceItem(seq);
    00283         }
    00284         for (unsigned int i = 0; i < groupNum; i++) {
    00285                 DCMTree::TreePtr embeddedTreePtr = tagPtr->sequenceItems()[i];
    00286                 CSOGroup* group = _inputCSOs->getGroupAt(i);
    00287                 ml::vec3 color = group->getColor();
    00288
    00289     DCMTree::TagPtr colorTagPtr = embeddedTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x002a));
    00290                 colorTagPtr->dropValues();
    00291                 colorTagPtr->addValue(color[0]*255.0);
    00292           colorTagPtr->addValue(color[1]*255.0);
    00293           colorTagPtr->addValue(color[2]*255.0);
    00294
    00295                 // find the tagPtr for "ReferencedROINumber" -- groupNum
    00296           DCMTree::TagPtr refROITagPtr = embeddedTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0084));
    00297                 refROITagPtr->dropValues();
    00298                 refROITagPtr->addValue((int) group->getId());
    00299
    00300     // find the tagPtr for "ContourSequence"
    00301           DCMTree::TagPtr contourSeqTagPtr = embeddedTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0040));
    00302     if (contourSeqTagPtr == NULL || contourSeqTagPtr->isEmpty() || !contourSeqTagPtr->isSequence())
    00303                    return;
    00304           int numContours = (int) contourSeqTagPtr->numberOfSequenceItems();
    00305     int numCSOs = group->numCSO();
    00306            //add or delete numContours so that it == numCSOs
    00307           if (numContours < numCSOs) {
    00308                         for (int rest = numContours; rest < numCSOs; rest ++){
    00309                            DCMTree::TreePtr seq(contourSeqTagPtr->sequenceItems()[0]);
    00310                            contourSeqTagPtr->addSequenceItem(seq);
    00311                    }
    00312           } else if (numContours > numCSOs) {
    00313            //for (int rest = numCSOs; rest < numContours; rest ++)
    00314                    contourSeqTagPtr->sequenceItems().erase(contourSeqTagPtr->sequenceItems().begin()+numCSOs,
    00315        contourSeqTagPtr->sequenceItems().begin()+numContours);
    00316                    //unsigned int num = contourSeqTagPtr->numberOfSequenceItems();
    00317                    //unsigned int numSeq = num;
    00318            }
    00319      for (unsigned int imgSeqIndex = 0; imgSeqIndex < group->numCSO(); imgSeqIndex ++) {
    00320                    DCMTree::TreePtr contourSeqTreePtr = contourSeqTagPtr->sequenceItems()[imgSeqIndex];
    00321        CSO* aCSO = group->getCSOAt(imgSeqIndex);
    00322        DCMTree::TagPtr geoTagPtr = contourSeqTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0042));
    00323                    int numPts = (int) aCSO->numSeedPoints();
    00324                    if (numPts == 1){
    00325                                  geoTagPtr->addValue("POINT");
    00326                    } else {
    00327                            bool closed = aCSO->isClosed();
    00328                            bool inPlane = false;
    00329                            if (closed == false)
    00330                                    inPlane = aCSO->isInPlane();
    00331                            geoTagPtr->dropValues();
    00332                            if (closed){
    00333                                    geoTagPtr->addValue("CLOSED_PLANAR");
    00334                            }else if(inPlane) {
    00335                                    geoTagPtr->addValue("OPEN_PLANAR");
    00336                            }else {
    00337                                    geoTagPtr->addValue("OPEN_NONPLANAR");
    00338                            }
    00339                    }
    00340
    00341             DCMTree::TagPtr numTagPtr = contourSeqTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0046));
    00342                         //unsigned int numContours = numTagPtr->toInt();
    00343                         numTagPtr->dropValues();
    00344                         numTagPtr->addValue(numPts);
    00345
    00346                          DCMTree::TagPtr conTagPtr = contourSeqTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0050));
    00347                          conTagPtr->dropValues();
    00348                          for (unsigned int sedIndex = 0; sedIndex < aCSO->numSeedPoints(); sedIndex ++) {
    00349                                                 ml::CSOSeedPoint* pt = aCSO->getSeedPointAt(sedIndex);
    00350                                                 vec3 pos = pt->worldPosition;
    00351                                                 for (int posInd = 0; posInd < 3; posInd++) {
    00352                                                         conTagPtr->addValue(pos[posInd]);
    00353                                                 }
    00354                          }
    00355                          DCMTree::TagPtr contourImgSeqTagPtr = contourSeqTreePtr->getTag_rw(DCMTree::TagId(0x3006,0x0016));
    00356                          if (contourImgSeqTagPtr != NULL && contourImgSeqTagPtr->isSequence()) {
    00357                                 for (unsigned int imgSeqIndex = 0; imgSeqIndex < contourImgSeqTagPtr->numberOfSequenceItems(); imgSeqIndex ++) {
    00358                                                 DCMTree::TreePtr contourImgSeqTreePtr = contourImgSeqTagPtr->sequenceItems()[imgSeqIndex];
    00359                                                 DCMTree::TagPtr refImgTagPtr = contourImgSeqTreePtr->getTag_rw(DCMTree::TagId(0x0008, 0x1150));
    00360                                                 DCMTree::TagPtr refImgFrameTagPtr = contourImgSeqTreePtr->getTag_rw(DCMTree::TagId(0x0008, 0x1155));
    00361                                                 std::string desc(aCSO->getDescription());
    00362                                                 if (!desc.empty()) {
    00363                                                         std::string image = desc.substr(0, desc.find_first_of(":"));
    00364                                                         std::string frame = desc.substr(desc.find_first_of(":")+1, desc.length() -1);
    00365                                                         refImgTagPtr->dropValues();
    00366                                                         refImgTagPtr->addValue(image);
    00367                                                         refImgFrameTagPtr->dropValues();
    00368                                                         refImgFrameTagPtr->addValue(frame);
    00369                                                 }
    00370                                 }
    00371                          }
    00372         }
    00373         }
    00374 }
    00375
    00376 //----------------------------------------------------------------------------------
    00378 //----------------------------------------------------------------------------------
    00379 void  CSODCMHdrToRTStructure::insertObservation() {
    00380         if(_inputCSOs == NULL)
    00381                         return;
    00382         DCMTree::TagPtr tagPtr = _inputTree->getTag_rw(DCMTree::TagId(0x3006,0x0080));
    00383     if (tagPtr == NULL || !tagPtr->isSequence())
    00384                 return;
    00385     unsigned int seqNum = tagPtr->numberOfSequenceItems();
    00386         unsigned int grpNum = _inputCSOs->numGroups();
    00387         std::vector<int> CSOGrpIds;
    00388         for (unsigned int i = 0; i < grpNum; i ++) {
    00389                 CSOGrpIds.push_back((int)_inputCSOs->getGroupAt(i)->getId());
    00390         }
    00391         if (seqNum > grpNum) {
    00392                 DCMTree::TreePtrVector::iterator seqIter = tagPtr->sequenceItems().begin();
    00393                 while(seqIter != tagPtr->sequenceItems().end()) {
    00394                         DCMTree::TreePtr treePtr = *seqIter;
    00395                         DCMTree::TagPtr tagPtr1 = treePtr->getTag_rw(DCMTree::TagId("0x3006,0x0084"));
    00396                         std::vector <int>::iterator it = (find(CSOGrpIds.begin(), CSOGrpIds.end(), tagPtr1->toInt()));
    00397                         if (it == CSOGrpIds.end())
    00398                                 seqIter = tagPtr->sequenceItems().erase(seqIter);
    00399                         else
    00400                                 ++seqIter;
    00401                 }
    00402         }
    00403 }
    00404
    00405 //----------------------------------------------------------------------------------
    00407 //----------------------------------------------------------------------------------
    00408 BaseOp::INPUT_HANDLE CSODCMHdrToRTStructure::handleInput(int /*inIndex*/, INPUT_STATE /*state*/) const
    00409 {
    00410   ML_TRACE_IN("test::handleInput ()");
    00411
    00412   return INVALIDATE;
    00413 }
    00414
    00415 ML_END_NAMESPACE
    00416

All Classes Namespaces Files Functions Variables Enumerator Friends