Files
DCMV/src/src/base/DicomLoader.cpp
2022-02-14 09:24:27 +08:00

734 lines
22 KiB
C++
Raw Blame History

#include "base/DicomLoader.h"
#include <QObject>
#include <QMainWindow>
#include <QStatusBar>
#include "base/seriesinstance.h"
#include "DICOMDirectoryHelper.h"
#include "ExtendMedicalImageProperties.h"
#include "vtkDICOMImageReader2.h"
#include "vtkImageData.h"
#include <map>
#include <algorithm>
#include <vtkStringArray.h>
#include <qDebug>
#include <string.h>
#include <stdio.h>
#define ORIEN_NUM 4
#define SINGLE_INSTANCE 1
OrienMapType OrienHelper::orien_map;
/************************************************************************
* [Q]Is there anything different between these two?
* instance->m_image = m_itkConnector->GetOutput();
* instance->m_image->DeepCopy(m_itkConnector->GetOutput());
* [Q]I have no idea why it works just fine not using deep copy,
while the vtkdata is replaced in the Qfusion Project using exatly the same workflow!
/************************************************************************/
std::string OrienHelper::StringFilter(char* str)
{
const char s[] = "\\ ";
char *token;
char *buftmp;
token = strtok_s(str, s, &buftmp);
std::string trim ="";
while (token != NULL) {
//printf("%s\n", token);
trim += token;
token = strtok_s(NULL, s, &buftmp);
}
return trim;
}
void OrienHelper::init()
{
const std::string index[] = { "LH","LF","RH","RF" };
std::vector<std::string> indexList(std::begin(index), std::end(index));
const std::string lh[] = { "S" ,"L" ,"R" ,"I" };
const std::string lf[] = { "I" , "L" , "R" , "S" };
const std::string rh[] = { "S" , "R" , "L" , "I" };
const std::string rf[] = { "I" , "R" , "L" , "S" };
std::vector<std::string> v_lh(std::begin(lh), std::end(lh));
std::vector<std::string> v_lf(std::begin(lf), std::end(lf));
std::vector<std::string> v_rh(std::begin(rh), std::end(rh));
std::vector<std::string> v_rf(std::begin(rf), std::end(rf));
std::vector<std::vector<std::string>> retList;
retList.push_back(v_lh);
retList.push_back(v_lf);
retList.push_back(v_rh);
retList.push_back(v_rh);
for (int i = 0; i < ORIEN_NUM; i++)
{
OrienHelper::orien_map.insert(std::pair<std::string, std::vector<std::string>>(indexList.at(i),retList.at(i)));
}
}
std::vector<std::string>* OrienHelper::getOrienStrList(const std::string &index)
{
const char* s = index.c_str();
int len = strlen(s);
char *hint = new char[len + 1];
strcpy_s(hint, len + 1, s);
std::string trim = StringFilter(hint);
OrienMapType::iterator it = OrienHelper::orien_map.find(trim);
delete hint;
if (it == orien_map.end())
{
return nullptr;
}
return &(it->second);
}
DicomLoader* DicomLoader::instance = new DicomLoader();
DicomLoader* DicomLoader::GetInstance() {
//lazy man
//if (!instance) {
// instance = new DicomLoader();
//}
//hungry man
return instance;
}
DicomLoader::DicomLoader():m_addType(AddDicomType::DUPLICATE_TYPE) {
// m_itkSeriesReader = SeriesReaderType::New();
// m_itkConnector = ConnectorType::New();
// m_gdcmIO = ImageIOType::New();
// m_inputNames = InputNamesGeneratorType::New();
DICOMHelper = new DICOMDirectoryHelper;
reader = nullptr;
//transfer to series after!
m_patients.clear();
}
DicomLoader::~DicomLoader() {
delete DICOMHelper;
if (reader)reader->Delete();
reader = nullptr;
delete instance;
}
bool DicomLoader::IsDuplicate(UniqueIDInfo_t* unique)
{
if (m_patients.count(unique->patient_name) == 0)
{
//new patient
m_addType = AddDicomType::PATINET_LEVEL;
return false;
}
PatientsMapType::iterator cur_patient_iter = m_patients.find(unique->patient_name);
StudiesMapType *studies = cur_patient_iter->second->studies;
if (studies->count(unique->study_uid) == 0)
{
//new study
m_addType = AddDicomType::STUDY_LEVEL;
return false;
}
StudiesMapType::iterator cur_study_iter = studies->find(unique->study_uid);
SeriesMapType *series = cur_study_iter->second->series;
if (series->count(unique->series_uid) == 0)
{
//new series
m_addType = AddDicomType::SERIES_LEVEL;
return false;
}
SeriesMapType::iterator cur_series_iter = series->find(unique->series_uid);
//if (cur_series_iter->second->getSerirsOpenMode()== FILE_OPEN_MODE &&
if (cur_series_iter->second->open_mode == FILE_OPEN_MODE &&
unique->open_mode == DIR_OPEN_MODE)
{
m_addType = AddDicomType::OVERRIDE_LEVEL;
return false;
}
if (cur_series_iter->second->open_mode == FILE_OPEN_MODE &&
unique->open_mode == FILE_OPEN_MODE)
{
if (cur_series_iter->second->instance_num != unique->instance_num)
{
m_addType = AddDicomType::OVERRIDE_LEVEL;
return false;
}
}
m_addType = AddDicomType::DUPLICATE_TYPE;
return true;
}
void DicomLoader::InitFromCopy(SeriesInstance* instance)
{
//copy data from existing instance!
UniqueIDInfo_t* unique = instance->getUniqueID();
//SeriesInfo_t* serie_info = getSerieInfo(*unique);
SeriesInstance *exists = getFirstInstance(*unique);
//DicomTagInfo_t *tag_info = serie_info->tag_info;
//instance->setDicomTagInfo(exists->getDicomTagInfo());
//copyDicomTagsInfo(exists, instance);
//smart pointer reference count++
instance->m_image = exists->m_image;
if (exists->getUniqueID()->open_mode == DIR_OPEN_MODE)
{
//vector deep copy
//exists->m_fileNames = instance->m_fileNames;This is a bug<75><67>
instance->m_fileNames = exists->m_fileNames;
}
}
void DicomLoader::InitFromRead(SeriesInstance* instance)//, DicomTagInfo_t* tag_info)
{
//////////////////////////////////////////////////////////////////////////
//You have to use DeepCopy on this condition,otherwise, the previous image will be flushed.
instance->m_image = reader->GetOutput();
if (instance->getUniqueID()->open_mode == DIR_OPEN_MODE)
{
auto files = reader->GetDICOMFileNames();
std::for_each(files->begin(),files->end(),[=](auto v){
instance->m_fileNames.push_back(v);
});
}
reader->Delete();
reader = nullptr;
}
//You may not use const & cause intance may be deleted during this func
//delete all the instances assotiated with this series UID
void DicomLoader::deleteInstanceFromMap(UniqueIDInfo uniqueID)
{
//const UniqueIDInfo & uniqueID = instance->getUniqueID();
PatientsMapType::iterator cur_patient_iter = m_patients.find(uniqueID.patient_name);
StudiesMapType::iterator cur_study_iter = cur_patient_iter->second->studies->find(uniqueID.study_uid);
//in order
SeriesInfo_t* the_series = cur_study_iter->second->series->at(uniqueID.series_uid);
//SeriesInstance *cur_series = cur_study_iter->second->series->at(uniqueID.series_uid);
//delete all the instances assotiated with this series UID
for (int i = 0; i < the_series->instances->size(); i++)
{
delete the_series->instances->at(i);
}
the_series->instances->clear();
//erase series from study
cur_study_iter->second->series->erase(uniqueID.series_uid);
//Recursively Delete
//if the study has no series
if (cur_study_iter->second->series->empty())
{
cur_patient_iter->second->studies->erase(uniqueID.study_uid);
}
//if the patient has no study
if (cur_patient_iter->second->studies->empty())
{
m_patients.erase(uniqueID.patient_name);
}
//cause you need uniqueID, therefore you have to delete series at last
//delete cur_series;
}
InstancesVecType* DicomLoader::getInstancesVec(const UniqueIDInfo &uniqueID)
{
PatientsMapType::iterator cur_patient_iter = m_patients.find(uniqueID.patient_name);
if (cur_patient_iter == m_patients.end())
{
return nullptr;
}
StudiesMapType::iterator cur_study_iter = cur_patient_iter->second->studies->find(uniqueID.study_uid);
if (cur_study_iter == cur_patient_iter->second->studies->end())
{
return nullptr;
}
SeriesMapType::iterator the_series = cur_study_iter->second->series->find(uniqueID.series_uid);
if (the_series == cur_study_iter->second->series->end())
{
return nullptr;
}
return the_series->second->instances;
}
void DicomLoader::getOpenedInstancesVec(InstancesVecType& retVec)
{
for (PatientsMapType::const_iterator cur_patient_iter = m_patients.begin(); cur_patient_iter !=
m_patients.end(); cur_patient_iter++)
{
StudiesMapType *cur_studies = cur_patient_iter->second->studies;
for (StudiesMapType::const_iterator cur_study_iter = cur_studies->begin(); cur_study_iter !=
cur_studies->end(); cur_study_iter++)
{
SeriesMapType *cur_series = cur_study_iter->second->series;
for (SeriesMapType::const_iterator cur_series_iter = cur_series->begin(); cur_series_iter !=
cur_series->end(); cur_series_iter++)
{
//default export instance: the recently added one
SeriesInstance *last = cur_series_iter->second->instances->back();
if(nullptr!=last)
{
retVec.push_back(last);
}
}
}
}
}
SeriesInstance* DicomLoader::getFirstInstance(const UniqueIDInfo &uniqueID)
{
PatientsMapType::iterator cur_patient_iter = m_patients.find(uniqueID.patient_name);
if (cur_patient_iter == m_patients.end())
{
return nullptr;
}
StudiesMapType::iterator cur_study_iter = cur_patient_iter->second->studies->find(uniqueID.study_uid);
if (cur_study_iter == cur_patient_iter->second->studies->end())
{
return nullptr;
}
SeriesMapType::iterator the_series = cur_study_iter->second->series->find(uniqueID.series_uid);
if (the_series == cur_study_iter->second->series->end())
{
return nullptr;
}
return *the_series->second->instances->begin();
}
SeriesInfo_t* DicomLoader::getSerieInfo(const UniqueIDInfo &uniqueID)
{
PatientsMapType::iterator cur_patient_iter = m_patients.find(uniqueID.patient_name);
if (cur_patient_iter == m_patients.end())
{
return nullptr;
}
StudiesMapType::iterator cur_study_iter = cur_patient_iter->second->studies->find(uniqueID.study_uid);
if (cur_study_iter == cur_patient_iter->second->studies->end())
{
return nullptr;
}
SeriesMapType::iterator the_series = cur_study_iter->second->series->find(uniqueID.series_uid);
if (the_series == cur_study_iter->second->series->end())
{
return nullptr;
}
return the_series->second;
}
bool DicomLoader::deleteSeriesInstance(SeriesInstance* old)
{
//DicomLoader *helper = DicomLoader::GetInstance();
InstancesVecType* inst_vec = instance->getInstancesVec(*old->getUniqueID());
//if there is only one instance<63><65>do not delete
if (inst_vec->size() == SINGLE_INSTANCE)
{
//Comment1:You should set Series Instance to no DicomImageView
//Comment2:It is hard to tell wether it is in use,you'd better do nothing
//old->orphanizeSeriesInstance();
//You should set Series Instance to no DicomImageView
//old->orphanizeSeriesInstance();
return false;
}
for (InstancesVecType::iterator iter = inst_vec->begin(); iter != inst_vec->end(); iter++)
{
if (old == *iter)
{
inst_vec->erase(iter);
delete old;
return true;
}
}
return false;
}
SeriesInstance* DicomLoader::addSeriesInstance(SeriesInstance* instance,bool copy)
{
DicomTagInfo_t* seriesInfo = instance->getDicomTagInfo();
UniqueIDInfo_t* unique = instance->getUniqueID();
InstancesVecType* all_instances = nullptr;
SeriesMapType* all_series = nullptr;
StudiesMapType* all_studies = nullptr;
SeriesInfo_t* series = nullptr;
StudyInfo_t* study = nullptr;
PatientInfo_t *patient = nullptr;
PatientsMapType::iterator cur_patient_iter;
StudiesMapType::iterator cur_study_iter;
SeriesMapType::iterator cur_series_iter;
if (copy)
{
//just push back
cur_patient_iter = m_patients.find(unique->patient_name);
all_studies = cur_patient_iter->second->studies;
cur_study_iter = all_studies->find(unique->study_uid);
cur_series_iter = cur_study_iter->second->series->find(unique->series_uid);
all_instances = cur_series_iter->second->instances;
all_instances->push_back(instance);
return nullptr;
}
switch (m_addType)
{
case DUPLICATE_TYPE:
break;
case PATINET_LEVEL:
all_instances = new InstancesVecType();
all_instances->push_back(instance);
series = new SeriesInfo_t();
series->open_mode = unique->open_mode;
if (unique->open_mode == FILE_OPEN_MODE)
{
series->instance_num = unique->instance_num;
}
//EEROR CODE HERE,YOU CAN NOT DEPEND ON SINGLE INSTANCE!!
series->tag_info = instance->getDicomTagInfo();
series->unique_info = instance->getUniqueID();
series->series_pixmap = instance->GetPixmap();
series->instances = all_instances;
all_series = new SeriesMapType();
all_series->insert(std::pair<std::string, SeriesInfo_t*>(unique->series_uid, series));
//patient
all_studies = new StudiesMapType();
study = new StudyInfo_t();
study->study_description = seriesInfo->m_StudyDescription;
study->study_date = seriesInfo->m_StudyDate;
study->study_time = seriesInfo->m_StudyTime;
study->series = all_series;
all_studies->insert(std::pair<std::string, StudyInfo_t*>(unique->study_uid, study));
//patient level
patient = new PatientInfo_t();
patient->patient_name = seriesInfo->m_PatientName;
patient->birth_date = seriesInfo->m_PatientBirth;
patient->studies = all_studies;
m_patients.insert(std::pair<std::string, PatientInfo_t*>(unique->patient_name, patient));
break;
case STUDY_LEVEL:
all_instances = new InstancesVecType();
all_instances->push_back(instance);
series = new SeriesInfo_t();
series->open_mode = unique->open_mode;
if (unique->open_mode == FILE_OPEN_MODE)
{
series->instance_num = unique->instance_num;
}
series->tag_info = instance->getDicomTagInfo();
series->unique_info = instance->getUniqueID();
series->series_pixmap = instance->GetPixmap();
series->instances = all_instances;
//study
all_series = new SeriesMapType();
all_series->insert(std::pair<std::string, SeriesInfo_t*>(unique->series_uid, series));
study = new StudyInfo_t();
study->study_description = seriesInfo->m_StudyDescription;
study->study_date = seriesInfo->m_StudyDate;
study->study_time = seriesInfo->m_StudyTime;
study->series = all_series;
cur_patient_iter = m_patients.find(unique->patient_name);
all_studies = cur_patient_iter->second->studies;
all_studies->insert(std::pair<std::string, StudyInfo_t*>(unique->study_uid, study));
break;
case SERIES_LEVEL:
all_instances = new InstancesVecType();
all_instances->push_back(instance);
series = new SeriesInfo_t();
series->open_mode = unique->open_mode;
if (unique->open_mode == FILE_OPEN_MODE)
{
series->instance_num = unique->instance_num;
}
series->tag_info = instance->getDicomTagInfo();
series->unique_info = instance->getUniqueID();
series->series_pixmap = instance->GetPixmap();
series->instances = all_instances;
cur_patient_iter = m_patients.find(unique->patient_name);
all_studies = cur_patient_iter->second->studies;
cur_study_iter = all_studies->find(unique->study_uid);
//all_series = new SeriesMapType();
all_series = cur_study_iter->second->series;
all_series->insert(std::pair<std::string, SeriesInfo_t*>(unique->series_uid, series));
break;
//combine two situationas, both image and series
case OVERRIDE_LEVEL:
cur_patient_iter = m_patients.find(unique->patient_name);
all_studies = cur_patient_iter->second->studies;
cur_study_iter = all_studies->find(unique->study_uid);
cur_series_iter = cur_study_iter->second->series->find(unique->series_uid);
cur_series_iter->second->open_mode = unique->open_mode;
if (unique->open_mode == FILE_OPEN_MODE)
{
cur_series_iter->second->instance_num = unique->instance_num;
}
//need to delete
cur_series_iter->second->tag_info = instance->getDicomTagInfo();
cur_series_iter->second->unique_info = instance->getUniqueID();
cur_series_iter->second->series_pixmap = instance->GetPixmap();
//wait for thumbnail update to delete it...
cur_series_iter->second->pixmap_valid = false;
all_instances = cur_series_iter->second->instances;
for (int i = 0; i < all_instances->size(); i++)
{
//check if it is newly created or old to delete
SeriesInstance *cur_series = all_instances->at(i);
if (cur_series->getUniqueID() != instance->getUniqueID())
{
//return the replaced pointer
all_instances->at(i) = instance;
return cur_series;
}
}
/*what if the images is shown*/
//remove the duplicate series, replace it with new.
//do this in delete stage
//last = cur_study_iter->second->series->at(unique->series_uid);
//delete last;
//cur_study_iter->second->series->erase(unique->series_uid);
//cur_study_iter->second->series->insert(std::pair<std::string, SeriesInstance*>(m_uniqueID.series_uid, instance));
break;
default:
break;
}
return nullptr;
}
void DicomLoader::ItkPreReadSeries(const std::string &dicomName, SeriesOpenMode openMode)
{
//m_itkSeriesReader->SetImageIO(gdcmIO);
if (openMode == FILE_OPEN_MODE)
{
//m_itkSeriesReader->SetFileName(m_dicomName.toStdString());
DICOMHelper->SetFileName(dicomName.c_str());
}
if (openMode == DIR_OPEN_MODE)
{
DICOMHelper->SetDirName(dicomName.c_str());
}
DICOMHelper->Update();
if(DICOMHelper->GetSeriesCount()>0){
currentImageProperty = DICOMHelper->GetSeries(0);
if (reader) reader->Delete();
reader = vtkDICOMImageReader2::New();
reader->SetFileNames(*(currentImageProperty->GetFileNames()));
reader->Update();
}
}
UniqueIDInfo_t* DicomLoader::createUniqueID(const std::string &dicomName, SeriesOpenMode openMode)
{
UniqueIDInfo_t* pUniqueID(new UniqueIDInfo_t());
pUniqueID->open_mode = openMode;
pUniqueID->dicom_name = dicomName;
if (openMode == FILE_OPEN_MODE)
{
char buffer[16]={};
pUniqueID->instance_num=itoa(currentImageProperty->GetFileNames()->size(),buffer,10);
}
pUniqueID->patient_name = currentImageProperty->GetPatientName();
pUniqueID->study_uid = currentImageProperty->GetStudyUID();
pUniqueID->series_uid = currentImageProperty->GetSeriesUID();
return pUniqueID;
}
void DicomLoader::setDirObservers(void* client)
{
//Adding a reading progress observer to the reader so we can see how are we reading.
// itk::CStyleCommand::Pointer pcl = itk::CStyleCommand::New();
// pcl->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderProCallbackFunction_DIR);
// pcl->SetClientData(client);
// //m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
// m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
//
// itk::CStyleCommand::Pointer pcl2 = itk::CStyleCommand::New();
// pcl2->SetClientData(client);
// pcl2->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderEndCallbackFunction);
// //m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
// m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
}
void DicomLoader::setFileObservers(void* client)
{
//Adding a reading progress observer to the reader so we can see how are we reading.
// itk::CStyleCommand::Pointer pcl = itk::CStyleCommand::New();
// pcl->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderProCallbackFunction_FILE);
// pcl->SetClientData(client);
// //m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
// m_itkSeriesReader->AddObserver(itk::ProgressEvent(), pcl);
//
// itk::CStyleCommand::Pointer pcl2 = itk::CStyleCommand::New();
// pcl2->SetClientData(client);
// pcl2->SetCallback((itk::CStyleCommand::FunctionPointer)&itkReaderEndCallbackFunction);
// //m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
// m_itkSeriesReader->AddObserver(itk::EndEvent(), pcl2);
}
//void DicomLoader::itkReaderProCallbackFunction_FILE(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data)
//{
// QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data);
// QString status = QString("Reading Images...");
// qdv->statusBar()->showMessage(status);
//}
//void DicomLoader::itkReaderProCallbackFunction_DIR(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data)
//{
// QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data);
// QString status = QString("Scanning Folder...(%1%)").arg(100 * obj->GetProgress());
// qdv->statusBar()->showMessage(status);
//}
//
//void DicomLoader::itkReaderEndCallbackFunction(itk::ProcessObject* obj, const itk::ProgressEvent&, void* data)
//
//{
// QMainWindow* qdv = reinterpret_cast<QMainWindow*>(data);
// qdv->statusBar()->showMessage("Ready");
//}
//
//void DicomLoader::copyDicomTagsInfo(SeriesInstance* origin, SeriesInstance* copy)
//{
// const DicomTagInfo_t *origin_info = origin->getConstDicomTagInfo();
// DicomTagInfo_t *copy_info = copy->getDicomTagInfo();
// copy_info->m_PatientName = origin_info->m_PatientName;
// copy_info->m_StudyDescription = origin_info->m_StudyDescription;
// copy_info->m_Institution = origin_info->m_Institution;
// copy_info->m_StudyDate = origin_info->m_StudyDate;
// copy_info->m_Modality = origin_info->m_Modality;
// copy_info->lbl_ser_num = origin_info->lbl_ser_num;
// copy_info->m_SeriesNumber = origin_info->m_SeriesNumber;
// copy_info->m_SeriesDescription = origin_info->m_SeriesDescription;
// copy_info->m_StudyTime = origin_info->m_StudyTime;
// copy_info->m_PatientBirth = origin_info->m_PatientBirth;
// copy_info->m_SliceNumber = origin_info->m_SliceNumber;
// copy_info->m_orientation = origin_info->m_orientation;
// copy_info->WL = origin_info->WL;
// copy_info->WW = origin_info->WW;
//
//}
DicomTagInfo_t* DicomLoader::createDicomTagsInfo()
{
DicomTagInfo_t* info = new DicomTagInfo_t();
char PatientName[255];
char StudyDescription[255];
char Institution[255];
char StudyDate[255];
char Modality[255];
std::string s_wl;
std::string s_ww;
info->spacing[0] = currentImageProperty->GetSpacing()[0];
info->spacing[1] = currentImageProperty->GetSpacing()[1];
info->spacing[2] = currentImageProperty->GetSliceThicknessAsDouble();
info->m_PatientName = currentImageProperty->GetPatientName();
info->m_StudyDescription = currentImageProperty->GetStudyDescription();
info->m_Institution = currentImageProperty->GetInstitutionName();
info->m_StudyDate = currentImageProperty->GetStudyDate();
info->m_Modality = currentImageProperty->GetModality();
info->lbl_ser_num = currentImageProperty->GetSeriesNumber();
info->m_SeriesNumber = currentImageProperty->GetSeriesNumber();
info->m_SeriesDescription = currentImageProperty->GetSeriesDescription();
info->m_StudyTime = currentImageProperty->GetStudyTime();
info->m_PatientBirth = currentImageProperty->GetPatientBirthDate();
char buffer[16]={0};
info->m_SliceNumber = itoa(currentImageProperty->GetFileNames()->size(), buffer,10);
info->m_orientation = "";
info->WL = currentImageProperty->GetNthWindowLevelPreset(0)[1];
info->WW = currentImageProperty->GetNthWindowLevelPreset(0)[0];
return info;
}
SeriesInstance* DicomLoader::createSeries(UniqueIDInfo_t* uniqueID, DicomTagInfo_t* tag_info, vtkGenericOpenGLRenderWindow* gl_rewin, bool copy)
{
SeriesInstance* series = new SeriesInstance(uniqueID, tag_info, gl_rewin);
//DicomLoader *helper = DicomLoader::GetInstance();
/******in order*******/
//whether create or copy from existing one
if (copy)
{
instance->InitFromCopy(series);
}
else
{
instance->InitFromRead(series);
}
series->setUpSeriesInstance();
return series;
}