Files
glocalize/dicomUtils.cpp
T
2026-01-05 14:20:11 +01:00

486 lines
21 KiB
C++
Executable File

#include "dicomUtils.h"
//FUNCTION DECLARATION NECESSARY FOR COPY/PASTE FROM vtkGDCMImageReader
// const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds);
const char *gGetStringValueFromTag(const gdcm::Tag& t, const gdcm::DataSet& ds)
{
static std::string buffer;
buffer = ""; // cleanup previous call
if( ds.FindDataElement( t ) )
{
const gdcm::DataElement& de = ds.GetDataElement( t );
const gdcm::ByteValue *bv = de.GetByteValue();
if( bv ) // Can be Type 2
{
buffer = std::string( bv->GetPointer(), bv->GetLength() );
// Will be padded with at least one \0
}
}
// Since return is a const char* the very first \0 will be considered
return buffer.c_str();
};
//GENERAL INDEPENDENT FUNCTION TO CHECK FOR FILE DICOM MODALITY (PLAN, STRUCT, IMAGE) REQUIRES CORRECT PATH
const char * gCheckDICOMModality(const char *filename)
{
gdcm::Reader gR;
gR.SetFileName(filename);//str.toAscii().data());
if(!gR.Read())
return("NODCMFILE");
const gdcm::File &file = gR.GetFile();
const gdcm::DataSet &ds = file.GetDataSet();
return(gGetStringValueFromTag( gdcm::Tag(0x0008,0x0060), ds) ); //RETURN MODALITY
};
int gCheckDICOMModalityToInt(const char *filename){
const char * tmp = gCheckDICOMModality(filename);
//cout<< tmp<<endl;
if( !strcmp(tmp,"RTSTRUCT") )
return RTSTRUCT;
else if ( !strcmp(tmp,"RTPLAN") )
return RTPLAN;
else if( !strcmp(tmp,"CT") )
return IMAGE;
else
return NODCMFILE;
};
IonBeamProperties::IonBeamProperties(){
BeamNumber = BADVALUE;
BeamName = new char [MAXSTRINGLENGHT];
SupportId = new char [MAXSTRINGLENGHT];
SupportType = new char [MAXSTRINGLENGHT];
GantryAngle = BADVALUE;
IsocenterPosition = new double [3];
TablePitchAngle= BADVALUE;
TableRollAngle = BADVALUE;
TableYawAngle= BADVALUE;
TableLatDispl = BADVALUE;
TableLongDispl= BADVALUE;
TableVertDispl= BADVALUE;
}
IonBeamProperties::~IonBeamProperties(){
delete[] BeamName;
delete[] SupportId;
delete[] IsocenterPosition;
delete[] SupportType;
}
void IonBeamProperties::PrintSelf(){
cout<< "__ IonBeamProperties print self ** " <<endl;
cout<<" |_ BeamNumber = "<<BeamNumber<<endl;
cout<<" |_ BeamName = "<<BeamName<<endl;
cout<<" |_ SupportType = " <<SupportType<<endl;
cout<<" |_ SupportId = "<<SupportId<<endl;
cout<<" |_ GantryAngle = "<<GantryAngle<<endl;
cout<<" |_ IsocenterPosition = "<<IsocenterPosition[0]<<
IsocenterPosition[1]<<" "<<
IsocenterPosition[2]<<endl;
cout<<" |_ TableYawAngle = "<<TableYawAngle<<endl;
cout<<" |_ TablePitchAngle = "<<TablePitchAngle<<endl;
cout<<" |_ TableRollAngle = "<<TableRollAngle<<endl;
cout<<" |_ TableLatDispl = "<<TableLatDispl<<endl;
cout<<" |_ TableLongDispl = "<<TableLongDispl<<endl;
cout<<" |_ TableVertDispl = "<<TableVertDispl<<endl;
}
/*-----*/
//CLASS gIonBEAMProperties
RTPlan::~RTPlan(){
if(NumberOfBeams > 0)
for(int ii=0;ii<NumberOfBeams;ii++)
delete Beams[ii];
delete [] Beams;
delete [] PatientName;
delete [] PatientID;
delete [] PatientSex;
delete [] PatientAge;
delete [] PatientBirthDate;
delete [] SeriesNumber;
delete [] SeriesDescription;
delete [] StudyID;
delete [] StudyDescription;
delete [] Modality;
delete [] IsocenterPosition;
delete [] VolumeCenter;
delete [] BeamName;
delete [] SupportType;
delete [] PatientOrientation;
}
RTPlan::RTPlan(){
NumberOfBeams=0;
PatientName = new char [MAXSTRINGLENGHT];
PatientID = new char [MAXSTRINGLENGHT];
PatientSex = new char [MAXSTRINGLENGHT];
PatientAge = new char [MAXSTRINGLENGHT];
PatientBirthDate = new char [MAXSTRINGLENGHT];
SeriesNumber = new char [MAXSTRINGLENGHT];
SeriesDescription = new char [MAXSTRINGLENGHT];
StudyID = new char [MAXSTRINGLENGHT];
StudyDescription = new char [MAXSTRINGLENGHT];
Modality = new char [MAXSTRINGLENGHT];
IsocenterPosition = new double[3];
std::fill(IsocenterPosition,(IsocenterPosition+3),BADVALUE);
VolumeCenter= new double[3];
std::fill(VolumeCenter,(VolumeCenter+3),BADVALUE);
BeamNumber = BADVALUE;
BeamName = new char [MAXSTRINGLENGHT];
TableRollAngle = BADVALUE;
TableYawAngle= BADVALUE;
TablePitchAngle= BADVALUE;
TableLatDispl= BADVALUE;
TableVertDispl= BADVALUE;
TableLongDispl= BADVALUE;
SupportType = new char [MAXSTRINGLENGHT];
SupportId = new char [MAXSTRINGLENGHT];
PatientOrientation = new char [MAXSTRINGLENGHT];
}
void RTPlan::PrintSelf(){
cout<< "** RTPlan print self ** " <<endl;
cout<<"PatientName = "<<PatientName<<endl;
cout<<"PatientID = "<<PatientID<<endl;
cout<<"PatientSex = "<<PatientSex<<endl;
cout<<"PatientAge = "<<PatientAge<<endl;
cout<<"PatientBirthDate = "<<PatientBirthDate<<endl;
cout<<"SeriesNumber = "<<SeriesNumber<<endl;
cout<<"SeriesDescription = "<<SeriesDescription<<endl;
cout<<"StudyID = "<<StudyID<<endl;
cout<<"StudyDescription = "<<StudyDescription<<endl;
cout<<"Modality = "<<Modality<<endl;
cout<<"IsocenterPosition = "<<IsocenterPosition[0]<<" "<<
IsocenterPosition[1]<<" "<<
IsocenterPosition[2]<<endl;
cout<<"VolumeCenter = "<<VolumeCenter[0]<<" "<<
VolumeCenter[1]<<" "<<
VolumeCenter[2]<<endl;
cout<<"BeamNumber = "<<BeamNumber<<endl;
cout<<"BeamName = "<<BeamName<<endl;
cout<<"TableRollAngle = "<<TableRollAngle<<endl;
cout<<"TableYawAngle = "<<TableYawAngle<<endl;
cout<<"TablePitchAngle = "<<TablePitchAngle<<endl;
cout<<"TableVertDispl = "<<TableVertDispl<<endl;
cout<<"TableLongDispl = "<<TableLongDispl<<endl;
cout<<"SupportType = "<<SupportType<<endl;
cout<<"SupportId = "<<SupportId<<endl;
cout<<"PatientOrientation = "<<PatientOrientation<<endl;
if(NumberOfBeams > 0)
for(int ii=0; ii<NumberOfBeams;ii++)
Beams[ii]->PrintSelf();
}
bool RTPlan::fillRTPlan( char *filertionplan){
cout<<"reading filename: "<<filertionplan<<endl;
gdcm::Reader R;
R.SetFileName(filertionplan);
if(!R.Read())
{ cout<<"ERROR: cannot read filertionplan."<<endl;
}
const gdcm::File &file = R.GetFile();
const gdcm::DataSet &ds = file.GetDataSet();
//GENERAL PATIENT AND STUDY DATE
//PATIENT NAME
strcpy( PatientName,gGetStringValueFromTag( gdcm::Tag(0x0010,0x0010), ds));
// // // PATIENT ID For ex: DICOM (0010,0020) = 1933197
strcpy(PatientID , gGetStringValueFromTag( gdcm::Tag(0x0010,0x0020), ds));
// //
// // // PATIENT AGE For ex: DICOM (0010,1010) = 031Y
strcpy(PatientAge , gGetStringValueFromTag( gdcm::Tag(0x0010,0x1010), ds)) ;
// //
// // // PATIENT SEX For ex: DICOM (0010,0040) = M
strcpy(PatientSex, gGetStringValueFromTag( gdcm::Tag(0x0010,0x0040), ds) );
// //
// // // PATIENT BIRTHDATE For ex: DICOM (0010,0030) = 19680427
strcpy(PatientBirthDate, gGetStringValueFromTag( gdcm::Tag(0x0010,0x0030), ds) );
// //
// // // SERIES NUMBER For ex: DICOM (0020,0011) = 902
strcpy(SeriesNumber, gGetStringValueFromTag( gdcm::Tag(0x0020,0x0011), ds) );
// //
// // // SERIES DESCRIPTION For ex: DICOM (0008,103e) = SCOUT
strcpy(SeriesDescription , gGetStringValueFromTag( gdcm::Tag(0x0008,0x103e), ds) );
// //
// // // STUDY ID For ex: DICOM (0020,0010) = 37481
strcpy(StudyID, gGetStringValueFromTag( gdcm::Tag(0x0020,0x0010), ds) );
// //
// // // STUDY DESCRIPTION For ex: DICOM (0008,1030) = BRAIN/C-SP/FACIAL
strcpy(StudyDescription, gGetStringValueFromTag( gdcm::Tag(0x0008,0x1030), ds) );
// //
// // // STUDY MODALITY For ex: DICOM (0008,0060)= CT
strcpy(Modality, gGetStringValueFromTag( gdcm::Tag(0x0008,0x0060), ds) );
//TREATMENT GEOMETRY
//IONI 0x300a,0x00b0
// radiation 0x300ax00c6
//FIND TAG BEAMSequence
//v04Build27 HANDLE PROTON vs CARBONION
bool IsCarbon=false;
//v04Build27 CHECK EXISTANCE SETUP SEQUENCE (PRESENT IN PROTN ABSENT IN IONS)
if(!ds.FindDataElement(gdcm::Tag(0x300a,0x03a2)))
IsCarbon=true;
//QUI HFP vs HFS
//v04 Build29: LOOK FOR SETUP SEQUENCE TO SEARHC FOR PATINET ORIENTATION
const gdcm::DataElement &gSetupSequence=ds.GetDataElement(gdcm::Tag(0x300a,0x0180));
//LOOK FOR PATIENT ORIENTATION
gdcm::SmartPointer<gdcm::SequenceOfItems> sqiPS = gSetupSequence.GetValueAsSQ();
const gdcm::DataSet& gPatSetupNest = sqiPS->GetItem(1).GetNestedDataSet();
//SET PATIENT ORIENTATION STRING
strcpy(PatientOrientation, gGetStringValueFromTag(gdcm::Tag(0x0018, 0x5100),gPatSetupNest));
const gdcm::DataElement &gBeamSequence=ds.GetDataElement(gdcm::Tag(0x300a,(IsCarbon==false ? 0x03a2 : 0x00b0)));
// (THESE ARE THE BEAMS)
gdcm::SmartPointer<gdcm::SequenceOfItems> sqi = gBeamSequence.GetValueAsSQ();
if(!sqi || !sqi->GetNumberOfItems())
{
cout<<"usteria" <<endl;//throw(gException("CRITICAL: Beam sequence not found in RTION Plan file"));
}
NumberOfBeams=sqi->GetNumberOfItems();
//ALLOCATE BEAM STRUCTURES
Beams=new IonBeamProperties* [NumberOfBeams];
//memset(Beams,NULL,NumberOfBeams*sizeof(IonBeamProperties *));
memset(Beams, 0, NumberOfBeams * sizeof(IonBeamProperties*));
//ITERATES ON BEAM NUMBER
for(int i=0;i<NumberOfBeams;i++)
{ const gdcm::Item & item = sqi->GetItem(i+1); //ITEM START FROM 1
const gdcm::DataSet& gBeamNestedds = item.GetNestedDataSet(); //THIS IS BEAM DATASET
//ALLOCATE BEAM CLASS
Beams[i]=new IonBeamProperties;
//READ BEAM DATA
Beams[i]->BeamNumber = (atoi(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x00c0),gBeamNestedds))); //BEAM NUMBER
strcpy (Beams[i]->BeamName,(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x00c2),gBeamNestedds))); //BEAM NAME
if(IsCarbon==false)
strcpy (Beams[i]->SupportType,gGetStringValueFromTag(gdcm::Tag(0x300a, 0x0350),gBeamNestedds));//PATIENT SUPPORT TYPE IMPLEMENT TRICK FOR THE CHAIR
else strcpy(Beams[i]->SupportType,"TABLE");
strcpy(Beams[i]->SupportId,gGetStringValueFromTag(gdcm::Tag(0x300a, 0x0352),gBeamNestedds));//PATIENT SUPPORT TYPE IMPLEMENT TRICK FOR THE CHAIR
//gBeams[i]->gSetSupportType("CHAIR");
//READ GEOMETRY
//READ SEQUENCE OF CONTROL POINTS
//v04Build27 DO DIFFERENTLY IF PROTONS OR CARBONS
const gdcm::DataElement &gCPSequence=gBeamNestedds.GetDataElement(gdcm::Tag(0x300a,IsCarbon==false ? 0x03a8 : 0x0111));
//FIND ITEM SEQUENCE (THESE ARE THE CONTROL POINTS)
gdcm::SmartPointer<gdcm::SequenceOfItems> sqicp = gCPSequence.GetValueAsSQ();
//READ DATA FROM ITEM 1
const gdcm::DataSet& gCPNestedds = sqicp->GetItem(1).GetNestedDataSet();
//GANTRY ANGLE (NEEDED FOR CHAIR ?)
Beams[i]->GantryAngle=atoi(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x011e),gCPNestedds));
//ISOCENTER POSITION (THIS IS BEAM POSITION NOT PATIENT ALIGNMENT (VOLUME CENTER) POSITION)
double iso[3];
char str[MAXSTRINGLENGHT];
strcpy(str,gGetStringValueFromTag(gdcm::Tag(0x300a, 0x012c),gCPNestedds));
Beams[i]->IsocenterPosition[0]=atof(strtok(str,"\\"));
Beams[i]->IsocenterPosition[1]=atof(strtok(NULL,"\\"));
Beams[i]->IsocenterPosition[2]=atof(strtok(NULL,"\\"));
// Beams[i]->IsocenterPosition[](iso[0],iso[1],iso[2]);
//SUPPORT ANGLE (YAW ANGLE OF SUPPORT WITH RESPECT TO FIXED REFERENCE SYSTEM) AROUND Z AXIS (VERTICAL)
//POSITIVE COUNTER-CLOCKWISE WHEN VIEWED FROM TOP OF Z-Axis
Beams[i]->TableYawAngle=atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x0122),gCPNestedds));
/*if(i==1)
gBeams[i]->gSetTableYawAngle(0);
*/
//TABLE TOP PITCH (ROTATION AROUND X AXIS, i.e. LATERAL AXIS OF TABLE AND BEAM DIRECTION IN FIXED REF SYS)
////v04Build27 IF PROTONS READ IT FROM PLAN; IF CARBONS SET DEFAULT VALUE (0.0) AND FORGET CHAIR
if(IsCarbon==false)
{ gdcm::Attribute <0x300a, 0x0140> pa;
pa.SetFromDataElement(gCPNestedds.GetDataElement( pa.GetTag()));
Beams[i]->TablePitchAngle =pa.GetValue();
}
else
(Beams[i]->TablePitchAngle)=(0.0);
//v04 Build23 SET SUPPORT TYPE CORRECTLY IF PITCH IS 90 (IT IS CHAIR); DO IT FOR ALL BEAMS
// if(i==0)
// { if(Beams[i]->TablePitchAngle()>45)
// strcpy (Beams[i]->SupportType,("CHAIR"));
// }
// else if (i>0)
// { if(Beams[0]->SupportChair()==true)
// Beams[i]->gSetSupportType("CHAIR");
// }
//TABLE TOP ROLL (ROTATION AROUND Y AXIS, i.e. LONGITUDINAL AXIS OF TABLE)
//v04Build27 IF PROTONS READ IT FROM PLAN; IF CARBONS SET DEFAULT VALUE (0.0)
if(IsCarbon==false)
{ gdcm::Attribute <0x300a, 0x0144> ra;
ra.SetFromDataElement(gCPNestedds.GetDataElement(ra.GetTag()));
Beams[i]->TableRollAngle =(ra.GetValue());
}
else
(Beams[i]->TableRollAngle)=(0.0);
//WHAT ABOUT TABLE TOP VERTICAL POSITION, LOGITUDINAL AND LATERAL POSITION ? USEFUL SOMEHOW ?
// THEY ARE READ AND USED TO REALIZE VOLUME CENTER ALIGNMENT IN ROOM ISOCENTER
//FIND PATIENT SETUP SEQUENCE (IT IS UNIQUE FOR ALL BEAMS BUT I DO IT BEAM BY BEAM)
//v04Build27 DO NOT LOOK FOR PATIENT SETUPSEQUENCE
/* if(!ds.FindDataElement(gdcm::Tag(0x300a,0x0180)))
throw(gException("CRITICAL: PATIENT SETUP SEQUENCE NOT FOUND IN RT ION PLAN"));
const gdcm::DataElement &gPatientSetupSequence=ds.GetDataElement(gdcm::Tag(0x300a,0x0180));
gdcm::SmartPointer<gdcm::SequenceOfItems> sqpt = gPatientSetupSequence.GetValueAsSQ();
int psuseq=sqpt->GetNumberOfItems(); //CHECK NUMBER OF SETUPSEQUENCE VS BEAM NUMBER
//READ DATA FROM ITEM 1 OR BEAM IS MORE PATIENT SETUP SEQUENCE ARE FOUND (ATTENTION !!!!)
//v03 Build30: READ TABLE POSITIONS FROM SETUPSEQUENCE
const gdcm::DataSet& gPSNestedds = sqpt->GetItem((i+1)<=psuseq ? (i+1) : 1).GetNestedDataSet(); //IF PSTIENT SETUP SEQUENCE < THAN BEAMS USE FIRST
*/
//v04Build27 READ BEAMS ABSOLUTE GEOMETRY NOT FROM SETUP SEQUENCE BUT FROM CONTROL POINT SEQUENCE (NEW VERSION OIS FOR CARBONS)
/*float tablelat=atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x01d6),gPSNestedds));
float tablelong=atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x01d4),gPSNestedds));
float tablevert=atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x01d2),gPSNestedds));*/
float deltatablelat=atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x012a),gCPNestedds));
float deltatablelong=atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x0129),gCPNestedds));
float deltatablevert=atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x0128),gCPNestedds));
//v03 (Build 30) NOW ADD TO TREATMENT BEMA EVENTUAL RELATIVE SHIFTS BETWEEN SETUP SEQUENCE AND STORE IN BEAM STRUCTURE ONLY TO TREATMETN BEAMS
// if(i==0) //THIS IS SETUP BEAM DO NOTHING
//v04Build26 TREAT ALL BEAMS THE SAME WAY (SET-UP+BEAMS)(NEW VERSION OF OIS)
//v04Build27 USE PPS GEOMETRY READ FROM POINT SEQUENCE
{ Beams[i]->TableLatDispl=(deltatablelat);
Beams[i]->TableLongDispl=(deltatablelong);
Beams[i]->TableVertDispl=(deltatablevert);
}
/* else
{ gBeams[i]->gSetTableLatDispl(tablelat);
gBeams[i]->gSetTableLongDispl(tablelong);
gBeams[i]->gSetTableVertDispl(tablevert);
}*/
//v04Build26 DO NOT ADD DELTASHIFTS (NEW VERSION OF OIS)
//v04Build1: CHECK FOR VIRTUAL ISO
//ADD DELTASHIFTS TO TABLE DISPLACEMENTS
//v04Build26 DO NOT ADD DELTASHIFTS (NEW VERSION OF OIS)
/*gBeams[i]->gSetTableLatDispl(tablelat+atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x012a),gCPNestedds)));
gBeams[i]->gSetTableLongDispl(tablelong+atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x0129),gCPNestedds)));
gBeams[i]->gSetTableVertDispl(tablevert+atof(gGetStringValueFromTag(gdcm::Tag(0x300a, 0x0128),gCPNestedds)));
//UPDATE ISOCENTER POSITION ON TREATMENT BEAM USING CT REFERENCE (LONG IS Z COORDINATE; Y IS VERTICAL; Z I)
//v04Build26 DO NOT ADD DELTASHIFTS (NEW VERSION OF OIS)
gBeams[i]->gSetIsocenterPosition(iso[0]-deltatablelat,iso[1]-deltatablevert,iso[2]-deltatablelong); //SIGNS AND COORDINATE TO BE CHECKED (OK for LONG)
}
*/
//v04Build28 CORRECT ISO POSITION IN CASE OF VIRTUAL ISO
/* if(i<0) //DO THIS ONLY FOR TREATMENT BEAMS
gBeams[i]->gSetIsocenterPosition(iso[0]-(gBeams[i]->gGetTableLatDispl()-gBeams[0]->gGetTableLatDispl()),iso[1]-(gBeams[i]->gGetTableVertDispl()-gBeams[0]->gGetTableVertDispl()),iso[2]-(gBeams[i]->gGetTableLongDispl()-gBeams[0]->gGetTableLongDispl())); //SIGNS AND COORDINATE TO BE CHECKED (OK for LONG)
*/
//UPDATE AT FIRST CNAO PATIENT SET TABLE POSITION FROM PLAN AT THE ISOCENTER POSITION FOR EVERY BEAM
/* gBeams[i]->gSetTableLatDispl(gBeams[i]->gGetIsocenterPosition()[0]);
gBeams[i]->gSetTableLongDispl(gBeams[i]->gGetIsocenterPosition()[1]);gui
gBeams[i]->gSetTableVertDispl(gBeams[i]->gGetIsocenterPosition()[2]);
*/
// FILL gPPS CLASS WITH CURRENT PPS CONFIGURATION UPDATING CONVENTIONS FROM PLAN TO PPS (-90 FOR CONVENTION CT-PPS)
// Beams[i]->gGetCurrentPPS()->gSetPPSXPlan(gBeams[i]->gGetTableLatDispl());
// Beams[i]->gGetCurrentPPS()->gSetPPSYPlan(gBeams[i]->gGetTableLongDispl());
// Beams[i]->gGetCurrentPPS()->gSetPPSYOrig(gBeams[i]->gGetTableLongDispl()); //SAVE ALSO AN ORIGINAL COPY FROM PLAN OF LONGITUFINAL POSITION (FOR INDEXING DIALOG)
// Beams[i]->gGetCurrentPPS()->gSetPPSZPlan(gBeams[i]->gGetTableVertDispl());
//
//v03 Build35: ADD TO TREATMENT BEAMS YAW THE YAW VALUE OF SETUP BEAM TO RECOVER ABSOLUTE VALUES FROM RELATIVE ONES AS SENT BY OIS
if(i>0) // THIS IS TREATMENT BEAM
{ //v04Build03 SET PROPER DELTA ANGLES FOR BEAM ROTATION (IF DELTA IS NEGATIVE SET IT NEGATIVE)
double yaw=Beams[i]->TableYawAngle;
if(yaw>180)
yaw=yaw-360;
//V04Build26 NEW VERSION OF MOSAIQ OIS DO NOT USE RELATIVE ANGLES
//yaw=yaw+gBeams[0]->gGetTableYawAngle();
Beams[i]->TableYawAngle=(yaw);
double pitch=Beams[i]->TablePitchAngle;
if(pitch>180)
pitch=pitch-360;
//V04Build26 NEW VERSION OF MOSAIQ OIS DO NOT USE RELATIVE ANGLES
//pitch=pitch+gBeams[0]->gGetTablePitchAngle();
//v04Build23 SET ALL PITCH AT 90 (NOT STABLE) IT IS FOR THE CHAIR
if(pitch>150) pitch=90;
Beams[i]->TablePitchAngle=(pitch);
double roll=Beams[i]->TableRollAngle;
if(roll>180)
roll=roll-360;
//V04Build26 NEW VERSION OF MOSAIQ OIS DO NOT USE RELATIVE ANGLES
//roll=roll+gBeams[0]->gGetTableRollAngle();
Beams[i]->TableRollAngle=(roll);
}
//HERE 90 DEGREES IS SUMMED IN ORDER TO SOLVE TEH AMBIGUITY BETWEEN TPS REFERENCE AND ROOM/ODEVIS REFERENCE
//0 DEGREE YAW IN TPS BECOMES +90 YAW IN ROOM/PPS MEANING BEAM IS FROM LATERAL
//THIS WE DO IT JUST FOR THE USER INTERFACE DISPLAYING DEGREES OF YAW ROTATION EXPECTED OR TO BE INSERTED IN THE PPS
//v04Build24 ADJUST PPS YAW ANGLE FOR PPS AND CHAIR
// double yaw=gBeams[0]->gIsSupportChair()==false ? gBeams[i]->gGetTableYawAngle()+90.0 : gBeams[i]->gGetTableYawAngle()-90.0;
// //NOW SET +- 180 YAW ROTATION CONVENTION
// if(yaw>180)
// yaw=yaw-360;
// gBeams[i]->gGetCurrentPPS()->gSetPPSRotateDegreePlan(yaw); //CONVERSION FROM CT BASE PLAN TO PPS (ANGLE RANGES -180 +180)
//
// //v04Build23 ATTENZIONE !
// if(gBeams[0]->gIsSupportChair()==false) gBeams[i]->gGetCurrentPPS()->gSetPPSPitchDegreePlan(gBeams[i]->gGetTablePitchAngle());
// else gBeams[i]->gGetCurrentPPS()->gSetPPSPitchDegreePlan(gBeams[i]->gGetTablePitchAngle()-90); //NEED TO SUBTRACT 90 DEGRESS FOR PPS CONFIGURATION : THERE IS THE CHAIR
//
// gBeams[i]->gGetCurrentPPS()->gSetPPSRollDegreePlan(gBeams[i]->gGetTableRollAngle());
//
//
//
// //SET CURRENT PPS CONFIGURATION WITH PLAN CONFIGURATION (THERE I TAKE CARE OF THE CHAIR)
// gBeams[i]->gGetCurrentPPS()->gSetPlanConfig();
/* //UPDATE TABLE DISPLACEMENT ACCORDING TO SIEMENS TPS USING THE ISOCENTER CO-ORDINATESIF DEFINE W.R.T. INDEXING POINT
//MIGHT NEED TO SUBTRACT COORDINATES OF STRUCTURE VOLUMECENTER IF RELATIVE REFERENCE SYSTEM IS NOT DEFINED IN TPS
gBeams[i]->gSetTableLatDispl(gBeams[i]->gGetIsocenterPosition()[0]);
gBeams[i]->gSetTableLongDispl(gBeams[i]->gGetIsocenterPosition()[1]);
gBeams[i]->gSetTableVertDispl(gBeams[i]->gGetIsocenterPosition()[2]);*/
// gBeams[i]->gSetIsocenterPosition(iso[0]- gBeams[i]->gGetCurrentPPS()->getPPSXPlan(),iso[1]- gBeams[i]->gGetCurrentPPS()->getPPSYPlan(),iso[2]- gBeams[i]->gGetCurrentPPS()->getPPSZPlan());
}
return true;
};