- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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

    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 "STUCSOToRTStructure.h"
    00048 #include <boost/filesystem/operations.hpp>
    00049 #include <boost/filesystem/fstream.hpp>
    00050 #include "mlDicomTreeImagePropertyExtension.h"
    00051 #include "mlDicomTreeAccess.h"
    00052 #include "DCMTree_StructuredMF.h"
    00053
    00054 #include <iostream>
    00055 #include <time.h>
    00056
    00057 using namespace boost::filesystem;
    00058 using namespace std;
    00059
    00060 ML_START_NAMESPACE
    00061
    00063 ML_BASEOP_CLASS_SOURCE(CSOToRTStructure, BaseOp);
    00064
    00065 std::map<std::string, std::string> CSOToRTStructure::_modalitySOPClassUIDMap;
    00066
    00067
    00068 //----------------------------------------------------------------------------------
    00070 //----------------------------------------------------------------------------------
    00071 CSOToRTStructure::CSOToRTStructure ()
    00072   : BaseOp(1, 1)
    00073 {
    00074   ML_TRACE_IN("CSOToRTStructure::CSOToRTStructure ()");
    00075
    00076   // Suppress calls of handleNotification on field changes to
    00077   // avoid side effects during initialization phase.
    00078   handleNotificationOff();
    00080   FieldContainer &fields = *getFieldContainer();
    00081   getInField(0)->attachField(getOutField(0));
    00082   _inputCSOs = NULL;
    00083
    00084   ML_CHECK(&fields);
    00085
    00086   (_inListFld = fields.addBase("inCSOList"))->setBaseValue(NULL);
    00087
    00088   _rtStructFileFld = fields.addString("rtStructFile");
    00089   _applyFld = fields.addNotify("apply");
    00090   _validFld = fields.addToggle("valid");
    00091   _validFld->setIntValue(false);
    00092   //_inListFld->attachField(_validFld);
    00093   // Reactivate calls of handleNotification on field changes.
    00094   handleNotificationOn();
    00095 }
    00096
    00097 //----------------------------------------------------------------------------------
    00099 //----------------------------------------------------------------------------------
    00100 void CSOToRTStructure::handleNotification (Field *field) {
    00101   ML_TRACE_IN("CSOToRTStructure::handleNotification ()");
    00102
    00103   // Handle changes of module parameters and connectors here.
    00104   // check input values
    00105   if (field == _inListFld) {
    00106     if ( !_isInNotificationCB ) {
    00107                 CSOList::removeNotificationObserverFromAllCSOLists( CSOListNotifyObserverCB,
    00108                 this);
    00109         }
    00110     Base *csoListB = _inListFld->getBaseValue();
    00111     _inputCSOs = mlbase_cast<CSOList*>(csoListB);
    00112     if (_inputCSOs == NULL) {
    00113                 return;
    00114     }
    00115     if (!_isInNotificationCB) {
    00116                 _inputCSOs->addNotificationObserver(CSOListNotifyObserverCB, this);
    00117     }
    00118   }else if (field == _applyFld){
    00119                 if (_rtStructFileFld->getStringValue().empty()) {
    00120                         ML_PRINT_ERROR("mlCSOToRTStructure::_HandleNotification",ML_BAD_PARAMETER, "File name needs to be provided.");
    00121                   return;
    00122                 }
    00123          if (_treeHeaderPtr != NULL) {
    00124            DCMTree::TreePtr myNewTree(new DCMTree::Tree());
    00125            _genTreePtr = myNewTree;
    00126            if (combineHeader() == true) {
    00127                          writeToDCMFile(_genTreePtr, _rtStructFileFld->getStringValue());
    00128           }
    00129         }
    00130         }else if (field->getName() == "input0"){
    00131                 //setValid(this);
    00132         } else {
    00133     //ML_PRINT_ERROR("mlCSOToRTStructure::_HandleNotification",ML_BAD_PARAMETER, "There is no DICOM header information in the provided input image. RTStructure file cannot be generated.");
    00134                 return;
    00135         }
    00136   setValid(this);
    00137 }
    00138
    00139 //----------------------------------------------------------------------------------
    00141 //----------------------------------------------------------------------------------
    00142 void CSOToRTStructure::CSOListNotifyObserverCB(void* userData, int notificationFlag)
    00143 {
    00144   CSOToRTStructure* myInst = static_cast<CSOToRTStructure*>(userData);
    00145   myInst->_isInNotificationCB = true;
    00146   if ( (notificationFlag & CSOList::NOTIFICATION_CSO_FINISHED   ) ||
    00147        (notificationFlag & CSOList::NOTIFICATION_GROUP_FINISHED ) ||
    00148        (notificationFlag & CSOList::NOTIFICATION_CSO_SELECTION  ) ||
    00149        (notificationFlag & CSOList::NOTIFICATION_GROUP_SELECTION) ){
    00150       // Do your notification handling here
    00151     setValid(myInst);
    00152   }
    00153   myInst->_isInNotificationCB = false;
    00154 }
    00155
    00156 //----------------------------------------------------------------------------------
    00158 //----------------------------------------------------------------------------------
    00159 void CSOToRTStructure::setValid(CSOToRTStructure* obj)
    00160 {
    00161   if (obj->getTreeHeaderPtr() == NULL && obj->getUpdatedInImg(0) != NULL) {
    00162     PagedImg *img = obj->getUpdatedInImg(0);
    00163         obj->updateGenTreeHeader(img);
    00164   }
    00165   if (obj->getUpdatedInImg(0) == NULL || obj->getInputCSOs() == NULL || obj->getInputCSOs()->numCSO() == 0) {
    00166         obj->setValidFld(false);
    00167
    00168   }else {
    00169         obj->setValidFld(true);
    00170   }
    00171 }
    00172
    00173 //----------------------------------------------------------------------------------
    00175 //----------------------------------------------------------------------------------
    00176 void CSOToRTStructure::activateAttachments ()
    00177 {
    00178   ML_TRACE_IN("test::activateAttachments ()");
    00179
    00180   // Update members to new field state here.
    00181   // Call super class functionality to enable notification handling again.
    00182   // For details see section "Module Persistence and Overloading activateAttachments()"
    00183   // in ML Programming Guide.
    00184   BaseOp::activateAttachments ();
    00185 }
    00186
    00187 //----------------------------------------------------------------------------------
    00189 //----------------------------------------------------------------------------------
    00190 BaseOp::INPUT_HANDLE CSOToRTStructure::handleInput(int /*inIndex*/, INPUT_STATE /*state*/) const
    00191 {
    00192   ML_TRACE_IN("ChamferMatching::handleInput ()")
    00193
    00194   return INVALIDATE;
    00195 }
    00196
    00197 //----------------------------------------------------------------------------------
    00199 //----------------------------------------------------------------------------------
    00200 bool CSOToRTStructure::combineSOPInstUID(DCMTree::TagPtr conImageTag, std::string SOPCUID){
    00201   if (_mSOPInstUIDs.size() == 0) {
    00202                 return false;
    00203   }
    00204   for(std::map<float,std::string>::const_iterator it = _mSOPInstUIDs.begin(); it != _mSOPInstUIDs.end(); ++it) {
    00205     DCMTree::TreePtr childTree(new DCMTree::Tree());
    00206         conImageTag->addSequenceItem(childTree);
    00207         addTag(childTree, DCMTree::TagId(0x0008,0x1150), SOPCUID, DCMTree::UI);
    00208         addTag(childTree, DCMTree::TagId(0x0008,0x1155),it->second, DCMTree::UI);
    00209
    00210   }
    00211   return true;
    00212 }
    00213
    00214 //----------------------------------------------------------------------------------
    00216 //----------------------------------------------------------------------------------
    00217 void CSOToRTStructure::updateGenTreeHeader(PagedImg *img) {
    00218         if (!DCMTree_Utils::UIDGenerator::isInitialized()) {
    00219                 // Add initClass calls from all other modules here...
    00220                 DCMTree_Utils::UIDGenerator::initialize("1.2.276.0.28","3","42");
    00221            // init the modality and SOPClassUID map
    00222                 CSOToRTStructure::_modalitySOPClassUIDMap.insert(std::pair<std::string,std::string>("RTSTRUCT","1.2.840.10008.5.1.4.1.1.481.3"));
    00223         }
    00224
    00225   const RuntimeType*               runtimeType       = DicomTreeImagePropertyExtension::getClassTypeId();
    00226   ImagePropertyExtensionContainer& propertyContainer = img->getImagePropertyContainer();
    00227
    00228   if ( propertyContainer.getNumEntries() > 0 ){
    00229     DicomTreeImagePropertyExtension* propertyExtension = reinterpret_cast<DicomTreeImagePropertyExtension*>
    00230                                                                                                                    (propertyContainer.getFirstEntryOfType(runtimeType));
    00231         DCMTree::Const_TreePtr           dicomTreePtr      = getDicomTreeFromImagePropertyExtension(propertyExtension);
    00232         if (dicomTreePtr == NULL)
    00233                 return;
    00234         ml::Vector ext = img->getImgExt();
    00235         DCMTree::TreePtr                 childTreePtr(new DCMTree::Tree());
    00236         childTreePtr = dicomTreePtr->copy();
    00237         DCMTree::StructuredMF structuredMF( childTreePtr, ext[2], ext[4], ext[5]);
    00238         // Get the extent of the dicom tree.
    00239         const DCMTree::StructuredMF::IndexVector& indices = structuredMF.getGridExtent();
    00240         if ( indices.size() > 0 ) {
    00241           unsigned int num = indices[0];
    00242           DCMTree::TagPtr tagTPtr = structuredMF.tagForGridPosition_rw( DCMTree::TagId(0x0008,0x0033), 0, 0);
    00243           std::string  tagTS=tagTPtr->toString();
    00244           for (unsigned int z=0; z< num; ++z) {
    00245                 // Get the tag at slice z.
    00246                 DCMTree::TagInfo info(DCMTree::TagId(0x0008,0x0018), DCMTree::UI, DCMTree::TagValueMultiplicity(1,1));
    00247                 DCMTree::TagPtr newTag(new DCMTree::Tag(info));
    00248                 structuredMF.setTagForGridPosition(newTag, z, 0);
    00249                 string SOPInstUID = DCMTree_Utils::UIDGenerator::uid();
    00250                 newTag->addValue(SOPInstUID);
    00251                 img->getVoxelSize(NULL, NULL, &_voxelSizeZ);
    00252                 ml::vec3 vec(0,0,z);
    00253                 ml::vec3 vecWorld;
    00254                 img->transformToWorldCoord(vec,vecWorld);
    00255                 float worldPosZ = vecWorld[2];
    00256                 _mSOPInstUIDs.insert(pair<float,std::string>(worldPosZ,SOPInstUID));
    00257           }
    00258         }
    00259         _treeHeaderPtr = childTreePtr;
    00260   }
    00261 }
    00262
    00263 //----------------------------------------------------------------------------------
    00265 //----------------------------------------------------------------------------------
    00266 void  CSOToRTStructure::calcOutImageProps (int /*outIndex*/){
    00267   ml::PagedImg* img = getOutImg();
    00268   if (img == NULL)
    00269     return;
    00270
    00271   updateGenTreeHeader(img);
    00272   if (_treeHeaderPtr == NULL) return;
    00273   const RuntimeType*               runtimeType       = DicomTreeImagePropertyExtension::getClassTypeId();
    00274   ImagePropertyExtensionContainer& outPropertyContainer = getOutImg(0)->getImagePropertyContainer();
    00275   DicomTreeImagePropertyExtension* outPropertyExtension = reinterpret_cast<DicomTreeImagePropertyExtension*>
    00276                                                                                                            (outPropertyContainer.getFirstEntryOfType(runtimeType));
    00277   if (outPropertyExtension!= NULL)
    00278     outPropertyExtension->setDicomTagTree(_treeHeaderPtr);
    00279 }
    00280
    00281 CALC_OUTSUBIMAGE1(CSOToRTStructure);
    00282 //----------------------------------------------------------------------------------
    00284 //----------------------------------------------------------------------------------
    00285 std::string  CSOToRTStructure::getRefUID(double z)
    00286 {
    00287   float key = 0;
    00288   float minDist = _voxelSizeZ/2 + 0.0002;
    00289   for(std::map<float,std::string>::const_iterator it = _mSOPInstUIDs.begin(); it != _mSOPInstUIDs.end(); ++it) {
    00290     if (minDist > abs(it->first - z)) {
    00291           minDist = abs(it->first - z);
    00292           key = it->first;
    00293         }
    00294   }
    00295   if (key != 0) {
    00296         std::map<float,std::string>::const_iterator rt = _mSOPInstUIDs.find(key);
    00297         return rt->second;
    00298   } else
    00299         return "";
    00300 }
    00301
    00302 //----------------------------------------------------------------------------------
    00304 //----------------------------------------------------------------------------------
    00305 void CSOToRTStructure::addSequence(DCMTree::TreePtr parentTree, DCMTree::TreePtr childTree, DCMTree::TagId tagId)
    00306 {
    00307   addSequenceTag(parentTree, tagId);
    00308   DCMTree::TagPtr childSeq = parentTree->getTag_rw(tagId);
    00309   childSeq->addSequenceItem(childTree);
    00310 }
    00311
    00312 //----------------------------------------------------------------------------------
    00314 //----------------------------------------------------------------------------------
    00315 void CSOToRTStructure::addSequenceTag(DCMTree::TreePtr &parent, DCMTree::TagId tagId)
    00316 {
    00317   DCMTree::TagInfo info(tagId, DCMTree::SQ, DCMTree::TagValueMultiplicity(1,0xffff));
    00318   DCMTree::TagPtr newTag(new DCMTree::Tag(info));
    00319   parent->addTag(tagId, newTag);
    00320 }
    00321
    00322
    00323 //----------------------------------------------------------------------------------
    00325 //----------------------------------------------------------------------------------
    00326 void CSOToRTStructure::addTag(DCMTree::TreePtr &parent, DCMTree::TagId tagId, std::string value, DCMTree::Vr vr)
    00327 {
    00328   DCMTree::TagInfo info(tagId, vr, DCMTree::TagValueMultiplicity(1,1));
    00329   DCMTree::TagPtr newTag(new DCMTree::Tag(info));
    00330   newTag->addValue(value);
    00331   parent->addTag(tagId, newTag);
    00332 }
    00333
    00334 //----------------------------------------------------------------------------------
    00336 //----------------------------------------------------------------------------------
    00337 bool CSOToRTStructure::combineHeader()
    00338 {
    00339   _genTreePtr->addTag(DCMTree::TagId(0x0002,0x0000), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0000)));
    00340   _genTreePtr->addTag(DCMTree::TagId(0x0002,0x0001), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0001)));
    00341   _genTreePtr->addTag(DCMTree::TagId(0x0002,0x0002), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0002)));
    00342   addTag(_genTreePtr, DCMTree::TagId(0x0002,0x0002), _modalitySOPClassUIDMap["RTSTRUCT"], DCMTree::UI);
    00343   _genTreePtr->addTag(DCMTree::TagId(0x0002,0x0003), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0003)));
    00344   _genTreePtr->addTag(DCMTree::TagId(0x0002,0x0010), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0010)));
    00345   _genTreePtr->addTag(DCMTree::TagId(0x0002,0x0012), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0012)));
    00346
    00347         time_t now;
    00348         struct tm *timeinfo;
    00349   char buffer[10];
    00350         char buffer1[10];
    00351         time(&now);
    00352   timeinfo = localtime(&now);
    00353         strftime(buffer, 10, "%H%M%S",timeinfo);
    00354   strftime(buffer1, 10, "%Y%m%d",timeinfo);
    00355         addTag(_genTreePtr, DCMTree::TagId(0x0008, 0x0012), buffer1, DCMTree::DA);
    00356         addTag(_genTreePtr, DCMTree::TagId(0x0008, 0x0013), buffer, DCMTree::TM);
    00357
    00358   string transferSUID = _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0010))->toString();
    00359         addTag(_genTreePtr, DCMTree::TagId(0x0008,0x0016), _modalitySOPClassUIDMap["RTSTRUCT"], DCMTree::UI);
    00360         //generate the SOP Instance UID for the RT structure file
    00361         addTag(_genTreePtr, DCMTree::TagId(0x0008,0x0018),DCMTree_Utils::UIDGenerator::uid(), DCMTree::UI);
    00362         _genTreePtr->addTag(DCMTree::TagId(0x0008,0x0020), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x0020)));
    00363         _genTreePtr->addTag(DCMTree::TagId(0x0008,0x0030), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x0030)));
    00364         _genTreePtr->addTag(DCMTree::TagId(0x0008,0x0050), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x0050)));
    00365
    00366         DCMTree::TagPtr modTagPtr = _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x0060));
    00367         string modality = modTagPtr->toString();
    00368         addTag(_genTreePtr, DCMTree::TagId(0x0008,0x0060),"RTSTRUCT", DCMTree::CS);
    00369
    00370         _genTreePtr->addTag(DCMTree::TagId(0x0008,0x0070), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x0070)));
    00371         _genTreePtr->addTag(DCMTree::TagId(0x0008,0x0090), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x0090)));
    00372         //hard code "Mevis" here, need to find how to get machine name
    00373         addTag(_genTreePtr, DCMTree::TagId(0x0008,0x1010), "MevisLab", DCMTree::SH);
    00374         _genTreePtr->addTag(DCMTree::TagId(0x0008,0x103e), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x103e)));
    00375   addTag(_genTreePtr, DCMTree::TagId(0x0008,0x103e), "Structure Set", DCMTree::LO);
    00376   _genTreePtr->addTag(DCMTree::TagId(0x0008,0x1090), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0008,0x1090)));
    00377         _genTreePtr->addTag(DCMTree::TagId(0x0010,0x0010), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0010,0x0010)));
    00378         _genTreePtr->addTag(DCMTree::TagId(0x0010,0x0020), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0010,0x0020)));
    00379         _genTreePtr->addTag(DCMTree::TagId(0x0010,0x0030), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0010,0x0030)));
    00380         _genTreePtr->addTag(DCMTree::TagId(0x0010,0x0040), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0010,0x0040)));
    00381
    00382         _genTreePtr->addTag(DCMTree::TagId(0x0020,0x000d), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x000d)));
    00383         _genTreePtr->addTag(DCMTree::TagId(0x0020,0x000e), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x000e)));
    00384         std::string seriesInstUID = _treeHeaderPtr->getTag(DCMTree::TagId(DCMTree::TagId(0x0020,0x000e)))->toString();
    00385
    00386         _genTreePtr->addTag(DCMTree::TagId(0x0010,0x0040), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0010,0x0040)));
    00387         addTag(_genTreePtr,DCMTree::TagId(0x0018,0x1020), "OS 8.1.18", DCMTree::LO);
    00388         _genTreePtr->addTag(DCMTree::TagId(0x0020,0x000d), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x000d)));
    00389         _genTreePtr->addTag(DCMTree::TagId(0x0020,0x000e), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x000e)));
    00390         _genTreePtr->addTag(DCMTree::TagId(0x0020,0x0010), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x0010)));
    00391         _genTreePtr->addTag(DCMTree::TagId(0x0020,0x0011), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x0011)));
    00392         _genTreePtr->getTag_rw(DCMTree::TagId(0x0020,0x0011))->setValue("1");
    00393         string label = _genTreePtr->getTag_rw(DCMTree::TagId(0x0008,0x0060))->toString();
    00394         label.append("_1");
    00395         addTag(_genTreePtr, DCMTree::TagId(0x3006,0x0002), label, DCMTree::SH);
    00396         addTag(_genTreePtr, DCMTree::TagId(0x3006,0x0008),"",DCMTree::DA);
    00397         addTag(_genTreePtr,DCMTree::TagId(0x3006,0x0009),"",DCMTree::TM);
    00398
    00399         DCMTree::TreePtr embeddedTree(new DCMTree::Tree());
    00400         addSequence(_genTreePtr, embeddedTree, DCMTree::TagId(0x3006,0x0010));
    00401
    00402
    00403         embeddedTree->addTag(DCMTree::TagId(0x0020,0x0052), _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x0052)));
    00404         std::string frameofReferencedFrameUID = embeddedTree->getTag(DCMTree::TagId(0x0020,0x0052))->toString();
    00405
    00406         DCMTree::TreePtr refStudySeq(new DCMTree::Tree());
    00407         addSequence(embeddedTree, refStudySeq, DCMTree::TagId(0x3006,0x0012));
    00408
    00409         _refSopClassUID = _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0002,0x0002))->toString();
    00410         addTag(refStudySeq,DCMTree::TagId(0x0008,0x1150), _refSopClassUID, DCMTree::UI);
    00411
    00412   string SOPInsUID = _treeHeaderPtr->getTag_rw(DCMTree::TagId(0x0020,0x0052))->toString();
    00413         addTag(refStudySeq,DCMTree::TagId(0x0008,0x1155),SOPInsUID.substr(0, SOPInsUID.find_last_of(".")), DCMTree::UI);
    00414
    00415         DCMTree::TreePtr refSeriesSeq(new DCMTree::Tree());
    00416         addSequence(refStudySeq, refSeriesSeq, DCMTree::TagId(0x3006,0x0014));
    00417
    00418   addTag(refSeriesSeq,DCMTree::TagId(0x0020,0x000e),seriesInstUID,DCMTree::UI);
    00419         addSequenceTag(refSeriesSeq,DCMTree::TagId(0x3006, 0x0016));
    00420         DCMTree::TagPtr conImageTag = refSeriesSeq->getTag_rw(DCMTree::TagId(0x3006, 0x0016));
    00421
    00422         std::string refSOPClassUID = _treeHeaderPtr->getTag(DCMTree::TagId(0x0008,0x0016))->toString();
    00423         if (combineSOPInstUID(conImageTag, refSOPClassUID) == false) {
    00424                 return false;
    00425         }
    00426         addSequenceTag(_genTreePtr, DCMTree::TagId(0x3006,0x0020));
    00427   DCMTree::TagPtr csoGroupTag = _genTreePtr->getTag_rw(DCMTree::TagId(0x3006, 0x0020));
    00428         std::string studyID = (_genTreePtr->getTag(DCMTree::TagId(0x0020,0x000d)))->toString();
    00429         if (addCSOGroupTags(csoGroupTag, frameofReferencedFrameUID) == false) {
    00430                 return false;
    00431         }
    00432         DCMTree::TreePtr ROIContourSeq(new DCMTree::Tree());
    00433   addSequence(_genTreePtr, ROIContourSeq, DCMTree::TagId(0x3006,0x0039));
    00434
    00435         DCMTree::TagPtr csoTag = _genTreePtr->getTag_rw(DCMTree::TagId(0x3006, 0x0039));
    00436         if (addCSOTags(csoTag, ROIContourSeq) == false) {
    00437                 return false;
    00438         }
    00439
    00440   // The following tags are not necessary in RT structure file
    00441   DCMTree::TreePtr RTROIObSeq(new DCMTree::Tree());
    00442   addSequence(_genTreePtr, RTROIObSeq, DCMTree::TagId(0x3006,0x0080));
    00443
    00444         DCMTree::TagPtr RTROIObTag = _genTreePtr->getTag_rw(DCMTree::TagId(0x3006, 0x0080));
    00445         addRTROIObTags(RTROIObTag, RTROIObSeq);
    00446         return true;
    00447 }
    00448
    00449 //----------------------------------------------------------------------------------
    00451 //----------------------------------------------------------------------------------
    00452 void CSOToRTStructure::addRTROIObTags(DCMTree::TagPtr RTROIObTag, DCMTree::TreePtr RTROIObSeq)
    00453 {
    00454         unsigned int seqSize = RTROIObTag->sequenceItems().size();
    00455         if (seqSize != 0) {
    00456                 RTROIObTag->sequenceItems().erase(RTROIObTag->sequenceItems().begin(),
    00457                 RTROIObTag->sequenceItems().end());
    00458         }
    00459         unsigned int groups = _inputCSOs->numGroups();
    00460         for (unsigned int i = 0; i < groups; i ++) {
    00461                 CSOGroup* group = _inputCSOs->getGroupAt(i);
    00462                 DCMTree::TreePtr childTree(new DCMTree::Tree());
    00463                 RTROIObTag->addSequenceItem(childTree);
    00464     std::stringstream s;
    00465           s << int(i+1);
    00466     std::stringstream sId;
    00467           sId << int(group->getId());
    00468     addTag(childTree, DCMTree::TagId(0x3006,0x0082),s.str(), DCMTree::IS);
    00469                 addTag(childTree, DCMTree::TagId(0x3006,0x0084),sId.str(), DCMTree::IS);
    00470                 addTag(childTree, DCMTree::TagId(0x3006,0x0085), group->getLabel(), DCMTree::SH);
    00471                 // hard code here
    00472     addTag(childTree, DCMTree::TagId(0x3006,0x00a4), "ORGAN", DCMTree::CS);
    00473                 addTag(childTree, DCMTree::TagId(0x3006,0x00a6), "", DCMTree::PN);
    00474         }
    00475 }
    00476
    00477 //----------------------------------------------------------------------------------
    00479 //----------------------------------------------------------------------------------
    00480 bool CSOToRTStructure::addCSOGroupTags(DCMTree::TagPtr csoGroupTag, std::string refFOfRef) {
    00481         if (_inputCSOs== NULL){
    00482                 ML_PRINT_ERROR("mlCSOToRTStructure::addCSOGroupTags",ML_BAD_PARAMETER, "RT structure file cannot be generated because there is no input CSOs.");
    00483                 return false;
    00484         }
    00485   unsigned int groupNum = _inputCSOs->numGroups();
    00486   if (groupNum == 0) {
    00487                 ML_PRINT_ERROR("mlCSOToRTStructure::addCSOGroupTags",ML_BAD_PARAMETER, "RT structure file cannot be generated because there are no CSO groups.");
    00488                 return false;
    00489         }
    00490         for (unsigned int i=0; i < _inputCSOs->numGroups(); i++) {
    00491           CSOGroup* group = _inputCSOs->getGroupAt(i);
    00492                 DCMTree::TreePtr childTree(new DCMTree::Tree());
    00493                 DCMTree::TagInfo childInfo1(DCMTree::TagId(0x3006,0x0022),DCMTree::IS,DCMTree::TagValueMultiplicity(1,1));
    00494                 DCMTree::TagInfo childInfo2(DCMTree::TagId(0x3006,0x0024),DCMTree::UI,DCMTree::TagValueMultiplicity(1,1));
    00495                 DCMTree::TagInfo childInfo3(DCMTree::TagId(0x3006,0x0026),DCMTree::LO,DCMTree::TagValueMultiplicity(1,1));
    00496                 DCMTree::TagInfo childInfo4(DCMTree::TagId(0x3006,0x0036),DCMTree::CS,DCMTree::TagValueMultiplicity(1,1));
    00497                 DCMTree::TagPtr itemTag1(new DCMTree::Tag(childInfo1));
    00498                 DCMTree::TagPtr itemTag2(new DCMTree::Tag(childInfo2));
    00499                 DCMTree::TagPtr itemTag3(new DCMTree::Tag(childInfo3));
    00500                 DCMTree::TagPtr itemTag4(new DCMTree::Tag(childInfo4));
    00501                 std::stringstream s;
    00502                 s << int(group->getId());
    00503                 itemTag1->addValue(s.str());
    00504                 itemTag2->addValue(refFOfRef);
    00505                 std::string label = group->getLabel();
    00506                 if (label.empty()) {
    00507                   label.assign("Group ");
    00508                         std::stringstream s;
    00509                   s << int(group->getId());
    00510                   label.append(s.str());
    00511
    00512                   ML_PRINT_WARNING("mlCSOToRTStructure::addCSOGroupTags",ML_BAD_PARAMETER, "There is no CSO group label.Add default as group [number]");
    00513                 }
    00514                 itemTag3->addValue(label);
    00515                 childTree->addTag(childInfo1.id(), itemTag1);
    00516                 childTree->addTag(childInfo2.id(), itemTag2);
    00517                 childTree->addTag(childInfo3.id(), itemTag3);
    00518                 childTree->addTag(childInfo4.id(), itemTag4);
    00519                 csoGroupTag->addSequenceItem(childTree);
    00520         }
    00521         return true;
    00522 }
    00523
    00524 //----------------------------------------------------------------------------------
    00526 //----------------------------------------------------------------------------------
    00527 bool CSOToRTStructure::addCSOTags(DCMTree::TagPtr csoTag, DCMTree::TreePtr contourTree) {
    00528         if (_inputCSOs== NULL){
    00529                 ML_PRINT_ERROR("mlCSOToRTStructure::addCSOTags",ML_BAD_PARAMETER, "RT structure file cannot be generated because there is no input CSOs.");
    00530                 return false;
    00531         }
    00532   unsigned int num = _inputCSOs->numCSO();
    00533         if (num == 0) {
    00534                 ML_PRINT_ERROR("mlCSOToRTStructure::addCSOTags",ML_BAD_PARAMETER, "RT structure file cannot be generated because there is no input CSOs.");
    00535                 return false;
    00536         }
    00537         unsigned int groupNum = _inputCSOs->numGroups();
    00538         if (groupNum == 0) {
    00539                 ML_PRINT_ERROR("mlCSOToRTStructure::addCSOTags",ML_BAD_PARAMETER, "RT structure file cannot be generated because there are no CSO groups.");
    00540                 return false;
    00541         }
    00542         unsigned int seqSize = csoTag->sequenceItems().size();
    00543         if (seqSize != 0) {
    00544                 csoTag->sequenceItems().erase(csoTag->sequenceItems().begin(),
    00545                 csoTag->sequenceItems().end());
    00546         }
    00547         for (unsigned int gInd = 0; gInd < groupNum; gInd ++) {
    00548                 CSOGroup* group = _inputCSOs->getGroupAt(gInd);
    00549                 if (group == NULL || group->numCSO() == 0){
    00550                         ML_PRINT_ERROR("mlCSOToRTStructure::addCSOTags",ML_BAD_PARAMETER, "RT structure file cannot be generated because some groups donot contain any CSOs.");
    00551                         return false;
    00552                 }
    00553                 DCMTree::TreePtr csoGTree(new DCMTree::Tree());
    00554
    00555                 ml::vec3 color = group->getColor();
    00556                 string strColor[3];
    00557                 DCMTree::TagInfo info(DCMTree::TagId(0x3006,0x002a), DCMTree::IS,DCMTree::TagValueMultiplicity(1,1));
    00558                 DCMTree::TagPtr newTag(new DCMTree::Tag(info));
    00559                 csoGTree->addTag(DCMTree::TagId(0x3006,0x002a), newTag);
    00560                 for (int i = 0; i < 3; i++) {
    00561                         std::stringstream s;
    00562                         s << int(color[i]*255);
    00563                         strColor[i].assign(s.str());
    00564                         newTag->addValue(strColor[i]);
    00565                 }
    00566                 DCMTree::TreePtr childGTree(new DCMTree::Tree());
    00567                 addSequence(csoGTree, childGTree, DCMTree::TagId(0x3006,0x0040));
    00568                 DCMTree::TagPtr childGTag = csoGTree->getTag_rw(DCMTree::TagId(0x3006, 0x0040));
    00569                 unsigned int seqGSize = childGTag->sequenceItems().size();
    00570                 if (seqGSize != 0) {
    00571                         childGTag->sequenceItems().erase(childGTag->sequenceItems().begin(),
    00572                         childGTag->sequenceItems().end());
    00573                 }
    00574
    00575                 unsigned int csoNum = group->numCSO();
    00576                 bool colorAdded = false;
    00577     for (unsigned int in = 0; in < csoNum; in++) {
    00578                         CSO* cso = group->getCSOAt(in);
    00579                         //std::cout << cso->getId();
    00580                         if (cso->isInPlane()) {
    00581                                 CSOSeedPoint *sp = cso->getFirstSeedPoint();
    00582                                 double z = sp->worldPosition[2];
    00583                                 string refUID = getRefUID(z);
    00584                                 if (refUID.empty()){
    00585                                   ML_PRINT_ERROR("mlCSOToRTStructure::addCSOTags",ML_BAD_PARAMETER, "There are no matching slices for a CSO." + cso->getId());
    00586                                   return false;
    00587                                 }
    00588                                 DCMTree::TreePtr csoCTree(new DCMTree::Tree());
    00589                                 DCMTree::TreePtr seqTree(new DCMTree::Tree());
    00590
    00591                                 addSequence(csoCTree, seqTree, DCMTree::TagId(0x3006,0x0016));
    00592                                 DCMTree::TagPtr UIDs = csoCTree->getTag_rw(DCMTree::TagId(0x3006,0x0016));
    00593
    00594                                 addTag(seqTree, DCMTree::TagId(0x0008,0x1150),_refSopClassUID, DCMTree::UI);
    00595                                 addTag(seqTree, DCMTree::TagId(0x0008,0x1155),refUID, DCMTree::UI);
    00596                                 addTag(csoCTree, DCMTree::TagId(0x3006,0x0042),"CLOSED_PLANAR", DCMTree::CS);
    00597                                 unsigned int ptNum = 0;
    00598                                 for (unsigned int i = 0; i < cso->numPathPointLists(); i ++){
    00599                                   ml::CSOPathPoints* pt = cso->getPathPointsAt(i);
    00600                                   std::vector<vec3> vec;
    00601                                   pt->getWorldPositions(vec);
    00602                                   ptNum = ptNum + vec.size() + 1;
    00603                                 }
    00604                                 std::stringstream s;
    00605                                 s << int(ptNum);
    00606                                 addTag(csoCTree, DCMTree::TagId(0x3006,0x0046), s.str(), DCMTree::IS);
    00607                                 addCSOPathPoint(csoCTree, DCMTree::TagId(0x3006,0x0050), DCMTree::DS, cso);
    00608                                 if (colorAdded == false) {
    00609                                   csoTag->addSequenceItem(csoGTree);
    00610                                    colorAdded = true;
    00611                                 }
    00612                                 childGTag->addSequenceItem(csoCTree);
    00613                         }else {
    00614                                  ML_PRINT_ERROR("mlCSOToRTStructure::addCSOTags",ML_BAD_PARAMETER, "CSO must be in one plane to proceed.");
    00615                                  return false;
    00616                          }
    00617                 }
    00618     if(colorAdded == true) {
    00619                         std::stringstream sg;
    00620                         sg << int(group->getId());
    00621                         addTag(csoGTree, DCMTree::TagId(0x3006,0x0084), sg.str(), DCMTree::IS);
    00622                 }
    00623         }
    00624   return true;
    00625 }
    00626
    00627 //----------------------------------------------------------------------------------
    00629 //----------------------------------------------------------------------------------
    00630 void CSOToRTStructure::addCSOPathPoint(DCMTree::TreePtr childTree, DCMTree::TagId tagId, DCMTree::Vr vr, ml::CSO* cso){
    00631         DCMTree::TagInfo info(tagId, vr, DCMTree::TagValueMultiplicity(1,1));
    00632         DCMTree::TagPtr newTag(new DCMTree::Tag(info));
    00633         for (unsigned int i = 0; i < cso->numPathPointLists(); i ++){
    00634                 ml::CSOPathPoints* pt = cso->getPathPointsAt(i);
    00635                 std::vector<vec3> vec;
    00636                 pt->getWorldPositions(vec);
    00637           ml::CSOSeedPoint *tailPt = pt->tailSeedPoint;
    00638                 ml::vec3 vecT = tailPt->worldPosition;
    00639                 for (int i = 0; i < 3; i++){
    00640                         std::stringstream s;
    00641                         s << vecT[i];
    00642                         std::string m = s.str();
    00643                         newTag->addValue(s.str());
    00644                 }
    00645           for (unsigned int j = 0; j < vec.size(); j ++){
    00646                         for (int coordInd = 0; coordInd < 3; coordInd++) {
    00647                                 std::stringstream s;
    00648                                 s << vec[j][coordInd];
    00649                                 std::string m = s.str();
    00650                                 newTag->addValue(s.str());
    00651                         }
    00652                 }
    00653         }
    00654         childTree->addTag(tagId, newTag);
    00655 }
    00656
    00657 //----------------------------------------------------------------------------------
    00659 //----------------------------------------------------------------------------------
    00660 void CSOToRTStructure::writeToDCMFile(DCMTree::TreePtr tree, std::string dest) {
    00661
    00662         DCMTree::MessagePtr messagePtr = DCMTree::MessagePtr(
    00663     new DCMTree::Message(DCMTree_Unicode::UTF8CharacterSet(), DCMTree::IMPLICIT_LITTLE_ENDIAN));
    00664   messagePtr->setTags(tree);
    00665
    00666   // Create writer object
    00667         DCMTree::WriterPtr writer = DCMTree::Writer::create(DCMTree::Dict::singleton());
    00668
    00669   // Write message
    00670         DCMTree::IOParameterPtr param(DCMTree::IOParameter::create(dest));
    00671   writer->write(param, messagePtr);
    00672 }
    00673
    00674 ML_END_NAMESPACE
    00675

All Classes Namespaces Files Functions Variables Enumerator Friends