Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

722 lines
20 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkMedicalImageProperties.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkMedicalImageProperties.h"
#include "vtkObjectFactory.h"
#include <vtksys/stl/string>
#include <vtksys/stl/vector>
#include <time.h> // for strftime
#include <ctype.h> // for isdigit
//----------------------------------------------------------------------------
vtkCxxRevisionMacro(vtkMedicalImageProperties, "$Revision: 1.3.2.1 $");
vtkStandardNewMacro(vtkMedicalImageProperties);
//----------------------------------------------------------------------------
class vtkMedicalImagePropertiesInternals
{
public:
class WindowLevelPreset
{
public:
double Window;
double Level;
vtksys_stl::string Comment;
};
typedef vtkstd::vector<WindowLevelPreset> WindowLevelPresetPoolType;
typedef vtkstd::vector<WindowLevelPreset>::iterator WindowLevelPresetPoolIterator;
WindowLevelPresetPoolType WindowLevelPresetPool;
};
//----------------------------------------------------------------------------
vtkMedicalImageProperties::vtkMedicalImageProperties()
{
this->Internals = new vtkMedicalImagePropertiesInternals;
this->AcquisitionDate = NULL;
this->AcquisitionTime = NULL;
this->ConvolutionKernel = NULL;
this->EchoTime = NULL;
this->EchoTrainLength = NULL;
this->Exposure = NULL;
this->ExposureTime = NULL;
this->GantryTilt = NULL;
this->ImageDate = NULL;
this->ImageNumber = NULL;
this->ImageTime = NULL;
this->InstitutionName = NULL;
this->KVP = NULL;
this->ManufacturerModelName = NULL;
this->Manufacturer = NULL;
this->Modality = NULL;
this->PatientAge = NULL;
this->PatientBirthDate = NULL;
this->PatientID = NULL;
this->PatientName = NULL;
this->PatientSex = NULL;
this->RepetitionTime = NULL;
this->SeriesDescription = NULL;
this->SeriesNumber = NULL;
this->SliceThickness = NULL;
this->StationName = NULL;
this->StudyDescription = NULL;
this->StudyID = NULL;
this->XRayTubeCurrent = NULL;
}
//----------------------------------------------------------------------------
vtkMedicalImageProperties::~vtkMedicalImageProperties()
{
if (this->Internals)
{
delete this->Internals;
this->Internals = NULL;
}
this->Clear();
}
//----------------------------------------------------------------------------
void vtkMedicalImageProperties::Clear()
{
this->SetAcquisitionDate(NULL);
this->SetAcquisitionTime(NULL);
this->SetConvolutionKernel(NULL);
this->SetEchoTime(NULL);
this->SetEchoTrainLength(NULL);
this->SetExposure(NULL);
this->SetExposureTime(NULL);
this->SetGantryTilt(NULL);
this->SetImageDate(NULL);
this->SetImageNumber(NULL);
this->SetImageTime(NULL);
this->SetInstitutionName(NULL);
this->SetKVP(NULL);
this->SetManufacturerModelName(NULL);
this->SetManufacturer(NULL);
this->SetModality(NULL);
this->SetPatientAge(NULL);
this->SetPatientBirthDate(NULL);
this->SetPatientID(NULL);
this->SetPatientName(NULL);
this->SetPatientSex(NULL);
this->SetRepetitionTime(NULL);
this->SetSeriesDescription(NULL);
this->SetSeriesNumber(NULL);
this->SetSliceThickness(NULL);
this->SetStationName(NULL);
this->SetStudyDescription(NULL);
this->SetStudyID(NULL);
this->SetXRayTubeCurrent(NULL);
this->RemoveAllWindowLevelPresets();
}
//----------------------------------------------------------------------------
void vtkMedicalImageProperties::DeepCopy(vtkMedicalImageProperties *p)
{
if (p == NULL)
{
return;
}
this->Clear();
this->SetAcquisitionDate(p->GetAcquisitionDate());
this->SetAcquisitionTime(p->GetAcquisitionTime());
this->SetConvolutionKernel(p->GetConvolutionKernel());
this->SetEchoTime(p->GetEchoTime());
this->SetEchoTrainLength(p->GetEchoTrainLength());
this->SetExposure(p->GetExposure());
this->SetExposureTime(p->GetExposureTime());
this->SetGantryTilt(p->GetGantryTilt());
this->SetImageDate(p->GetImageDate());
this->SetImageNumber(p->GetImageNumber());
this->SetImageTime(p->GetImageTime());
this->SetInstitutionName(p->GetInstitutionName());
this->SetKVP(p->GetKVP());
this->SetManufacturerModelName(p->GetManufacturerModelName());
this->SetManufacturer(p->GetManufacturer());
this->SetModality(p->GetModality());
this->SetPatientAge(p->GetPatientAge());
this->SetPatientBirthDate(p->GetPatientBirthDate());
this->SetPatientID(p->GetPatientID());
this->SetPatientName(p->GetPatientName());
this->SetPatientSex(p->GetPatientSex());
this->SetRepetitionTime(p->GetRepetitionTime());
this->SetSeriesDescription(p->GetSeriesDescription());
this->SetSeriesNumber(p->GetSeriesNumber());
this->SetSliceThickness(p->GetSliceThickness());
this->SetStationName(p->GetStationName());
this->SetStudyDescription(p->GetStudyDescription());
this->SetStudyID(p->GetStudyID());
this->SetXRayTubeCurrent(p->GetXRayTubeCurrent());
int nb_presets = p->GetNumberOfWindowLevelPresets();
for (int i = 0; i < nb_presets; i++)
{
double w, l;
p->GetNthWindowLevelPreset(i, &w, &l);
this->AddWindowLevelPreset(w, l);
this->SetNthWindowLevelPresetComment(
this->GetNumberOfWindowLevelPresets() - 1,
p->GetNthWindowLevelPresetComment(i));
}
}
//----------------------------------------------------------------------------
void vtkMedicalImageProperties::AddWindowLevelPreset(
double w, double l)
{
if (!this->Internals || this->HasWindowLevelPreset(w, l))
{
return;
}
vtkMedicalImagePropertiesInternals::WindowLevelPreset preset;
preset.Window = w;
preset.Level = l;
this->Internals->WindowLevelPresetPool.push_back(preset);
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::HasWindowLevelPreset(double w, double l)
{
if (this->Internals)
{
vtkMedicalImagePropertiesInternals::WindowLevelPresetPoolIterator it =
this->Internals->WindowLevelPresetPool.begin();
vtkMedicalImagePropertiesInternals::WindowLevelPresetPoolIterator end =
this->Internals->WindowLevelPresetPool.end();
for (; it != end; ++it)
{
if ((*it).Window == w && (*it).Level == l)
{
return 1;
}
}
}
return 0;
}
//----------------------------------------------------------------------------
void vtkMedicalImageProperties::RemoveWindowLevelPreset(double w, double l)
{
if (this->Internals)
{
vtkMedicalImagePropertiesInternals::WindowLevelPresetPoolIterator it =
this->Internals->WindowLevelPresetPool.begin();
vtkMedicalImagePropertiesInternals::WindowLevelPresetPoolIterator end =
this->Internals->WindowLevelPresetPool.end();
for (; it != end; ++it)
{
if ((*it).Window == w && (*it).Level == l)
{
this->Internals->WindowLevelPresetPool.erase(it);
break;
}
}
}
}
//----------------------------------------------------------------------------
void vtkMedicalImageProperties::RemoveAllWindowLevelPresets()
{
if (this->Internals)
{
this->Internals->WindowLevelPresetPool.clear();
}
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetNumberOfWindowLevelPresets()
{
return this->Internals ? this->Internals->WindowLevelPresetPool.size() : 0;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetNthWindowLevelPreset(
int idx, double *w, double *l)
{
if (this->Internals &&
idx >= 0 && idx < this->GetNumberOfWindowLevelPresets())
{
*w = this->Internals->WindowLevelPresetPool[idx].Window;
*l = this->Internals->WindowLevelPresetPool[idx].Level;
return 1;
}
return 0;
}
//----------------------------------------------------------------------------
double* vtkMedicalImageProperties::GetNthWindowLevelPreset(int idx)
{
static double wl[2];
if (this->GetNthWindowLevelPreset(idx, wl, wl + 1))
{
return wl;
}
return NULL;
}
//----------------------------------------------------------------------------
const char* vtkMedicalImageProperties::GetNthWindowLevelPresetComment(
int idx)
{
if (this->Internals &&
idx >= 0 && idx < this->GetNumberOfWindowLevelPresets())
{
return this->Internals->WindowLevelPresetPool[idx].Comment.c_str();
}
return NULL;
}
//----------------------------------------------------------------------------
void vtkMedicalImageProperties::SetNthWindowLevelPresetComment(
int idx, const char *comment)
{
if (this->Internals &&
idx >= 0 && idx < this->GetNumberOfWindowLevelPresets())
{
this->Internals->WindowLevelPresetPool[idx].Comment =
(comment ? comment : "");
}
}
//----------------------------------------------------------------------------
double vtkMedicalImageProperties::GetSliceThicknessAsDouble()
{
if (this->SliceThickness)
{
return atof(this->SliceThickness);
}
return 0;
}
//----------------------------------------------------------------------------
double vtkMedicalImageProperties::GetGantryTiltAsDouble()
{
if (this->GantryTilt)
{
return atof(this->GantryTilt);
}
return 0;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetAgeAsFields(const char *age, int &year,
int &month, int &week, int &day)
{
year = month = week = day = -1;
if( !age )
{
return 0;
}
size_t len = strlen(age);
if( len == 4 )
{
// DICOM V3
unsigned int val;
char type;
if( !isdigit(age[0])
|| !isdigit(age[1])
|| !isdigit(age[2]))
{
return 0;
}
if( sscanf(age, "%3u%c", &val, &type) != 2 )
{
return 0;
}
switch(type)
{
case 'Y':
year = (int)val;
break;
case 'M':
month = (int)val;
break;
case 'W':
week = (int)val;
break;
case 'D':
day = (int)val;
break;
default:
return 0;
}
}
else
{
return 0;
}
return 1;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetPatientAgeYear()
{
const char *age = this->GetPatientAge();
int year, month, week, day;
vtkMedicalImageProperties::GetAgeAsFields(age, year, month, week, day);
return year;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetPatientAgeMonth()
{
const char *age = this->GetPatientAge();
int year, month, week, day;
vtkMedicalImageProperties::GetAgeAsFields(age, year, month, week, day);
return month;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetPatientAgeWeek()
{
const char *age = this->GetPatientAge();
int year, month, week, day;
vtkMedicalImageProperties::GetAgeAsFields(age, year, month, week, day);
return week;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetPatientAgeDay()
{
const char *age = this->GetPatientAge();
int year, month, week, day;
vtkMedicalImageProperties::GetAgeAsFields(age, year, month, week, day);
return day;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetDateAsFields(const char *date, int &year,
int &month, int &day)
{
if( !date )
{
return 0;
}
size_t len = strlen(date);
if( len == 8 )
{
// DICOM V3
if( sscanf(date, "%04d%02d%02d", &year, &month, &day) != 3 )
{
return 0;
}
}
else if( len == 10 )
{
// Some *very* old ACR-NEMA
if( sscanf(date, "%04d.%02d.%02d", &year, &month, &day) != 3 )
{
return 0;
}
}
else
{
return 0;
}
return 1;
}
//----------------------------------------------------------------------------
// Some buggy versions of gcc complain about the use of %c: warning: `%c'
// yields only last 2 digits of year in some locales. Of course program-
// mers are encouraged to use %c, it gives the preferred date and time
// representation. One meets all kinds of strange obfuscations to circum-
// vent this gcc problem. A relatively clean one is to add an intermediate
// function. This is described as bug #3190 in gcc bugzilla:
// [-Wformat-y2k doesn't belong to -Wall - it's hard to avoid]
inline size_t
my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm)
{
return strftime(s, max, fmt, tm);
}
// Helper function to convert a DICOM iso date format into a locale one
// locale buffer should be typically char locale[200]
int vtkMedicalImageProperties::GetDateAsLocale(const char *iso, char *locale)
{
int year, month, day;
if( vtkMedicalImageProperties::GetDateAsFields(iso, year, month, day) )
{
struct tm date;
memset(&date,0, sizeof(date));
date.tm_mday = day;
// month are expressed in the [0-11] range:
date.tm_mon = month - 1;
// structure is date starting at 1900
date.tm_year = year - 1900;
my_strftime(locale, 200, "%x", &date);
return 1;
}
return 0;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetPatientBirthDateYear()
{
const char *date = this->GetPatientBirthDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return year;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetPatientBirthDateMonth()
{
const char *date = this->GetPatientBirthDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return month;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetPatientBirthDateDay()
{
const char *date = this->GetPatientBirthDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return day;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetAcquisitionDateYear()
{
const char *date = this->GetAcquisitionDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return year;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetAcquisitionDateMonth()
{
const char *date = this->GetAcquisitionDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return month;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetAcquisitionDateDay()
{
const char *date = this->GetAcquisitionDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return day;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetImageDateYear()
{
const char *date = this->GetImageDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return year;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetImageDateMonth()
{
const char *date = this->GetImageDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return month;
}
//----------------------------------------------------------------------------
int vtkMedicalImageProperties::GetImageDateDay()
{
const char *date = this->GetImageDate();
int year, month, day;
vtkMedicalImageProperties::GetDateAsFields(date, year, month, day);
return day;
}
//----------------------------------------------------------------------------
void vtkMedicalImageProperties::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << "\n" << indent << "PatientName: ";
if (this->PatientName)
{
os << this->PatientName;
}
os << "\n" << indent << "PatientID: ";
if (this->PatientID)
{
os << this->PatientID;
}
os << "\n" << indent << "PatientAge: ";
if (this->PatientAge)
{
os << this->PatientAge;
}
os << "\n" << indent << "PatientSex: ";
if (this->PatientSex)
{
os << this->PatientSex;
}
os << "\n" << indent << "PatientBirthDate: ";
if (this->PatientBirthDate)
{
os << this->PatientBirthDate;
}
os << "\n" << indent << "ImageDate: ";
if (this->ImageDate)
{
os << this->ImageDate;
}
os << "\n" << indent << "ImageTime: ";
if (this->ImageTime)
{
os << this->ImageTime;
}
os << "\n" << indent << "ImageNumber: ";
if (this->ImageNumber)
{
os << this->ImageNumber;
}
os << "\n" << indent << "AcquisitionDate: ";
if (this->AcquisitionDate)
{
os << this->AcquisitionDate;
}
os << "\n" << indent << "AcquisitionTime: ";
if (this->AcquisitionTime)
{
os << this->AcquisitionTime;
}
os << "\n" << indent << "SeriesNumber: ";
if (this->SeriesNumber)
{
os << this->SeriesNumber;
}
os << "\n" << indent << "SeriesDescription: ";
if (this->SeriesDescription)
{
os << this->SeriesDescription;
}
os << "\n" << indent << "StudyDescription: ";
if (this->StudyDescription)
{
os << this->StudyDescription;
}
os << "\n" << indent << "StudyID: ";
if (this->StudyID)
{
os << this->StudyID;
}
os << "\n" << indent << "Modality: ";
if (this->Modality)
{
os << this->Modality;
}
os << "\n" << indent << "ManufacturerModelName: ";
if (this->ManufacturerModelName)
{
os << this->ManufacturerModelName;
}
os << "\n" << indent << "Manufacturer: ";
if (this->Manufacturer)
{
os << this->Manufacturer;
}
os << "\n" << indent << "StationName: ";
if (this->StationName)
{
os << this->StationName;
}
os << "\n" << indent << "InstitutionName: ";
if (this->InstitutionName)
{
os << this->InstitutionName;
}
os << "\n" << indent << "ConvolutionKernel: ";
if (this->ConvolutionKernel)
{
os << this->ConvolutionKernel;
}
os << "\n" << indent << "SliceThickness: ";
if (this->SliceThickness)
{
os << this->SliceThickness;
}
os << "\n" << indent << "KVP: ";
if (this->KVP)
{
os << this->KVP;
}
os << "\n" << indent << "GantryTilt: ";
if (this->GantryTilt)
{
os << this->GantryTilt;
}
os << "\n" << indent << "EchoTime: ";
if (this->EchoTime)
{
os << this->EchoTime;
}
os << "\n" << indent << "EchoTrainLength: ";
if (this->EchoTrainLength)
{
os << this->EchoTrainLength;
}
os << "\n" << indent << "RepetitionTime: ";
if (this->RepetitionTime)
{
os << this->RepetitionTime;
}
os << "\n" << indent << "ExposureTime: ";
if (this->ExposureTime)
{
os << this->ExposureTime;
}
os << "\n" << indent << "XRayTubeCurrent: ";
if (this->XRayTubeCurrent)
{
os << this->XRayTubeCurrent;
}
os << "\n" << indent << "Exposure: ";
if (this->Exposure)
{
os << this->Exposure;
}
}