Commit de93a207 authored by Chad Lantz's avatar Chad Lantz
Browse files

Added surveys for precise detector location information

parent 8a9b141b
......@@ -54,6 +54,11 @@ class Analysis{
Alignment* m_alignment;
/** Alignment information for the given run */
Alignment2021* m_alignment2021;
/** X position of the beam incident on the detector */
double beamX;
/** Y position of the beam incident on the detector */
double beamY;
};
#endif
......@@ -12,6 +12,9 @@
#include "Containers.h"
#include "TH1.h"
#include "TF1.h"
#include "TMath.h"
#include "Math/Vector3D.h"
#include "Math/GenVector/Quaternion.h"
#include <iostream>
#include <vector>
......@@ -184,5 +187,20 @@ class Alignment2021 {
std::string Det6;
};
class Survey{
public:
/** Name of the detector this survey entry is for */
std::string detector;
/** Position of the Detector during the survey*/
ROOT::Math::XYZVector pos;
/** Table position during survey */
ROOT::Math::XYZVector table;
/** Trigger table position during survey */
ROOT::Math::XYZVector trig_table;
/** Quaternion for this detector*/
ROOT::Math::Quaternion q;
};
#endif
......@@ -47,9 +47,10 @@ class DataReader2021{
void ReadListOfFiles( std::string listname );
void LoadAlignmentFile (std::string _inFile = "");
void LoadConfigurationFile (std::string _inFile = "");
void LoadTimingFile (std::string _inFile = "" );
void LoadAlignmentFile ( std::string _inFile = "" );
void LoadConfigurationFile ( std::string _inFile = "" );
void LoadTimingFile ( std::string _inFile = "" );
void LoadSurveyFile ( std::string _inFile = "" );
void SetDebugMode ( ) { m_debug = true; }
void SetVerbosity ( int _level ){ m_verbose = _level; }
void SetOutputDirectory ( std::string _dir ){ m_outputDir = _dir; }
......
......@@ -16,7 +16,11 @@
#include "Containers.h"
#include "Visualizer.h"
#include "TTree.h"
#include "Math/GenVector/EulerAngles.h"
#include "Math/GenVector/Quaternion.h"
#include "Math/GenVector/VectorUtil.h"
class Detector{
......@@ -27,18 +31,19 @@ class Detector{
virtual ~Detector( );
virtual void LoadElements(std::vector< Channel* > _elements, int _runNumber){ std::cout << "It's using the mother class LoadElements()" << std::endl;}
virtual bool LoadSurvey (std::vector< Survey* > _surveys);
virtual Channel* GetElement (int row, int column);
virtual Channel* GetElement (std::string _name);
virtual std::vector < Channel* > GetChannelsVector () { return m_Element; }
virtual double* GetPosition ( ) { return m_Position; }
virtual double* GetAngle ( ) { return m_Angle; }
virtual Alignment* GetAlignment( ) { return m_Alignment; }
virtual ROOT::Math::XYZVector GetPosition ( );
virtual ROOT::Math::XYZVector GetBeamPos ( );
virtual ROOT::Math::EulerAngles GetAngles ( ) { return ROOT::Math::EulerAngles(m_Survey->q); }
virtual Alignment* GetAlignment( ) { return m_Alignment; }
virtual Alignment2021* GetAlignment2021( ) { return m_Alignment2021; }
virtual Survey* GetSurvey( ){ return m_Survey; }
virtual void SetNSamples ( int _nSamples ) { m_nSamp = _nSamples; }
virtual void SetElement ( Channel* _entry) { m_Element.push_back(_entry); }
virtual void SetPosition ( double x, double y, double z) { m_Position[0] = x; m_Position[1] = y; m_Position[2] = z; }
virtual void SetAngle ( double _cosx = 0, double _cosy = 0, double _cosz = 0) { m_Angle[0] = _cosx; m_Angle[1] = _cosy; m_Angle[2] = _cosz; }
virtual void SetBranches ( TTree* _dataTree );
virtual void SetAlignment ( Alignment* _alignment ){ m_Alignment = _alignment; }
virtual void SetAlignment2021 ( Alignment2021* _alignment ){ m_Alignment2021 = _alignment; }
......@@ -76,10 +81,8 @@ class Detector{
std::vector< std::vector < TObject* >* >* hMarksFront;
/** 2d vector of TMarkers or TLines to be drawn on the pads. 1st index is channel number, 2nd index is mark to be drawn */
std::vector< std::vector < TObject* >* >* hMarksBack;
/** Three element array with x, y, and z of some pre-defined point on the detector **/
double m_Position[3];
/** Three element array of angle about the x, y, and z axis **/
double m_Angle[3];
/** Position of the center of the active area in beam line coordinates **/
ROOT::Math::XYZVector m_Position;
/** Hit threshold to be set for all channels in this detector */
double m_Threshold = 3.5;
/** Smoothing factor (number of bins to be summed) in calculation of waveform first derivative */
......@@ -104,6 +107,8 @@ class Detector{
Alignment* m_Alignment = 0;
/** Alignment of the 2021 Testbeam */
Alignment2021* m_Alignment2021 = 0;
/** Survey for this detector */
Survey* m_Survey = 0;
};
#endif
......@@ -349,6 +349,89 @@ void DataReader2021::LoadTimingFile(std::string _inFile){
std::cout << "Timing File: loading complete " << std::endl;
}
/** @brief Loads calibrated timing information for DRS4 modules based on run number
* @param _inFile Optional argument for loading a custom file
*
* Uses run number to determine scan number and loads the appropriate DRS4 timing
* information from the 2018 Testbeam. After loading, we hand each Channel a
* pointer to its timing vector. Must be run after LoadConfigurationFile()
*
*/
void DataReader2021::LoadSurveyFile(std::string _inFile){
if( _inFile == "" ) _inFile = std::getenv("JZCaPA") + std::string("/Utils/Survey_2021.xml");
m_XMLparser = new XMLSettingsReader();
if (!m_XMLparser->parseFile(_inFile)) {
std::cerr << " Data Reader could not parse file : " << _inFile << std::endl;
return;
}
std::vector < Survey* > surveyEntries;
int first_run, last_run;
double x,y,z,tx,ty,ttx,tty,qw,qi,qj,qk;
for (unsigned int i = 0; i < m_XMLparser->getBaseNodeCount("Survey"); i++) {
Survey *buffer = new Survey();
m_XMLparser->getChildValue("Survey",i,"start_run",first_run);
m_XMLparser->getChildValue("Survey",i,"end_run",last_run);
//Discard entries for any channel that does not apply to our run
if(m_runNumber < first_run || m_runNumber > last_run) continue;
//If the entry applies, we store it in the vector
m_XMLparser->getChildValue("Survey",i,"detector",buffer->detector);
std::cout << "Parsing " << buffer->detector << " from run " << first_run << " to " << last_run << std::endl;
m_XMLparser->getChildValue("Survey",i,"x_pos",x);
m_XMLparser->getChildValue("Survey",i,"y_pos",y);
m_XMLparser->getChildValue("Survey",i,"z_pos",z);
buffer->pos.SetXYZ(x,y,z);
m_XMLparser->getChildValue("Survey",i,"trigger_x",ttx);
m_XMLparser->getChildValue("Survey",i,"trigger_y",tty);
buffer->trig_table.SetXYZ(ttx,tty,0.0);
m_XMLparser->getChildValue("Survey",i,"table_x",tx);
m_XMLparser->getChildValue("Survey",i,"table_y",ty);
buffer->table.SetXYZ(tx,ty,0.0);
m_XMLparser->getChildValue("Survey",i,"w",qw);
m_XMLparser->getChildValue("Survey",i,"i",qi);
m_XMLparser->getChildValue("Survey",i,"j",qj);
m_XMLparser->getChildValue("Survey",i,"k",qk);
buffer->q.SetComponents(qw,qi,qj,qk);
bool isNew(true);
for( int k = 0; k < surveyEntries.size(); k++){
if(buffer->detector == surveyEntries.at(k)->detector){
std::cout << "WARNING!!! Redundancy in your settings file for " << buffer->detector << ". Check it carefully. The second entry found will be skipped..." << std::endl;
isNew = false;
}
}
if(isNew) surveyEntries.push_back(buffer);
}
std::string names = "";
bool found = false;
//Hand the surveys to the detectors so they can pick theirs from the list
//If a detector doesn't find its survey, remove it from the vector (and analysis)
//If it does find its survey, add its name to the list to print for the user
for(int det = 0; det < m_detectors.size(); det++){
found = m_detectors.at(det)->LoadSurvey(surveyEntries);
if( !found ){
std::cout << "No survey entries found for " << m_detectors.at(det)->GetName() << ". Removing detector from analysis." << std::endl;
m_detectors.erase(m_detectors.begin() + det);
}else{
names+= m_detectors.at(det)->GetName() + "; ";
}
}
std::cout << "Detectors found in survey file: " << names << std::endl << std::endl;
delete m_XMLparser; m_XMLparser = NULL;
}
/**
* @brief DataReader2021::GetDetector allows the user to access the detectors objects after loading them at the beginning of the execution
* @param _detName can be ZDC1 (upstream module), ZDC2 (downstream module) or RPD.
......
......@@ -38,6 +38,61 @@ Detector::~Detector( ){
}
/** @brief Load the survey into this detector
* @param Vector of surveys for all detectors
*
* Searches for the relevant survey within the input vector
*
*/
bool Detector::LoadSurvey( std::vector< Survey* > _surveys ){
for(int i = 0; i < _surveys.size(); i++){
if(_surveys[i]->detector == m_name){
m_Survey = _surveys[i];
return true;
}
}
return false;
}
/** @brief Get the position of the center detector active area in beamline coordinates
*
*/
ROOT::Math::XYZVector Detector::GetPosition(){
//If the position hasn't been set, calculate it
if(m_Position.x() == 0 && m_Position.y() == 0 && m_Position.z() == 0){
float x,y;
if(m_Alignment != 0){
x = m_Alignment->x_table - m_Survey->table.x() + m_Survey->pos.x();
y = m_Alignment->y_table - m_Survey->table.y() + m_Survey->pos.y();
}
if(m_Alignment2021 != 0){
x = m_Alignment2021->x_det_table - m_Survey->table.x() + m_Survey->pos.x();
y = m_Alignment2021->y_det_table - m_Survey->table.y() + m_Survey->pos.y();
}
m_Position.SetXYZ(x,y,m_Survey->pos.z());
}
return m_Position;
}
/** @brief Get the position of the beam relitave to the center of the active area of the detector
*
*/
ROOT::Math::XYZVector Detector::GetBeamPos(){
ROOT::Math::XYZVector pos = GetPosition();
ROOT::Math::XYZVector beamPos;
//For now just switch from beam coordinates to detector coordinates.
//Future behavior should involve data from wire chambers
beamPos.SetXYZ(-pos.x(),-pos.y(),0.0);
return beamPos;
}
/** @brief Get the properties of a detector element
* @param row Row of element to be accessed
* @param column Column of element to be accessed
......
......@@ -68,7 +68,7 @@ void EM::LoadElements( std::vector < Channel* > _elements, int _runNumber ){
for(int i=0; i < (int)_elements.size(); i++){
if(_elements.at(i)->mapping_row == rowTranslation[row]
&& _elements.at(i)->mapping_column == colTranslation[column]
&& ( _elements.at(i)->detector == "EM" ) ){
&& ( _elements.at(i)->detector == GetName() ) ){
m_SortedElements.at(row).push_back(_elements.at(i));
std::cout << Form("Config: X_Col[%d], Y_Row[%d] -> Array: X_Col[%d], Y_Row[%d] -> Channel[%s] -> Det[%s]",
......
......@@ -45,7 +45,7 @@ void EMAnalysis::Initialize( std::vector < Detector* > _vDet ){
for( auto& det : _vDet ){
if(det->GetChannelsVector().size() == 0) continue;
if(det->GetChannelsVector().at(0)->detector == "EM" ){ //CHECK FOR 2021!
if(det->GetChannelsVector().at(0)->detector == "UEM" ){ //CHECK FOR 2021!
m_EM = (EM*) det;
m_alignment2021 = m_EM->GetAlignment2021();
m_numRows = m_EM->GetnRows();
......@@ -58,12 +58,8 @@ void EMAnalysis::Initialize( std::vector < Detector* > _vDet ){
}
}
double tableOffsetX, tableOffsetY;
tableOffsetX = 1.2930;
tableOffsetY = 0.8630;
m_beamPosX = -(m_alignment2021->x_det_table + tableOffsetX)*100;
m_beamPosY = -(m_alignment2021->y_det_table + tableOffsetY)*100;
beamX = m_EM->GetBeamPos().x();
beamY = m_EM->GetBeamPos().y();
}
/** @brief Historgam Setup method for EMAnalysis
......@@ -111,6 +107,8 @@ void EMAnalysis::SetupHistograms( ){
void EMAnalysis::SetBranches( TTree* _tree ){
m_AnalysisTree = _tree;
m_AnalysisTree->Branch( "em_BeamX", &beamX, "em_BeamX/D");
m_AnalysisTree->Branch( "em_BeamY", &beamY, "em_BeamY/D");
for(int row = 0; row < m_numRows; row++){
for(int col = 0; col < m_numCols; col++){
m_AnalysisTree->Branch( Form("em%d_%d_Charge", row, col), "std::vector<double>", &em[row][col]->Charge );
......
......@@ -72,15 +72,9 @@ void RPDAnalysis2021::Initialize( std::vector < Detector* > _vDet ){
hMarksFront->push_back( new std::vector< TObject* > );
}
}
double tableOffsetX, tableOffsetY;
tableOffsetX = 1.2930;
tableOffsetY = 0.8630;
//}
//Position in cm
//if table goes towards Jura - the beam moves on the detector goes towarrds Saleve
//same logic for top/bottom
m_beamPosX = -(m_alignment2021->x_det_table + tableOffsetX)*100;
m_beamPosY = -(m_alignment2021->y_det_table + tableOffsetY)*100;
beamX = m_RPD->GetBeamPos().x();
beamY = m_RPD->GetBeamPos().y();
}
......@@ -129,6 +123,9 @@ void RPDAnalysis2021::SetupHistograms( ){
void RPDAnalysis2021::SetBranches( TTree* _tree ){
m_AnalysisTree = _tree;
m_AnalysisTree->Branch( "rpd_BeamX", &beamX, "rpd_BeamX/D");
m_AnalysisTree->Branch( "rpd_BeamY", &beamY, "rpd_BeamY/D");
for(int row = 0; row < 4; row++){
for(int col = 0; col < 4; col++){
m_AnalysisTree->Branch( Form("rpd%d_%d_Charge", row, col), "std::vector<double>", &rpd[row][col]->Charge );
......
......@@ -60,7 +60,12 @@ void ScintillatorsAnalysis2021::Initialize( std::vector < Detector* > _vDet ){
m_sciSH = det->GetElement(2,2);
}
}
m_alignment2021 = m_scintillator->GetAlignment2021();
Survey* survey = m_scintillator->GetSurvey();
beamX = m_alignment2021->x_trig_table - survey->trig_table.x() + survey->pos.x();
beamY = m_alignment2021->y_trig_table - survey->trig_table.y() + survey->pos.y();
}
......@@ -83,6 +88,10 @@ void ScintillatorsAnalysis2021::SetupHistograms( ){
*/
void ScintillatorsAnalysis2021::SetBranches( TTree* _tree ){
m_AnalysisTree = _tree;
m_AnalysisTree->Branch( "trig_BeamX", &beamX, "trig_BeamX/D");
m_AnalysisTree->Branch( "trig_BeamY", &beamY, "trig_BeamY/D");
//The tree output in this class is set to be equal to the one of the ZDC channels.
//Large Vertical scintillator
m_AnalysisTree->Branch("LV_Charge", "std::vector<double>", &m_sciLV->Charge );
......
......@@ -84,6 +84,17 @@ void ZDCAnalysis2021::Initialize( std::vector < Detector* > _vDet ){
hMarksFront->push_back( new std::vector< TObject* > );
}
if(m_zdc1 != 0){
beamX = m_zdc1->GetBeamPos().x();
beamY = m_zdc1->GetBeamPos().y();
}else if(m_zdc2 != 0){
beamX = m_zdc2->GetBeamPos().x();
beamY = m_zdc2->GetBeamPos().y();
}else if(m_zdc2 != 0){
beamX = m_zdc2->GetBeamPos().x();
beamY = m_zdc2->GetBeamPos().y();
}
m_alignment2021 = m_zdc1->GetAlignment2021();
}
......@@ -155,7 +166,8 @@ void ZDCAnalysis2021::SetupHistograms( ){
*/
void ZDCAnalysis2021::SetBranches( TTree* _tree ){
m_AnalysisTree = _tree;
m_AnalysisTree->Branch( "zdc_BeamX", &beamX, "zdc_BeamX/D");
m_AnalysisTree->Branch( "zdc_BeamY", &beamY, "zdc_BeamY/D");
for(int mod = 0; mod < vZDC.size(); mod++){
m_AnalysisTree->Branch( Form("zdc%d_Charge",mod+1), "std::vector<double>", &vZDC[mod]->Charge );
m_AnalysisTree->Branch( Form("zdc%d_Peak_max",mod+1), "std::vector<double>", &vZDC[mod]->Peak_max );
......
......@@ -23,7 +23,7 @@ namespace {
void PrintUsage() {
std::cout << " Usage: AnalysisExample2021 [-d /path/to/input/files/ ] [-f /list/of.root /files/here.root]" << std::endl
<< " [-o /output/directory/] [-c /config/file.xml] [-a /alignment/file.xml]" << std::endl
<< " [-t /timing/file.txt] [-n #events] [-v (verbose)] [--help]" << std::endl;
<< " [-s /survey/file.xml] [-t /timing/file.txt] [-n #events] [-v (verbose)] [--help]" << std::endl;
}
}
......@@ -37,6 +37,7 @@ void PrintHelp(){
std::cout << " n Maximum number of events to be processed for a given run" << std::endl;
std::cout << " c Configuration file to be used" << std::endl;
std::cout << " a Alignment file to be used" << std::endl;
std::cout << " s Survey file to be used" << std::endl;
std::cout << " t Timing file to be used" << std::endl;
std::cout << " v Verbose. Currently prints event#, CPU/RAM usage if flag is used. Takes no argument" << std::endl;
......@@ -80,6 +81,7 @@ int main(int argc, char *argv[]){
std::string path_to_datafiles = "";
std::string config_file = "";
std::string alignment_file = "";
std::string survey_file = "";
std::string timing_file = (std::string)std::getenv("JZCaPA") + "/Utils/Timing_data/2021_PreliminaryTiming.txt";
int verbosity = 0;
std::vector<std::string> root_files;
......@@ -101,6 +103,7 @@ int main(int argc, char *argv[]){
else if(TString(argv[i]) == "-n") maxEvents = atoi(argv[i+1]);
else if(TString(argv[i]) == "-c") config_file = argv[i+1];
else if(TString(argv[i]) == "-a") alignment_file = argv[i+1];
else if(TString(argv[i]) == "-s") survey_file = argv[i+1];
else if(TString(argv[i]) == "-t") timing_file = argv[i+1];
else if(TString(argv[i]) == "-v") verbosity = 1;
else if(TString(argv[i]) == "--help") PrintHelp();
......@@ -129,42 +132,57 @@ int main(int argc, char *argv[]){
r->SetOutputDirectory( Form("%s/run%d/",output_dir.c_str(),runNum) );
gSystem->Exec( Form("mkdir -p %s/run%d/",output_dir.c_str(),runNum) );
}
//ADD DETECTORS AND WF ANALYSIS VARIABLES
//Trigger paddles
Scintillators *trig = new Scintillators("TRIGGER");
trig->SetWFAthresholds( 4, 25 );
trig->SetMedianFilter( 4 );
r->AddDetector( trig );
//ATLAS ZDC
ZDC *zdc1 = new ZDC(1);
zdc1->SetWFAthresholds( 5, 30 );
zdc1->SetMedianFilter( 4 );
r->AddDetector( zdc1 );
//ATLAS ZDC
ZDC *zdc2 = new ZDC(2);
zdc2->SetWFAthresholds( 5, 30 );
zdc2->SetMedianFilter( 4 );
r->AddDetector( zdc2 );
//ATLAS ZDC
ZDC *zdc3 = new ZDC(3);
zdc3->SetWFAthresholds( 5, 30 );
zdc3->SetMedianFilter( 4 );
r->AddDetector( zdc3 );
//Pan Flute RPD
RPD *rpd = new RPD("PFRPD");
rpd->SetWFAthresholds( 3.2, 28 );
rpd->SetMedianFilter( 4 );
r->AddDetector( rpd );
//Tile RPD
// RPD *rpd = new RPD("TRPD");
// rpd->SetWFAthresholds( 3.2, 28 );
// rpd->SetMedianFilter( 4 );
// r->AddDetector( rpd );
//Upgraded EM
EM *em = new EM("UEM");
em->SetWFAthresholds( 4, 25 );
em->SetMedianFilter( 4 );
r->AddDetector( em );
Scintillators *trig = new Scintillators("TRIGGER");
trig->SetWFAthresholds( 4, 25 );
trig->SetMedianFilter( 4 );
r->AddDetector( trig );
//CMS EM cal
// EM *em = new EM("CMSEM");
// em->SetWFAthresholds( 4, 25 );
// em->SetMedianFilter( 4 );
// r->AddDetector( em );
std::cout << std::endl << "============ LoadConfigurationFile ============" << std::endl << std::endl;
r->LoadConfigurationFile( config_file );
......@@ -181,6 +199,9 @@ int main(int argc, char *argv[]){
std::cout << std::endl << "============ LoadAlignmentFile ============" << std::endl << std::endl;
r->LoadAlignmentFile( alignment_file );
std::cout << std::endl << "============ LoadSurveyFile ============" << std::endl << std::endl;
r->LoadSurveyFile( survey_file );
std::cout << std::endl << "============ LoadTimingFile ============" << std::endl << std::endl;
r->LoadTimingFile( timing_file );
......
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<root>
<!-- H2-SM1 (mm)-->
<Survey>
<start_run>12</start_run>
<end_run>853</end_run>
<detector>TRIGGER</detector>
<x_pos>0.0</x_pos>
<y_pos>0.0</y_pos>
<z_pos>1100</z_pos>
<i>-3.720414370527883995e-03</i>
<j>2.992673248723477959e-03</j>
<k>-6.306922022863050391e-03</k>
<w>9.999687120897009507e-01</w>
<table_x>1293</table_x>
<table_y>863</table_y>
<trigger_x>2.26</trigger_x>
<trigger_y>2.04</trigger_y>
</Survey>
<Survey>
<start_run>12</start_run>
<end_run>267</end_run>
<detector>UEM</detector>
<x_pos>1.425</x_pos>
<y_pos>8.915</y_pos>
<z_pos>3195.1</z_pos>
<i>-3.720414370527883995e-03</i>
<j>2.992673248723477959e-03</j>
<k>-6.306922022863050391e-03</k>
<w>9.999687120897009507e-01</w>
<table_x>1293</table_x>
<table_y>863</table_y>
<trigger_x>2.26</trigger_x>
<trigger_y>2.04</trigger_y>
</Survey>
<Survey>
<start_run>268</start_run>
<end_run>364</end_run>
<detector>CMSEM</detector>
<x_pos>1.275</x_pos>
<y_pos>28.575</y_pos>
<z_pos>3195.1</z_pos>
<i>-3.720414370527883995e-03</i>
<j>2.992673248723477959e-03</j>
<k>-6.306922022863050391e-03</k>
<w>9.999687120897009507e-01</w>
<table_x>1293</table_x>
<table_y>863</table_y>
<trigger_x>2.26</trigger_x>
<trigger_y>2.04</trigger_y>
</Survey>
<Survey>
<start_run>12</start_run>
<end_run>489</end_run>
<detector>PFRPD</detector>
<x_pos>-2.225</x_pos>
<y_pos>12.6</y_pos>
<z_pos>3306.1</z_pos>
<i>1.315484423720185468e-03</i>
<j>1.366682497106245717e-02</j>
<k>-2.171158807128949902e-03</k>
<w>9.999033820651751503e-01</w>
<table_x>1293</table_x>
<table_y>863</table_y>
<trigger_x>2.26</trigger_x>
<trigger_y>2.04</trigger_y>
</Survey>
<Survey>
<start_run>12</start_run>
<end_run>489</end_run>
<detector>HAD1</detector>
<x_pos>1.275</x_pos>
<y_pos>28.575</y_pos>
<z_pos>3528.875</z_pos>
<i>-3.209634317627901683e-03</i>
<j>1.343110091663845358e-03</j>
<k>-2.800433590459760255e-03</k>
<w>9.999900258875257242e-01</w>
<table_x>1293</table_x>
<table_y>863</table_y>
<trigger_x>2.26</trigger_x>
<trigger_y>2.04</trigger_y>
</Survey>
<Survey>
<start_run>12</start_run>
<end_run>489</end_run>
<detector>HAD2</detector>
<x_pos>-3.575</x_pos>
<y_pos>22.675</y_pos>
<z_pos>3717.3</z_pos>
<i>-3.759405656986081808e-03</i>
<j>-3.199114194294144786e-02</j>
<k>-9.344127794516552191e-03</k>
<w>9.994374022329024498e-01</w>
<table_x>1293</table_x>
<table_y>863</table_y>
<trigger_x>2.26</trigger_x>
<trigger_y>2.04</trigger_y>
</Survey>
<Survey>
<start_run>12</start_run>
<