fix to2root event building
This commit is contained in:
parent
12f4803e45
commit
e281afa456
|
@ -58,7 +58,7 @@ int main(int argn, char **argv) {
|
||||||
TTree * tree = new TTree("tree", "tree");
|
TTree * tree = new TTree("tree", "tree");
|
||||||
|
|
||||||
tree->Branch("evID", &data->eventID, "data_ID/L");
|
tree->Branch("evID", &data->eventID, "data_ID/L");
|
||||||
tree->Branch("id", &data->id, "ID/s");
|
tree->Branch("id", &data->detID, "ID/s");
|
||||||
tree->Branch("e", &data->energy, "crystal_energy/s");
|
tree->Branch("e", &data->energy, "crystal_energy/s");
|
||||||
tree->Branch("e_t", &data->time, "crystal_timestamp/l");
|
tree->Branch("e_t", &data->time, "crystal_timestamp/l");
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
CC=g++
|
CC=g++
|
||||||
|
|
||||||
all: to2root evt2hist MergeEVT ev22txt EventBuilder pxi-time-order to2root_multi
|
all: to2root evt2hist MergeEVT ev22txt EventBuilder pxi-time-order
|
||||||
|
|
||||||
#this is FSU evt to root
|
#this is FSU evt to root
|
||||||
xia2root: ../armory/xia2root.cpp
|
xia2root: ../armory/xia2root.cpp
|
||||||
|
@ -13,10 +13,6 @@ xia2root: ../armory/xia2root.cpp
|
||||||
to2root: ../armory/to2root.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h
|
to2root: ../armory/to2root.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h
|
||||||
$(CC) ../armory/to2root.cpp -o to2root `root-config --cflags --glibs`
|
$(CC) ../armory/to2root.cpp -o to2root `root-config --cflags --glibs`
|
||||||
|
|
||||||
to2root_multi: ../armory/to2root_multi.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h
|
|
||||||
$(CC) ../armory/to2root_multi.cpp -o to2root_multi `root-config --cflags --glibs`
|
|
||||||
|
|
||||||
|
|
||||||
#this is for online root
|
#this is for online root
|
||||||
MergeEVT: ../armory/MergeEVT.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h
|
MergeEVT: ../armory/MergeEVT.cpp ../armory/DataBlock.h ../armory/evtReader.h ../mapping.h
|
||||||
$(CC) ../armory/MergeEVT.cpp -o MergeEVT `root-config --cflags --glibs`
|
$(CC) ../armory/MergeEVT.cpp -o MergeEVT `root-config --cflags --glibs`
|
||||||
|
|
|
@ -49,43 +49,30 @@ int main(int argc, char **argv) {
|
||||||
printf("=====================================\n");
|
printf("=====================================\n");
|
||||||
|
|
||||||
// Check that the corrent number of arguments were provided.
|
// Check that the corrent number of arguments were provided.
|
||||||
if (argc != 2 && argc != 3 && argc != 4 && argc != 5) {
|
if (argc <= 3) {
|
||||||
printf("Incorrect number of arguments:\n");
|
printf("Incorrect number of arguments:\n");
|
||||||
printf("%s [*.to File] <timeWindow> <fraction> <saveFile>\n", argv[0]);
|
printf("%s [outFile] [timeWindow] [to File1] [to File2] .... \n", argv[0]);
|
||||||
|
printf(" outFile : output root file name\n");
|
||||||
printf(" timeWindow : number of tick, 1 tick = 10 ns. default = 100 \n");
|
printf(" timeWindow : number of tick, 1 tick = 10 ns. default = 100 \n");
|
||||||
printf(" fraction : 0 to 100, default 100, last fraction of evt.to to root \n");
|
|
||||||
printf(" e.g. 10, last 10%% of the evt.to to root \n");
|
|
||||||
printf(" saveFile : default is replace evt.to with root \n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CERN ROOT things
|
TString outFileName = argv[1];
|
||||||
TString inFileName = argv[1];
|
int timeWindow = atoi(argv[2]);
|
||||||
int timeWindow = 100;
|
int nFile = argc - 3;
|
||||||
if( argc >= 3 ) timeWindow = atoi(argv[2]);
|
TString inFileName[nFile];
|
||||||
|
for( int i = 0 ; i < nFile ; i++){
|
||||||
|
inFileName[i] = argv[i+3];
|
||||||
|
}
|
||||||
|
|
||||||
int frac = 100;
|
printf("====================================\n");
|
||||||
if( argc >= 4 ) frac = abs(atoi(argv[3]));
|
|
||||||
|
|
||||||
TString outFileName = inFileName;
|
|
||||||
outFileName.Remove(inFileName.First('.'));
|
|
||||||
outFileName.Append(".root");
|
|
||||||
int pos = inFileName.Last('/');
|
|
||||||
outFileName.Remove(0, pos+1);
|
|
||||||
if( argc >= 5) outFileName = argv[4];
|
|
||||||
|
|
||||||
evtReader * evt = new evtReader();
|
evtReader * evt = new evtReader();
|
||||||
evt->OpenFile(inFileName);
|
|
||||||
DataBlock * data = evt->data;
|
DataBlock * data = evt->data;
|
||||||
|
|
||||||
printf(" in file : %s \n", inFileName.Data());
|
printf(" Number of input file : %d \n", nFile);
|
||||||
printf(" our file : \033[1;31m%s\033[m\n", outFileName.Data());
|
printf(" out file : \033[1;31m%s\033[m\n", outFileName.Data());
|
||||||
|
printf(" Event building time window : %d tics = %d nsec \n", timeWindow, timeWindow*10);
|
||||||
printf(" max number of detector channal: %d \n", MAX_ID);
|
|
||||||
|
|
||||||
printf(" Skipping the frist \033[0;34m %d %% \033[m of data \n", 100 - frac);
|
|
||||||
|
|
||||||
printf("------------------------ Event building time window : %d tics = %d nsec \n", timeWindow, timeWindow*10);
|
|
||||||
|
|
||||||
|
|
||||||
TFile * outRootFile = new TFile(outFileName, "recreate");
|
TFile * outRootFile = new TFile(outFileName, "recreate");
|
||||||
|
@ -98,8 +85,9 @@ int main(int argc, char **argv) {
|
||||||
double e[MAX_ID] = {TMath::QuietNaN()};
|
double e[MAX_ID] = {TMath::QuietNaN()};
|
||||||
unsigned long long e_t[MAX_ID] = {0};
|
unsigned long long e_t[MAX_ID] = {0};
|
||||||
int qdc[MAX_ID][8] = {0};
|
int qdc[MAX_ID][8] = {0};
|
||||||
Int_t multiCry = 0 ; /// this is total multiplicity for all crystal
|
int multiCry = 0 ; /// this is total multiplicity for all crystal
|
||||||
|
int runID = 0; // date-run-fileID, Dec15-02-001 = 1502001
|
||||||
|
int multiGagg = 0;
|
||||||
//unsigned short pileup[MAXMULTI];
|
//unsigned short pileup[MAXMULTI];
|
||||||
|
|
||||||
tree->Branch("evID", &evID, "event_ID/l");
|
tree->Branch("evID", &evID, "event_ID/l");
|
||||||
|
@ -109,22 +97,35 @@ int main(int argc, char **argv) {
|
||||||
tree->Branch("e_t", e_t, "e_timestamp[multi]/l");
|
tree->Branch("e_t", e_t, "e_timestamp[multi]/l");
|
||||||
tree->Branch("qdc", qdc, "qdc[multi][8]/I");
|
tree->Branch("qdc", qdc, "qdc[multi][8]/I");
|
||||||
tree->Branch("multiCry", &multiCry, "multiplicity_crystal/I");
|
tree->Branch("multiCry", &multiCry, "multiplicity_crystal/I");
|
||||||
|
tree->Branch("multiGagg", &multiGagg, "multiplicity_GAGG/I");
|
||||||
|
tree->Branch("runID", &runID, "runID/I");
|
||||||
|
|
||||||
int countGP = 0; //gamma-particle coincident
|
int countGP = 0; //gamma-particle coincident
|
||||||
|
|
||||||
/////////////////////
|
for( int i = 0; i < nFile; i++){
|
||||||
// MAIN WHILE LOOP //
|
|
||||||
/////////////////////
|
evt->OpenFile(inFileName[i]);
|
||||||
while ( evt->IsEndOfFile() == false ) { //main while loop
|
if( evt->IsOpen() == false ) continue;
|
||||||
|
|
||||||
|
printf("====================================================\n");
|
||||||
|
printf("\033[1;31m%s \033[m\n", inFileName[i].Data());
|
||||||
|
|
||||||
|
int pos = inFileName[i].Last('/');
|
||||||
|
TString temp = inFileName[i];
|
||||||
|
temp.Remove(0, pos+1);
|
||||||
|
temp.Remove(0, 3);
|
||||||
|
temp.Remove(2, 1);
|
||||||
|
temp.Remove(4, 1);
|
||||||
|
temp.Remove(7);
|
||||||
|
runID = atoi(temp.Data());
|
||||||
|
|
||||||
long long int etime = -1;
|
long long int etime = -1;
|
||||||
long long int tdif = -1;
|
long long int tdif = -1;
|
||||||
|
|
||||||
while (1) { //get subevents and event build for one "event"
|
|
||||||
|
while ( evt->IsEndOfFile() == false ) { //main while loop
|
||||||
|
|
||||||
if ( evt->ReadBlock() == -1) break;
|
if ( evt->ReadBlock() == -1) break;
|
||||||
if ( evt->GetFilePos() < evt->GetFileSize() * ( 1. - frac/100.) ) continue;
|
|
||||||
|
|
||||||
//Set reference time for event building
|
//Set reference time for event building
|
||||||
if (etime == -1) {
|
if (etime == -1) {
|
||||||
|
@ -138,10 +139,23 @@ int main(int argc, char **argv) {
|
||||||
//Check for end of event, rewind, and break out of while loop
|
//Check for end of event, rewind, and break out of while loop
|
||||||
if (tdif > timeWindow) {
|
if (tdif > timeWindow) {
|
||||||
|
|
||||||
|
//Gate
|
||||||
|
if( multiCry > 0 && multiGagg > 0 ) {
|
||||||
|
|
||||||
|
outRootFile->cd();
|
||||||
|
tree->Fill();
|
||||||
|
|
||||||
|
countGP++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
evID ++;
|
||||||
|
|
||||||
etime = data->time;
|
etime = data->time;
|
||||||
tdif = 0;
|
tdif = 0;
|
||||||
multi = 0;
|
multi = 0;
|
||||||
multiCry = 0;
|
multiCry = 0;
|
||||||
|
multiGagg = 0;
|
||||||
|
|
||||||
id[multi] = data->detID;
|
id[multi] = data->detID;
|
||||||
e[multi] = data->energy;
|
e[multi] = data->energy;
|
||||||
|
@ -149,16 +163,18 @@ int main(int argc, char **argv) {
|
||||||
for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i];
|
for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i];
|
||||||
multi++ ;
|
multi++ ;
|
||||||
if( data->detID < 100 ) multiCry ++;
|
if( data->detID < 100 ) multiCry ++;
|
||||||
|
if( data->detID >= 200 ) multiGagg ++;
|
||||||
|
|
||||||
break;
|
|
||||||
}else{
|
}else{
|
||||||
//if within time window, fill array;
|
//if within time window, fill array;
|
||||||
id[multi] = data->detID;
|
id[multi] = data->detID;
|
||||||
e[multi] = data->energy;
|
e[multi] = data->energy;
|
||||||
e_t[multi] = data->time;
|
e_t[multi] = data->time;
|
||||||
for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i];
|
for( int i = 0; i < 8; i++) qdc[multi-1][i] = data->QDCsum[i];
|
||||||
multi++ ;
|
multi++ ;
|
||||||
if( data->detID < 100 ) multiCry ++;
|
if( data->detID < 100 ) multiCry ++;
|
||||||
|
if( data->detID >= 200 ) multiGagg ++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// total pileups
|
// total pileups
|
||||||
|
@ -166,30 +182,25 @@ int main(int argc, char **argv) {
|
||||||
pileUpCount++;
|
pileUpCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} //end while loop for unpacking sub events and event building for one "event"
|
|
||||||
if (multi==0) break; //end main WHILE LOOP when out of events
|
|
||||||
dataCount = evt->GetBlockID();
|
|
||||||
evID ++;
|
|
||||||
|
|
||||||
evt->PrintStatus(10000);
|
evt->PrintStatus(10000);
|
||||||
|
|
||||||
// when no gagg, don't save
|
|
||||||
if( multiCry == 0 || multi == multiCry ) continue;
|
|
||||||
|
|
||||||
countGP ++;
|
|
||||||
|
|
||||||
outRootFile->cd();
|
|
||||||
tree->Fill();
|
|
||||||
|
|
||||||
} // end main while loop
|
} // end main while loop
|
||||||
/////////////////////////
|
|
||||||
// END MAIN WHILE LOOP //
|
|
||||||
/////////////////////////
|
|
||||||
evt->PrintStatus(1);
|
evt->PrintStatus(1);
|
||||||
|
printf("\n\n\n");
|
||||||
|
printf(" total number of event built : %llu\n", evID);
|
||||||
|
printf(" total number of Gamma - GAGG coincdient : %d (%.3f %%)\n", countGP, countGP*1.0/evID);
|
||||||
|
|
||||||
outRootFile->cd();
|
outRootFile->cd();
|
||||||
tree->Write();
|
tree->Write();
|
||||||
|
|
||||||
|
double rootFileSize = outRootFile->GetSize()/1024./1024./1024. ; // in GB
|
||||||
|
printf(" ----------- root file size : %.3f GB\n", rootFileSize);
|
||||||
|
if( rootFileSize > 3.0 ) break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
outRootFile->Close();
|
outRootFile->Close();
|
||||||
|
|
||||||
printf("\n\n\n==================== finished.\r\n");
|
printf("\n\n\n==================== finished.\r\n");
|
||||||
|
|
|
@ -1,207 +0,0 @@
|
||||||
/**********************************************************/
|
|
||||||
/* */
|
|
||||||
/* Modified by Ryan From */
|
|
||||||
/* */
|
|
||||||
/* PXI SCAN CODE -- J.M. Allmond (ORNL) -- July 2016 */
|
|
||||||
/* */
|
|
||||||
/**********************************************************/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "TFile.h"
|
|
||||||
#include "TTree.h"
|
|
||||||
#include "TMath.h"
|
|
||||||
#include "TBenchmark.h"
|
|
||||||
|
|
||||||
#define RAND ((float) rand() / ((unsigned int) RAND_MAX + 1)) // random number in interval (0,1)
|
|
||||||
|
|
||||||
#define MAX_CRATES 2
|
|
||||||
#define MAX_BOARDS_PER_CRATE 13
|
|
||||||
#define MAX_CHANNELS_PER_BOARD 16
|
|
||||||
#define BOARD_START 2
|
|
||||||
|
|
||||||
#define MAX_ID MAX_CRATES*MAX_BOARDS_PER_CRATE*MAX_CHANNELS_PER_BOARD
|
|
||||||
|
|
||||||
#define HEADER_LENGTH 4 //unit = words with 4 bytes per word
|
|
||||||
#define MAX_SUB_LENGTH 2016 //unit = words with 4 bytes per word ; 2004 --> 40 micro-second trace + 4 word header
|
|
||||||
|
|
||||||
#define RAWE_REBIN_FACTOR 2.0 // Rebin 32k pixie16 spectra to something smaller to fit better into 8k.
|
|
||||||
|
|
||||||
#include "../mapping.h"
|
|
||||||
|
|
||||||
#include "../armory/evtReader.h"
|
|
||||||
|
|
||||||
unsigned long long int dataCount=0;
|
|
||||||
unsigned long long int pileUpCount=0;
|
|
||||||
unsigned long long int evtCount=0;
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// START OF MAIN FUNCTION //
|
|
||||||
///////////////////////////////////
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
|
|
||||||
printf("=====================================\n");
|
|
||||||
printf("=== evt.to --> root ===\n");
|
|
||||||
printf("=====================================\n");
|
|
||||||
|
|
||||||
// Check that the corrent number of arguments were provided.
|
|
||||||
if (argc <= 4) {
|
|
||||||
printf("Incorrect number of arguments:\n");
|
|
||||||
printf("%s [outFile] [timeWindow] [to File1] [to File2] .... \n", argv[0]);
|
|
||||||
printf(" outFile : output root file name\n");
|
|
||||||
printf(" timeWindow : number of tick, 1 tick = 10 ns. default = 100 \n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString outFileName = argv[1];
|
|
||||||
int timeWindow = atoi(argv[2]);
|
|
||||||
int nFile = argc - 3;
|
|
||||||
TString inFileName[nFile];
|
|
||||||
for( int i = 0 ; i < nFile ; i++){
|
|
||||||
inFileName[i] = argv[i+3];
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("====================================\n");
|
|
||||||
|
|
||||||
evtReader * evt = new evtReader();
|
|
||||||
DataBlock * data = evt->data;
|
|
||||||
|
|
||||||
printf(" Number of input file : %d \n", nFile);
|
|
||||||
printf(" out file : \033[1;31m%s\033[m\n", outFileName.Data());
|
|
||||||
printf(" Event building time window : %d tics = %d nsec \n", timeWindow, timeWindow*10);
|
|
||||||
|
|
||||||
|
|
||||||
TFile * outRootFile = new TFile(outFileName, "recreate");
|
|
||||||
outRootFile->cd();
|
|
||||||
TTree * tree = new TTree("tree", "tree");
|
|
||||||
|
|
||||||
unsigned long long evID = 0;
|
|
||||||
int multi = 0;
|
|
||||||
int id[MAX_ID] = {0};
|
|
||||||
double e[MAX_ID] = {TMath::QuietNaN()};
|
|
||||||
unsigned long long e_t[MAX_ID] = {0};
|
|
||||||
int qdc[MAX_ID][8] = {0};
|
|
||||||
int multiCry = 0 ; /// this is total multiplicity for all crystal
|
|
||||||
int runID = 0; // date-run-fileID, Dec15-02-001 = 1502001
|
|
||||||
|
|
||||||
//unsigned short pileup[MAXMULTI];
|
|
||||||
|
|
||||||
tree->Branch("evID", &evID, "event_ID/l");
|
|
||||||
tree->Branch("multi", &multi, "multi/I");
|
|
||||||
tree->Branch("detID", id, "detID[multi]/I");
|
|
||||||
tree->Branch("e", e, "e[multi]/D");
|
|
||||||
tree->Branch("e_t", e_t, "e_timestamp[multi]/l");
|
|
||||||
tree->Branch("qdc", qdc, "qdc[multi][8]/I");
|
|
||||||
tree->Branch("multiCry", &multiCry, "multiplicity_crystal/I");
|
|
||||||
tree->Branch("runID", &runID, "runID/I");
|
|
||||||
|
|
||||||
int countGP = 0; //gamma-particle coincident
|
|
||||||
|
|
||||||
for( int i = 0; i < nFile; i++){
|
|
||||||
evt->OpenFile(inFileName[i]);
|
|
||||||
if( evt->IsOpen() == false ) continue;
|
|
||||||
|
|
||||||
printf("====================================================\n");
|
|
||||||
printf("\033[1;31m%s \033[m\n", inFileName[i].Data());
|
|
||||||
|
|
||||||
int pos = inFileName[i].Last('/');
|
|
||||||
TString temp = inFileName[i];
|
|
||||||
temp.Remove(0, pos+1);
|
|
||||||
temp.Remove(0, 3);
|
|
||||||
temp.Remove(2, 1);
|
|
||||||
temp.Remove(4, 1);
|
|
||||||
temp.Remove(7);
|
|
||||||
runID = atoi(temp.Data());
|
|
||||||
|
|
||||||
|
|
||||||
while ( evt->IsEndOfFile() == false ) { //main while loop
|
|
||||||
|
|
||||||
long long int etime = -1;
|
|
||||||
long long int tdif = -1;
|
|
||||||
|
|
||||||
while (1) { //get subevents and event build for one "event"
|
|
||||||
|
|
||||||
if ( evt->ReadBlock() == -1) break;
|
|
||||||
|
|
||||||
//Set reference time for event building
|
|
||||||
if (etime == -1) {
|
|
||||||
etime = data->time;
|
|
||||||
tdif = 0;
|
|
||||||
multi = 0;
|
|
||||||
}else {
|
|
||||||
tdif = data->time - etime;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check for end of event, rewind, and break out of while loop
|
|
||||||
if (tdif > timeWindow) {
|
|
||||||
|
|
||||||
etime = data->time;
|
|
||||||
tdif = 0;
|
|
||||||
multi = 0;
|
|
||||||
multiCry = 0;
|
|
||||||
|
|
||||||
id[multi] = data->detID;
|
|
||||||
e[multi] = data->energy;
|
|
||||||
e_t[multi] = data->time;
|
|
||||||
for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i];
|
|
||||||
multi++ ;
|
|
||||||
if( data->detID < 100 ) multiCry ++;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}else{
|
|
||||||
//if within time window, fill array;
|
|
||||||
id[multi] = data->detID;
|
|
||||||
e[multi] = data->energy;
|
|
||||||
e_t[multi] = data->time;
|
|
||||||
for( int i = 0; i < 8; i++) qdc[multi][i] = data->QDCsum[i];
|
|
||||||
multi++ ;
|
|
||||||
if( data->detID < 100 ) multiCry ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// total pileups
|
|
||||||
if (data->pileup == 1) {
|
|
||||||
pileUpCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} //end while loop for unpacking sub events and event building for one "event"
|
|
||||||
if (multi==0) break; //end main WHILE LOOP when out of events
|
|
||||||
dataCount = evt->GetBlockID();
|
|
||||||
evID ++;
|
|
||||||
|
|
||||||
evt->PrintStatus(10000);
|
|
||||||
|
|
||||||
// when no gagg, don't save
|
|
||||||
if( multiCry == 0 || multi == multiCry ) continue;
|
|
||||||
|
|
||||||
countGP ++;
|
|
||||||
|
|
||||||
outRootFile->cd();
|
|
||||||
tree->Fill();
|
|
||||||
|
|
||||||
} // end main while loop
|
|
||||||
|
|
||||||
evt->PrintStatus(1);
|
|
||||||
printf("\n\n\n");
|
|
||||||
printf(" total number of event built : %llu\n", evID);
|
|
||||||
printf(" total number of Gamma - GAGG coincdient : %d\n", countGP);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
outRootFile->cd();
|
|
||||||
tree->Write();
|
|
||||||
outRootFile->Close();
|
|
||||||
|
|
||||||
printf("\n\n\n==================== finished.\r\n");
|
|
||||||
|
|
||||||
printf(" number of Gamma - GAGG coincdient : %d\n", countGP);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user