//------------------------------------------------------------------------------ // Cluster data class -- // (C) Piero Giubilato 2008-2010, Berkeley Lab -- //------------------------------------------------------------------------------ //______________________________________________________________________________ // {Trace} // [File name] "data_Layer.cpp" // [Author] "Piero Giubilato" // [Version] "1.0" // [Modified by] "Piero Giubilato" // [Last revision] "31 Jul 2009" // [Language] "C++" // [Compiler] "Visual C++ 9.x" // [Member of] "Cool SEAL" // [Project] "SEAL" // [Description] "Cluster data class" // [Key documentation] // "Root user's guide" // "Visual C++ Reference Help" // {Trace} //______________________________________________________________________________ // Overloading check #ifndef data_Cluster_C #define data_Cluster_C // Standard components #include // Application components #include "data_Cluster.h" // ***************************************************************************** // **** DATA POINT **** // ***************************************************************************** //______________________________________________________________________________ template data_Point::data_Point(Int_t x, Int_t y, T z) { dp_X = x; dp_Y = y; dp_Z = z; } //______________________________________________________________________________ template data_Point::~data_Point() { // Do nothing } //______________________________________________________________________________ template void data_Point::Dump(UInt_t level) const { // Dump the point TString space(' ', level); // Shows data members std::cout << space.Data() << "x: " << dp_X << "y: " << dp_Y << "z: " << dp_Z << "\n"; } // ***************************************************************************** // **** DATA CLUSTER **** // ***************************************************************************** //______________________________________________________________________________ template data_Cluster::data_Cluster(UInt_t pSize) { // Preserve some points to speed up operations dp_Array.reserve(pSize); } //______________________________________________________________________________ template data_Cluster::data_Cluster(Int_t x, Int_t y, T z, UInt_t pSize) { // Preserve some points to speed up operations dp_Array.reserve(pSize); // Fill the first point dp_Array.push_back(new data_Point(x, y, z)) } //______________________________________________________________________________ template data_Cluster::~data_Cluster() { // Removes all data point for (UInt_t i = 0; i < dp_Array.size(); i++) delete dp_Array[i]; dp_Array.clear(); } //______________________________________________________________________________ template void data_Cluster::Refresh() { // Calculate clusters parameters // Check if (!dp_Array.size()) return; // Set the first point cl_Mult = dp_Array.size(); cl_Min = dp_Array[0]->dp_Z; cl_Max = dp_Array[0]->dp_Z; cl_Left = (Float_t)dp_Array[0]->dp_X; cl_Right = (Float_t)dp_Array[0]->dp_X; cl_Top = (Float_t)dp_Array[0]->dp_Y; cl_Bottom = (Float_t)dp_Array[0]->dp_Y; cl_Mass = (Double_t)dp_Array[0]->dp_Z; Double_t cl_x_Mass = (Double_t)dp_Array[0]->dp_X * dp_Array[0]->dp_Z; Double_t cl_y_Mass = (Double_t)dp_Array[0]->dp_Y * dp_Array[0]->dp_Z; Float_t x, y, z; // Scans all the other points for (UInt_t i = 1; i < cl_Mult; i++) { // Get data x = (Float_t)dp_Array[i]->dp_X; y = (Float_t)dp_Array[i]->dp_Y; z = (Float_t)dp_Array[i]->dp_Z; // Boundaries if (z < cl_Min) cl_Min = z; if (z > cl_Max) cl_Max = z; if (x < cl_Left) cl_Left = x; if (x > cl_Right) cl_Right = x; if (y < cl_Bottom) cl_Bottom = y; if (y > cl_Top) cl_Top = y; // Mass cl_Mass += z; cl_x_Mass += x * z; cl_y_Mass += y * z; } // Complete calculations cl_pos_X = (Float_t)(cl_x_Mass / cl_Mass); cl_pos_Y = (Float_t)(cl_y_Mass / cl_Mass); cl_Width = cl_Right - cl_Left + 1; cl_Height = cl_Top - cl_Bottom + 1; } //______________________________________________________________________________ template void data_Cluster::Dump(UInt_t level) const { // Spacer TString space(' ', level); // Shows all the cluster's points std::cout << space.Data() << "Total points: " << dp_Array.size() << "\n"; for (UInt_t i = 0; i < dp_Array.size(); i++) { std::cout << space.Data() << "#" << i << " x: " << dp_Array[i]->dp_X << " y: " << dp_Array[i]->dp_Y << " z: " << dp_Array[i]->dp_Z << "\n"; } } //______________________________________________________________________________ template void data_Cluster::Streamer(TBuffer& b) { // Fills the standar root streamer with the current cluster points and data // Read if (b.IsReading()) { // Debug dbg_Print ("data_Cluster::Streamer:(read TBuffer&)", DBG_LVL_STEP) // Reads class version UShort_t class_ver_Read = 0; b >> class_ver_Read; // Check version if (class_ver_Read != class_Ver) { dbg_Print ("data_Cluster::Streamer:(read): version mismatch", DBG_LVL_WARN) dbg_Value(class_ver_Read, DBG_LVL_WARN); dbg_Value(class_Ver, DBG_LVL_WARN); } // Clear the object for (UInt_t i = 0; i < dp_Array.size(); i++) delete dp_Array[i]; dp_Array.clear(); // Reads the points UInt_t dp_Count; b >> dp_Count; dp_Array.reserve(dp_Count); // Reads the points list Int_t x, y; T z; for (UInt_t i = 0; i < dp_Count; i++) { b >> x; b >> y; b >> z; dp_Array.push_back(new data_Point(x, y, z)); } // Writes } else { // Debug dbg_Print ("data_Layer::Streamer:(write TBuffer&)",DBG_LVL_STEP) // Writes class version b << class_Ver; // Writes the data points b << dp_Array.size(); for (UInt_t i = 0; i < dp_Array.size(); i++) { b << dp_Array[i]->dp_X; b << dp_Array[i]->dp_Y; b << dp_Array[i]->dp_Z; } // Would be a nonsense to write the cluster parameter, much faster // to recalculate them after loading the points } } // ***************************************************************************** // **** DATA STACK **** // ***************************************************************************** //______________________________________________________________________________ template data_Stack::data_Stack(UInt_t pSize) { // Preserve some points to speed up operations cl_Array.reserve(pSize); } //______________________________________________________________________________ template data_Stack::~data_Stack() { // Removes all data point for (UInt_t i = 0; i < cl_Array.size(); i++) delete cl_Array[i]; cl_Array.clear(); // Removes all links for (UInt_t i = 0; i < cl_Link.size(); i++) delete cl_Link[i]; cl_Link.clear(); } //______________________________________________________________________________ template void data_Stack::Link(UInt_t a_Idx, UInt_t b_Idx) { // Set a link between clusters a & b // Checks if (a_Idx == b_Idx) return; if (a_Idx >= cl_Array.size()) return; if (b_Idx >= cl_Array.size()) return; // Check if the link already exist for (UInt_t i = 0; i < cl_Link.size(); i++) { if (a_Idx == cl_Link[i]->a && b_Idx == cl_Link[i]->b) return; if (a_Idx == cl_Link[i]->b && b_Idx == cl_Link[i]->a) return; } // Assign the new link cl_Link.push_back(new link(a_Idx, b_Idx)); } //______________________________________________________________________________ template void data_Stack::Merge(UInt_t a_Idx, UInt_t b_Idx) { // Merges cluster a & b, leaving b empty // Checks if (a_Idx >= cl_Array.size()) return; if (b_Idx >= cl_Array.size()) return; // Merge for (UInt_t i = 0; i < cl_Array[b_Idx]->dp_Array.size(); i++) { cl_Array[a_Idx]->dp_Array.push_back(cl_Array[b_Idx]->dp_Array[i]); } cl_Array[b_Idx]->dp_Array.clear(); } //______________________________________________________________________________ template void data_Stack::Clean() { // Merge linked clusters and remove empty clusters // Merging //std::cout << "Merging\n"; UInt_t cl_Merged = 0; while (true) { // Merge cl_Merged = 0; for (UInt_t i = 0; i < cl_Link.size(); i++) { if (cl_Array[cl_Link[i]->b]->dp_Array.size()) { Merge(cl_Link[i]->a, cl_Link[i]->b); cl_Merged++; } } // Exit with no more effective merging if (!cl_Merged) break; } // Removes empty clusters left //std::cout << "Cleaning\n"; std::vector*>::iterator cl = cl_Array.begin(); while (cl < cl_Array.end()) { if ((*cl)->dp_Array.size()) ++cl; else cl_Array.erase(cl); } // Performs a refersh of the data Refresh(); } //______________________________________________________________________________ template void data_Stack::Refresh() { // Calculates parameters for the clusters in the stack for (UInt_t i = 0; i < cl_Array.size(); i++) cl_Array[i]->Refresh(); } //______________________________________________________________________________ template void data_Stack::cut_Apply() { // Applies the set cut to the current cluster list // Make sure the clusters have been updated for (UInt_t i = 0; i < cl_Array.size(); i++) cl_Array[i]->Refresh(); // Check all the clusters std::vector*>::iterator cl = cl_Array.begin(); while (cl < cl_Array.end()) { if ((*cl)->cl_Width >= cut_width_Min && (*cl)->cl_Width <= cut_width_Max) { // Width if ((*cl)->cl_Height >= cut_height_Min && (*cl)->cl_Height <= cut_height_Max) { // Height if ((*cl)->cl_Max >= cut_top_Min && (*cl)->cl_Max <= cut_top_Max) { // Top if ((*cl)->cl_Mult >= cut_mult_Min && (*cl)->cl_Mult <= cut_mult_Max) { // Mult if ((*cl)->cl_Mass >= cut_mass_Min && (*cl)->cl_Mass <= cut_mass_Max) { // Mass ++cl; } else cl_Array.erase(cl); } else cl_Array.erase(cl); } else cl_Array.erase(cl); } else cl_Array.erase(cl); } else cl_Array.erase(cl); } } //______________________________________________________________________________ template void data_Stack::List() { // Shows all the clusters in the stack for (UInt_t i = 0; i < cl_Array.size(); i++) { std::cout << "Cl #" << i << ": x: " << cl_Array[i]->cl_pos_X << ", y: " << cl_Array[i]->cl_pos_Y << ": max: " << cl_Array[i]->cl_Max << ": mass: " << cl_Array[i]->cl_Mass << ": mult: " << cl_Array[i]->dp_Array.size() << ": width: " << cl_Array[i]->cl_Width << ": height: " << cl_Array[i]->cl_Height << "\n"; } } //______________________________________________________________________________ template void data_Stack::Dump(UInt_t level) const { // Spacer TString space(' ', level); // Shows all the clusters in the stack std::cout << space.Data() << "Total clusters: " << cl_Array.size() << "\n\n"; for (UInt_t i = 0; i < cl_Array.size(); i++) { std::cout << space.Data() << "Cluster #" << i << "\n"; cl_Array[i]->Dump(level); std::cout << "\n"; } // Show the links std::cout << space.Data() << "\nTotal links: " << cl_Link.size() << "\n\n"; for (UInt_t i = 0; i < cl_Link.size(); i++) { std::cout << space.Data() << "Cl# " << cl_Link[i]->a << " & Cl# " << cl_Link[i]->b << "\n"; } } //______________________________________________________________________________ template void data_Stack::Streamer(TBuffer& b) { // Fills the standar root streamer with the current data points // Read if (b.IsReading()) { // Debug dbg_Print ("data_Stack::Streamer:(read TBuffer&)", DBG_LVL_STEP) // Reads class version UShort_t class_ver_Read = 0; b >> class_ver_Read; // Check version if (class_ver_Read != class_Ver) { dbg_Print ("data_Stack::Streamer:(read): version mismatch", DBG_LVL_WARN) dbg_Value(class_ver_Read, DBG_LVL_WARN); dbg_Value(class_Ver, DBG_LVL_WARN); } // Reads parent class data_Object::Streamer(b); // Clear the object for (UInt_t i = 0; i < cl_Array.size(); i++) delete cl_Array[i]; cl_Array.clear(); for (UInt_t i = 0; i < cl_Link.size(); i++) delete cl_Link[i]; cl_Link.clear(); // Reads cluster number UInt_t cl_Count; b >> cl_Count; cl_Array.reserve(cl_Count); // Loads the clusters TString name; for (UInt_t i = 0; i < cl_Count; i++) { name.Form("Cl%u", i); cl_Array.push_back(new data_Cluster()); cl_Array.back()->Read(name.Data()); } // Refresh the data Refresh(); // Writes } else { // Debug dbg_Print ("data_Layer::Streamer:(write TBuffer&)",DBG_LVL_STEP) // Writes class version b << class_Ver; // Writes parent class data_Object::Streamer(b); // Writes how many clusters b << cl_Array.size(); // Writes the clusters TString name; for (UInt_t i = 0; i < cl_Array.size(); i++) { name.Form("Cl%u", i); cl_Array[i]->Write(name.Data()); } } } // Overloading check #endif